Skip to content

Commit

Permalink
fix payjoin to account for cut-through
Browse files Browse the repository at this point in the history
  • Loading branch information
DanGould committed Sep 30, 2024
1 parent c943682 commit f413afd
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 15 deletions.
38 changes: 26 additions & 12 deletions src/wallet/psbt_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -434,24 +434,32 @@ impl BdkWalletVisitor for PsbtBuilder<AcceptingCurrentKeychainState> {
.push(((payout_id, destination, satoshis), 0));
}

// add foreign payjoin utxos
// *try* Handle payjoin to see what happens. visit_bdk_wallet will actually use the state machine
// - collect foreign payjoin utxos to add as input
// - add non-owned payjoin outputs as change
// - remove domain receiver outputs from payjoin original psbt to be forwarded or spent to change
let payjoin_original_psbt = if let Some(ref wants_outputs) = self.cfg.wants_outputs {
use std::str::FromStr;
let mut payjoin_original_psbt =
psbt::Psbt::from_str(&wants_outputs.original_psbt().to_string())
.expect("failed to parse payjoin original psbt");
let current_wallet_owned_vouts = wants_outputs.owned_vouts();
for i in (0..payjoin_original_psbt.unsigned_tx.output.len()).rev() {
if !current_wallet_owned_vouts.contains(&i) {
if current_wallet_owned_vouts.contains(&i) {
// remove original_psbt deposits as they'll be forwarded
payjoin_original_psbt.outputs.remove(i);
payjoin_original_psbt.unsigned_tx.output.remove(i);
} else {
// the payjoin sender's change outputs will be added as recipients
let output = &payjoin_original_psbt.unsigned_tx.output[i];
let txout = bdk::bitcoin::TxOut {
value: output.value,
script_pubkey: bdk::bitcoin::ScriptBuf::from_bytes(
output.script_pubkey.to_bytes(),
),
};
builder.add_recipient(txout.script_pubkey, txout.value);
}
}
// for include each remaining payjoin output
for output in payjoin_original_psbt.unsigned_tx.output.iter() {
builder.add_recipient(output.script_pubkey.clone(), output.value);
}
Some((current_keychain_id, payjoin_original_psbt))
} else {
None
Expand Down Expand Up @@ -721,15 +729,21 @@ impl PsbtBuilder<AcceptingCurrentKeychainState> {
.expect("failed to parse payjoin original psbt");
let current_wallet_owned_vouts = wants_outputs.owned_vouts();
for i in (0..payjoin_original_psbt.unsigned_tx.output.len()).rev() {
if !current_wallet_owned_vouts.contains(&i) {
if current_wallet_owned_vouts.contains(&i) {
// know that the receiver is liable to spend the amounts in these removed outputs
payjoin_original_psbt.outputs.remove(i);
payjoin_original_psbt.unsigned_tx.output.remove(i);
} else {
let output = &payjoin_original_psbt.unsigned_tx.output[i];
let txout = bdk::bitcoin::TxOut {
value: output.value,
script_pubkey: bdk::bitcoin::ScriptBuf::from_bytes(
output.script_pubkey.to_bytes(),
),
};
builder.add_recipient(txout.script_pubkey, txout.value);
}
}
// for each remaining output, still pay that change
for output in payjoin_original_psbt.unsigned_tx.output.iter() {
builder.add_recipient(output.script_pubkey.clone(), output.value);
}
for input in payjoin_original_psbt.unsigned_tx.input.iter() {
// FIXME weight should be paid for by payjoin sender
let bdk_outpoint = OutPoint {
Expand Down
3 changes: 0 additions & 3 deletions src/xpub/signing_client/bitcoind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ impl RemoteSigningClient for BitcoindRemoteSigner {
let raw_psbt = psbt.serialize();
let hex_psbt = general_purpose::STANDARD.encode(raw_psbt);
let sighash_type = Some(DEFAULT_SIGHASH_TYPE.into());
dbg!(&hex_psbt);
let response = self
.inner
.wallet_process_psbt(&hex_psbt, None, sighash_type, None)
Expand All @@ -49,13 +48,11 @@ impl RemoteSigningClient for BitcoindRemoteSigner {
"Failed to sign psbt via bitcoind: {e}"
))
})?;
dbg!(&response);
let signed_psbt = general_purpose::STANDARD
.decode(response.psbt)
.map_err(|e| {
SigningClientError::HexConvert(format!("Failed to convert psbt from bitcoind: {e}"))
})?;
dbg!(&signed_psbt);
let deserialized_psbt = psbt::PartiallySignedTransaction::deserialize(&signed_psbt)?;
dbg!(&deserialized_psbt);
Ok(deserialized_psbt)
Expand Down

0 comments on commit f413afd

Please sign in to comment.