Closed sethforprivacy closed 4 months ago
P.S. - it's most likely this is a broken interaction that involves both better error-handling on Sparrow's side and some issues with how BTCPay handles PayJoins. Happy to open an issue there once we dig a little deeper.
Yes, this is often reported by new users of this functionality. BTCPayServer always extracts and broadcasts the transaction from the original PSBT after a certain number of seconds. The only way to stop this is to successfully complete the payjoin, in which case the payjoin PSBT can be used. I understand the motivation - the merchant always gets paid - but for a user it's often unexpected which is not ideal.
Unfortunately, there's nothing Sparrow can do about it within the constraints of the Payjoin spec.
Is there any way to tell why it failed? The error was less than descriptive and would be good to be sure there isn't anything broken in the PayJoin comms. The transaction was broadcast immediately (by BTCPay it seems) when I tried to get the PayJoin input and got this error, there was not even a delay.
Is there any way to tell why it failed? The error was less than descriptive and would be good to be sure there isn't anything broken in the PayJoin comms.
The BIP78 spec defines four well known error codes: https://github.com/bitcoin/bips/blob/master/bip-0078.mediawiki#receivers-well-known-errors. In order to avoid displaying a message from a potential attacker, Sparrow will not display any other error messages within the UI, and defaults to Unknown Error. You can check the log file (Help menu) for a more detailed error message.
The transaction was broadcast immediately (by BTCPay it seems) when I tried to get the PayJoin input and got this error, there was not even a delay.
It shouldn't be immediate, otherwise there would be no way to ever complete a payjoin. But it's not long - in the order of seconds or a minute as I recall.
Ah, interesting, it was a script-type issue:
2024-07-22 07:16:36,117 ERROR [Thread-60] c.s.s.p.Payjoin [null:-1] Payjoin error
com.sparrowwallet.sparrow.payjoin.PayjoinReceiverException: Proposal script type of P2WPKH did not match wallet script type of P2TR
at com.sparrowwallet.sparrow@1.9.1/com.sparrowwallet.sparrow.payjoin.Payjoin.checkProposal(Unknown Source)
at com.sparrowwallet.sparrow@1.9.1/com.sparrowwallet.sparrow.payjoin.Payjoin.requestPayjoinPSBT(Unknown Source)
at com.sparrowwallet.sparrow@1.9.1/com.sparrowwallet.sparrow.payjoin.Payjoin$RequestPayjoinPSBTService$1.call(Unknown Source)
at com.sparrowwallet.sparrow@1.9.1/com.sparrowwallet.sparrow.payjoin.Payjoin$RequestPayjoinPSBTService$1.call(Unknown Source)
at javafx.graphics@18/javafx.concurrent.Task$TaskCallable.call(Unknown Source)
at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
at javafx.graphics@18/javafx.concurrent.Service.lambda$executeTask$6(Unknown Source)
at java.base/java.security.AccessController.doPrivileged(Unknown Source)
at javafx.graphics@18/javafx.concurrent.Service.lambda$executeTask$7(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.base/java.lang.Thread.run(Unknown Source)
2024-07-22 07:16:39,904 ERROR [RxCachedThreadScheduler-1] c.s.s.n.h.c.JettyHttpClient [null:-1] Http query failed: status=422, responseBody={"errorCode":"already-paid","message":"The invoice this PSBT is paying has already been partially or completely paid"}
2024-07-22 07:16:39,908 WARN [Thread-63] c.s.s.p.Payjoin [null:-1] Payjoin receiver returned an error of already-paid (The invoice this PSBT is paying has already been partially or completely paid)
2024-07-22 07:17:04,263 ERROR [RxCachedThreadScheduler-1] c.s.s.n.h.c.JettyHttpClient [null:-1] Http query failed: status=422, responseBody={"errorCode":"already-paid","message":"The invoice this PSBT is paying has already been partially or completely paid"}
2024-07-22 07:17:04,263 WARN [Thread-65] c.s.s.p.Payjoin [null:-1] Payjoin receiver returned an error of already-paid (The invoice this PSBT is paying has already been partially or completely paid)
Seems that the BTCPay server broadcasted the transaction ~3s after the initial error.
That seems pretty quick - might be worth inquiring with them about such a short time period.
Should we close this off?
It'd be helpful if you can figure out what error BTCPayServer threw, can you? If it were possible to Payjoin, sparrow should show "The receiver rejected the original PSBT." The unknown error suggests that something else happened here. My guess is the BTCPayServer had no coin to select.
I think the /real/ error message should show up in Sparrow debug logs if such a thing is available.
I was attempting to pay a PayJoin on a BTCPay server, and when I tried to get the PayJoin input after signing the initial PSBT I got this error:
That would be fine except that the transaction was still broadcast silently without my consent, and without being PayJoined. The BTCPay invoice being marked as paid immediately after the error was my first clue, but I couldn't find the TX in mempool at first. Eventually Sparrow finally showed the transaction (with notification) while I still hadn't hit the Broadcast Transaction button. My guess is that when I tried to get the PayJoin input Sparrow for some reason broadcast the transaction to the network, OR when sending the signed PSBT to BTCPay, BTCPay broadcast the transaction for some reason. I can't share the transaction details here, but happy to forward them in DMs to you if useful, @craigraw.