diff --git a/BTCPayServer.Client/BTCPayServer.Client.csproj b/BTCPayServer.Client/BTCPayServer.Client.csproj index 035d01c9b..d1e7df665 100644 --- a/BTCPayServer.Client/BTCPayServer.Client.csproj +++ b/BTCPayServer.Client/BTCPayServer.Client.csproj @@ -5,7 +5,7 @@ - + diff --git a/BTCPayServer.Tests/PayJoinTests.cs b/BTCPayServer.Tests/PayJoinTests.cs index deb0b9ff3..68f0368ae 100644 --- a/BTCPayServer.Tests/PayJoinTests.cs +++ b/BTCPayServer.Tests/PayJoinTests.cs @@ -141,8 +141,14 @@ namespace BTCPayServer.Tests var receiverCoin = await receiverUser.ReceiveUTXO(Money.Satoshis(810), network); var clientShouldError = unsupportedFormats.Contains(senderAddressType); - var errorCode = ( unsupportedFormats.Contains( receiverAddressType) || receiverAddressType != senderAddressType)? "unsupported-inputs" : null; - + string errorCode = null; + if (unsupportedFormats.Contains(receiverAddressType)) + { + errorCode = "unsupported-inputs"; + }else if (receiverAddressType != senderAddressType) + { + errorCode = "out-of-utxos"; + } var invoice = receiverUser.BitPay.CreateInvoice(new Invoice() {Price = 50000, Currency = "sats", FullNotifications = true}); var invoiceAddress = BitcoinAddress.Create(invoice.BitcoinAddress, cashCow.Network); diff --git a/BTCPayServer/Payments/PayJoin/PayJoinEndpointController.cs b/BTCPayServer/Payments/PayJoin/PayJoinEndpointController.cs index 29816498d..c79e15d7a 100644 --- a/BTCPayServer/Payments/PayJoin/PayJoinEndpointController.cs +++ b/BTCPayServer/Payments/PayJoin/PayJoinEndpointController.cs @@ -19,7 +19,6 @@ using NBXplorer; using NBXplorer.Models; using Newtonsoft.Json.Linq; using NicolasDorier.RateLimits; -using Microsoft.Extensions.Logging; using NBXplorer.DerivationStrategy; using System.Diagnostics.CodeAnalysis; @@ -384,8 +383,8 @@ namespace BTCPayServer.Payments.PayJoin Money ourFeeContribution = Money.Zero; // We need to adjust the fee to keep a constant fee rate var txBuilder = network.NBitcoinNetwork.CreateTransactionBuilder(); - txBuilder.AddCoins(psbt.Inputs.Select(i => i.GetCoin())); - txBuilder.AddCoins(selectedUTXOs.Select(o => o.Value.AsCoin())); + txBuilder.AddCoins(psbt.Inputs.Select(i => i.GetSignableCoin())); + txBuilder.AddCoins(selectedUTXOs.Select(o => o.Value.AsCoin(derivationSchemeSettings.AccountDerivation))); Money expectedFee = txBuilder.EstimateFees(newTx, originalFeeRate); Money actualFee = newTx.GetFee(txBuilder.FindSpentCoins(newTx)); Money additionalFee = expectedFee - actualFee; @@ -440,7 +439,8 @@ namespace BTCPayServer.Payments.PayJoin foreach (var selectedUtxo in selectedUTXOs.Select(o => o.Value)) { var signedInput = newPsbt.Inputs.FindIndexedInput(selectedUtxo.Outpoint); - signedInput.UpdateFromCoin(selectedUtxo.AsCoin()); + var coin = selectedUtxo.AsCoin(derivationSchemeSettings.AccountDerivation); + signedInput.UpdateFromCoin(coin); var privateKey = accountKey.Derive(selectedUtxo.KeyPath).PrivateKey; signedInput.Sign(privateKey); signedInput.FinalizeInput(); diff --git a/BTCPayServer/Services/PayjoinClient.cs b/BTCPayServer/Services/PayjoinClient.cs index 8915a6d24..964d91a80 100644 --- a/BTCPayServer/Services/PayjoinClient.cs +++ b/BTCPayServer/Services/PayjoinClient.cs @@ -34,9 +34,9 @@ namespace BTCPayServer.Services if (i.WitnessUtxo.ScriptPubKey.IsScriptType(ScriptType.P2WPKH)) return ScriptPubKeyType.Segwit; if (i.WitnessUtxo.ScriptPubKey.IsScriptType(ScriptType.P2SH) && - i.FinalScriptWitness.ToScript().IsScriptType(ScriptType.P2WPKH)) + PayToWitPubKeyHashTemplate.Instance.ExtractWitScriptParameters(i.FinalScriptWitness) is {}) return ScriptPubKeyType.SegwitP2SH; - return null as ScriptPubKeyType?; + return null; } } @@ -212,8 +212,10 @@ namespace BTCPayServer.Services if (sentAfter > sentBefore) { var overPaying = sentAfter - sentBefore; + if (!newPSBT.TryGetEstimatedFeeRate(out var newFeeRate) || !newPSBT.TryGetVirtualSize(out var newVirtualSize)) throw new PayjoinSenderException("The payjoin receiver did not included UTXO information to calculate fee correctly"); + var additionalFee = newPSBT.GetFee() - originalFee; if (overPaying > additionalFee) throw new PayjoinSenderException("The payjoin receiver is sending more money to himself");