diff --git a/payjoin/src/core/receive/mod.rs b/payjoin/src/core/receive/mod.rs index 2790a6325..f102d743a 100644 --- a/payjoin/src/core/receive/mod.rs +++ b/payjoin/src/core/receive/mod.rs @@ -312,6 +312,23 @@ impl PsbtContext { sender_input_indexes } + /// Returns payjoin proposal PSBT to be signed + /// + /// Removes all sender signatures which are received with the original PSBT + /// as these signatures are now invalid + fn psbt_to_sign(&self) -> Psbt { + let mut psbt = self.payjoin_psbt.clone(); + // Remove now-invalid sender signatures before applying the receiver signatures + for i in self.sender_input_indexes() { + tracing::trace!("Clearing sender input {i}"); + psbt.inputs[i].final_script_sig = None; + psbt.inputs[i].final_script_witness = None; + psbt.inputs[i].tap_key_sig = None; + } + + psbt + } + /// Finalizes the Payjoin proposal into a PSBT which the sender will find acceptable before /// they sign the transaction and broadcast it to the network. /// @@ -322,23 +339,16 @@ impl PsbtContext { self, wallet_process_psbt: impl Fn(&Psbt) -> Result, ) -> Result { - let mut psbt = self.payjoin_psbt.clone(); - // Remove now-invalid sender signatures before applying the receiver signatures - for i in self.sender_input_indexes() { - tracing::trace!("Clearing sender input {i}"); - psbt.inputs[i].final_script_sig = None; - psbt.inputs[i].final_script_witness = None; - psbt.inputs[i].tap_key_sig = None; - } - let finalized_psbt = wallet_process_psbt(&psbt)?; + let psbt = self.psbt_to_sign(); + let signed_psbt = wallet_process_psbt(&psbt)?; let expected_ntxid = self.payjoin_psbt.unsigned_tx.compute_ntxid(); - let actual_ntxid = finalized_psbt.unsigned_tx.compute_ntxid(); + let actual_ntxid = signed_psbt.unsigned_tx.compute_ntxid(); if expected_ntxid != actual_ntxid { return Err(ImplementationError::from( format!("Ntxid mismatch: expected {expected_ntxid}, got {actual_ntxid}").as_str(), )); } - let payjoin_proposal = self.prepare_psbt(finalized_psbt); + let payjoin_proposal = self.prepare_psbt(signed_psbt); Ok(payjoin_proposal) } } diff --git a/payjoin/src/core/receive/v1/mod.rs b/payjoin/src/core/receive/v1/mod.rs index 99e8aa3a9..8c659564e 100644 --- a/payjoin/src/core/receive/v1/mod.rs +++ b/payjoin/src/core/receive/v1/mod.rs @@ -304,7 +304,7 @@ impl ProvisionalProposal { /// In some applications the entity that progresses the typestate /// is different from the entity that has access to the private keys, /// so the PSBT to sign must be accessible to such implementers. - pub fn psbt_to_sign(&self) -> Psbt { self.psbt_context.payjoin_psbt.clone() } + pub fn psbt_to_sign(&self) -> Psbt { self.psbt_context.psbt_to_sign() } } /// A finalized Payjoin proposal, complete with fees and receiver signatures, that the sender diff --git a/payjoin/src/core/receive/v2/mod.rs b/payjoin/src/core/receive/v2/mod.rs index 4b57c6abd..7ff08f0ee 100644 --- a/payjoin/src/core/receive/v2/mod.rs +++ b/payjoin/src/core/receive/v2/mod.rs @@ -1124,7 +1124,7 @@ impl Receiver { /// In some applications the entity that progresses the typestate /// is different from the entity that has access to the private keys, /// so the PSBT to sign must be accessible to such implementers. - pub fn psbt_to_sign(&self) -> Psbt { self.state.psbt_context.payjoin_psbt.clone() } + pub fn psbt_to_sign(&self) -> Psbt { self.state.psbt_context.psbt_to_sign() } pub(crate) fn apply_payjoin_proposal(self, payjoin_psbt: Psbt) -> ReceiveSession { let psbt_context = PsbtContext {