Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Relax requirement on mixed input types #3

Merged
merged 1 commit into from
Jan 14, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 4 additions & 25 deletions BIP78.Sender/PayjoinClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ public async Task<PSBT> RequestPayjoin(BitcoinUrlBuilder bip21, IPayjoinWallet w
if (signedPSBT.IsAllFinalized())
throw new InvalidOperationException("The original PSBT should not be finalized.");
var optionalParameters = new PayjoinClientParameters();
var inputScriptType = wallet.ScriptPubKeyType;
var paymentScriptPubKey = bip21.Address?.ScriptPubKey;
var changeOutput = signedPSBT.Outputs.CoinsFor(wallet, wallet.AccountKey, wallet.RootedKeyPath)
.Where(o => o.ScriptPubKey != paymentScriptPubKey)
Expand All @@ -56,7 +55,7 @@ public async Task<PSBT> RequestPayjoin(BitcoinUrlBuilder bip21, IPayjoinWallet w
optionalParameters.MaxAdditionalFeeContribution = MaxFeeBumpContribution is null
?
// By default, we want to keep same fee rate and a single additional input
originalFeeRate.GetFee(GetVirtualSize(inputScriptType))
originalFeeRate.GetFee(110)
: MaxFeeBumpContribution;
if (MinimumFeeRate is FeeRate v)
optionalParameters.MinFeeRate = v;
Expand Down Expand Up @@ -140,9 +139,6 @@ public async Task<PSBT> RequestPayjoin(BitcoinUrlBuilder bip21, IPayjoinWallet w
throw new PayjoinSenderException(
"The receiver did not specify non_witness_utxo or witness_utxo for one of their inputs");
sequences.Add(proposedTxIn.Sequence);
// Verify that the payjoin proposal did not introduced mixed input's type.
if (inputScriptType != proposedPSBTInput.GetInputScriptPubKeyType())
throw new PayjoinSenderException("Mixed input type detected in the proposal");
}
}

Expand Down Expand Up @@ -187,9 +183,9 @@ public async Task<PSBT> RequestPayjoin(BitcoinUrlBuilder bip21, IPayjoinWallet w
// Make sure the actual contribution is only paying fee
if (actualContribution > additionalFee)
throw new PayjoinSenderException("The actual contribution is not only paying fee");
// Make sure the actual contribution is only paying for fee incurred by additional inputs
var additionalInputsCount = proposalGlobalTx.Inputs.Count - originalGlobalTx.Inputs.Count;
if (actualContribution > originalFeeRate.GetFee(GetVirtualSize(inputScriptType)) *
// This assumes an additional input can be up to 110 bytes.
var additionalInputsCount = proposalGlobalTx.Inputs.Count - originalGlobalTx.Inputs.Count;
if (actualContribution > originalFeeRate.GetFee(110) *
additionalInputsCount)
throw new PayjoinSenderException(
"The actual contribution is not only paying for additional inputs");
Expand Down Expand Up @@ -233,23 +229,6 @@ public async Task<PSBT> RequestPayjoin(BitcoinUrlBuilder bip21, IPayjoinWallet w
return proposal;
}

private int GetVirtualSize(ScriptPubKeyType? scriptPubKeyType)
{
switch (scriptPubKeyType)
{
case ScriptPubKeyType.Legacy:
return 148;
case ScriptPubKeyType.Segwit:
return 68;
case ScriptPubKeyType.SegwitP2SH:
return 91;
case ScriptPubKeyType.TaprootBIP86:
return 58;
default:
return 110;
}
}

private static PSBT CreateOriginalPSBT(PSBT signedPSBT)
{
var original = signedPSBT.Clone();
Expand Down
Loading