diff --git a/src/wallet/psbt_builder.rs b/src/wallet/psbt_builder.rs index e8d4e99b..deb93883 100644 --- a/src/wallet/psbt_builder.rs +++ b/src/wallet/psbt_builder.rs @@ -434,8 +434,9 @@ impl BdkWalletVisitor for PsbtBuilder { .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 = @@ -443,15 +444,22 @@ impl BdkWalletVisitor for PsbtBuilder { .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 @@ -721,15 +729,21 @@ impl PsbtBuilder { .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 { diff --git a/src/xpub/signing_client/bitcoind.rs b/src/xpub/signing_client/bitcoind.rs index 290dc648..683b28f4 100644 --- a/src/xpub/signing_client/bitcoind.rs +++ b/src/xpub/signing_client/bitcoind.rs @@ -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) @@ -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)