diff --git a/BTCPayServer.Tests/PayJoinTests.cs b/BTCPayServer.Tests/PayJoinTests.cs index 30457a2df..281990b6a 100644 --- a/BTCPayServer.Tests/PayJoinTests.cs +++ b/BTCPayServer.Tests/PayJoinTests.cs @@ -79,7 +79,7 @@ namespace BTCPayServer.Tests var receiverCoin = await receiverUser.ReceiveUTXO(Money.Satoshis(810), network); var clientShouldError = unsupportedFormats.Contains(senderAddressType); - var errorCode = !clientShouldError && ( unsupportedFormats.Contains( receiverAddressType) || receiverAddressType != senderAddressType)? "unsupported-inputs" : null; + var errorCode = ( unsupportedFormats.Contains( receiverAddressType) || receiverAddressType != senderAddressType)? "unsupported-inputs" : null; var invoice = receiverUser.BitPay.CreateInvoice(new Invoice() {Price = 50000, Currency = "sats", FullNotifications = true}); diff --git a/BTCPayServer/Payments/PayJoin/PayJoinEndpointController.cs b/BTCPayServer/Payments/PayJoin/PayJoinEndpointController.cs index 75e684b0e..a636f80f5 100644 --- a/BTCPayServer/Payments/PayJoin/PayJoinEndpointController.cs +++ b/BTCPayServer/Payments/PayJoin/PayJoinEndpointController.cs @@ -4,7 +4,6 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; -using BTCPayServer.Data; using BTCPayServer.Events; using BTCPayServer.Filters; using BTCPayServer.HostedServices; @@ -14,12 +13,8 @@ using BTCPayServer.Services.Invoices; using BTCPayServer.Services.Stores; using BTCPayServer.Services.Wallets; using Microsoft.AspNetCore.Cors; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Mvc.ModelBinding; using NBitcoin; -using NBitcoin.DataEncoders; -using NBitcoin.Logging; using NBXplorer; using NBXplorer.Models; using Newtonsoft.Json.Linq; @@ -173,8 +168,8 @@ namespace BTCPayServer.Payments.PayJoin await _explorerClientProvider.GetExplorerClient(network).BroadcastAsync(originalTx); } - var allNativeSegwit = originalTx.Inputs.All(i => (i.GetSigner() is WitKeyId)); - var allScript = originalTx.Inputs.All(i => (i.GetSigner() is WitScriptId)); + var allNativeSegwit = psbt.Inputs.All(i => i.ScriptPubKeyType() == ScriptPubKeyType.Segwit); + var allScript = psbt.Inputs.All(i => i.ScriptPubKeyType() == ScriptPubKeyType.SegwitP2SH); if (!allNativeSegwit && !allScript) return BadRequest(CreatePayjoinError(400, "unsupported-inputs", "Payjoin only support segwit inputs (of the same type)")); if (psbt.CheckSanity() is var errors && errors.Count != 0) diff --git a/BTCPayServer/Services/PayjoinClient.cs b/BTCPayServer/Services/PayjoinClient.cs index 443544b92..1eaf7f525 100644 --- a/BTCPayServer/Services/PayjoinClient.cs +++ b/BTCPayServer/Services/PayjoinClient.cs @@ -14,9 +14,14 @@ namespace BTCPayServer.Services public static class PSBTExtensions { - public static TxDestination GetSigner(this PSBTInput psbtInput) + public static ScriptPubKeyType? ScriptPubKeyType(this PSBTInput i) { - return psbtInput.FinalScriptSig?.GetSigner() ?? psbtInput.FinalScriptWitness?.GetSigner(); + if (i.WitnessUtxo.ScriptPubKey.IsScriptType(ScriptType.P2WPKH)) + return NBitcoin.ScriptPubKeyType.Segwit; + if (i.WitnessUtxo.ScriptPubKey.IsScriptType(ScriptType.P2SH) && + i.FinalScriptWitness.ToScript().IsScriptType(ScriptType.P2WPKH)) + return NBitcoin.ScriptPubKeyType.SegwitP2SH; + return null; } } @@ -160,7 +165,7 @@ namespace BTCPayServer.Services } } - // Making sure that the receiver's inputs are finalized and P2PWKH + // Making sure that the receiver's inputs are finalized and match format foreach (var input in newPSBT.Inputs) { if (originalTx.Inputs.FindIndexedInput(input.PrevOut) is null) @@ -168,18 +173,9 @@ namespace BTCPayServer.Services if (!input.IsFinalized()) throw new PayjoinSenderException("The payjoin receiver included a non finalized input"); - switch (type) + if (type != input.ScriptPubKeyType()) { - case ScriptPubKeyType.Segwit: - if (!(input.FinalScriptWitness.GetSigner() is WitKeyId)) - throw new PayjoinSenderException("The payjoin receiver included an input that is not the same segwit input type"); - break; - case ScriptPubKeyType.SegwitP2SH: - if (!(input.FinalScriptWitness.GetSigner() is WitKeyId)) - throw new PayjoinSenderException("The payjoin receiver included an input that is not the same segwit input type");; - break; - default: - throw new ArgumentOutOfRangeException(); + throw new PayjoinSenderException("The payjoin receiver included an input that is not the same segwit input type"); } } }