diff --git a/payjoin-cli/src/app/v2/mod.rs b/payjoin-cli/src/app/v2/mod.rs index cd0cf38ee..a43dcdf8f 100644 --- a/payjoin-cli/src/app/v2/mod.rs +++ b/payjoin-cli/src/app/v2/mod.rs @@ -985,7 +985,7 @@ impl App { loop { interval.tick().await; let check_result = proposal - .check_for_broadcast(|txid| { + .check_for_transaction(|txid| { self.wallet() .get_raw_transaction(&txid) .map_err(|e| ImplementationError::from(e.into_boxed_dyn_error())) diff --git a/payjoin-ffi/src/receive/mod.rs b/payjoin-ffi/src/receive/mod.rs index 4ee8c8d87..b271d9725 100644 --- a/payjoin-ffi/src/receive/mod.rs +++ b/payjoin-ffi/src/receive/mod.rs @@ -1437,7 +1437,7 @@ impl HasReplyableError { } #[uniffi::export(with_foreign)] -pub trait TransactionExists: Send + Sync { +pub trait TransactionFinder: Send + Sync { fn callback(&self, txid: String) -> Result>, ForeignError>; } @@ -1505,16 +1505,18 @@ fn try_deserialize_tx( #[uniffi::export] impl Monitor { - pub fn check_for_broadcast( + pub fn check_for_transaction( &self, - transaction_exists: Arc, + find_transaction: Arc, ) -> MonitorTransition { - MonitorTransition(Arc::new(RwLock::new(Some(self.0.clone().check_for_broadcast(|txid| { - transaction_exists - .callback(txid.to_string()) - .and_then(|buf| buf.map(try_deserialize_tx).transpose()) - .map_err(|e| ImplementationError::new(e).into()) - }))))) + MonitorTransition(Arc::new(RwLock::new(Some(self.0.clone().check_for_transaction( + |txid| { + find_transaction + .callback(txid.to_string()) + .and_then(|buf| buf.map(try_deserialize_tx).transpose()) + .map_err(|e| ImplementationError::new(e).into()) + }, + ))))) } } diff --git a/payjoin/src/core/receive/v2/mod.rs b/payjoin/src/core/receive/v2/mod.rs index 6f36e78cc..81b872b13 100644 --- a/payjoin/src/core/receive/v2/mod.rs +++ b/payjoin/src/core/receive/v2/mod.rs @@ -1469,24 +1469,22 @@ pub struct Monitor { /// The caller should decide the condition that must be satisfied for the Payjoin to be considered /// successful. /// -/// Call [`Receiver::check_for_broadcast`] to confirm the status of the transaction in the +/// Call [`Receiver::check_for_transaction`] to confirm the status of the transaction in the /// network and conclude the Payjoin session. impl Receiver { /// Checks the network for the Payjoin proposal or the fallback transaction using the passed - /// `transaction_exists` closure. Concludes the Payjoin session with a Success if the - /// transaction satisfies the condition. - /// - /// For example, the condition can be if the transaction has been broadcast to the - /// network, or if it has some number of confirmations on the blockchain. + /// `find_transaction` closure, and concludes the Payjoin session once one is found. The + /// closure defines the condition that counts as found — for example presence in the mempool, + /// or some number of confirmations on the blockchain. /// /// If the input address type in the fallback transaction is non-SegWit, then this /// function will directly conclude the Payjoin session with a Success without running the - /// provided `transaction_exists` closure. `transaction_exists` uses the transaction ID to + /// provided `find_transaction` closure. `find_transaction` uses the transaction ID to /// search for the transaction in the network. Since a non-SegWit input signature is going to /// change the TXID of the Payjoin proposal, it cannot be monitored. - pub fn check_for_broadcast( + pub fn check_for_transaction( &self, - transaction_exists: impl Fn(Txid) -> Result, ImplementationError>, + find_transaction: impl Fn(Txid) -> Result, ImplementationError>, ) -> MaybeFatalOrSuccessTransition { let fallback_tx = self.state.fallback_tx(); @@ -1504,7 +1502,7 @@ impl Receiver { // If the sender is spending SegWit-only inputs, then the transaction ID of the Payjoin proposal // is not going to change when the sender signs it. So we can use the TXID to check the // network for the Payjoin proposal. - match transaction_exists(payjoin_txid) { + match find_transaction(payjoin_txid) { Ok(Some(tx)) => { let tx_id = tx.compute_txid(); if tx_id != payjoin_txid { @@ -1531,7 +1529,7 @@ impl Receiver { // If the Payjoin proposal was not found, check the fallback transaction, as it is // the second of two transactions whose IDs the receiver is aware of. - match transaction_exists(fallback_tx.compute_txid()) { + match find_transaction(fallback_tx.compute_txid()) { Ok(Some(_)) => return MaybeFatalOrSuccessTransition::success(SessionEvent::Closed( SessionOutcome::FallbackBroadcasted, @@ -1699,7 +1697,7 @@ pub mod test { // Nothing was spent, should be in the same state let persister = InMemoryPersister::default(); let res = monitor - .check_for_broadcast(|_| Ok(None)) + .check_for_transaction(|_| Ok(None)) .save(&persister) .expect("InMemoryPersister shouldn't fail"); assert!(matches!(res, OptionalTransitionOutcome::Stasis(_))); @@ -1709,7 +1707,7 @@ pub mod test { // Payjoin was broadcasted, should progress to success let persister = InMemoryPersister::default(); let res = monitor - .check_for_broadcast(|_| Ok(Some(payjoin_tx.clone()))) + .check_for_transaction(|_| Ok(Some(payjoin_tx.clone()))) .save(&persister) .expect("InMemoryPersister shouldn't fail"); @@ -1727,7 +1725,7 @@ pub mod test { // Fallback was broadcasted, should progress to success let persister = InMemoryPersister::default(); let res = monitor - .check_for_broadcast(|txid| { + .check_for_transaction(|txid| { // Emulate if one of the fallback outpoints was double spent if txid == original_tx.compute_txid() { Ok(Some(original_tx.clone())) @@ -1764,8 +1762,8 @@ pub mod test { let persister = InMemoryPersister::default(); let res = monitor - .check_for_broadcast(|_| { - panic!("check_for_broadcast should return before this closure is called") + .check_for_transaction(|_| { + panic!("check_for_transaction should return before this closure is called") }) .save(&persister) .expect("InMemoryPersister shouldn't fail"); diff --git a/payjoin/tests/integration.rs b/payjoin/tests/integration.rs index c88931a7b..3a59409ba 100644 --- a/payjoin/tests/integration.rs +++ b/payjoin/tests/integration.rs @@ -557,8 +557,8 @@ mod integration { // The sender is using a non-SegWit address, so their signature is going to change the TXID. So we test whether the // function exists early and does not call the closure. monitoring_payment - .check_for_broadcast(|_| { - panic!("when the sender is using a non-SegWit address type, the check_for_broadcast function should skip the check and return success") + .check_for_transaction(|_| { + panic!("when the sender is using a non-SegWit address type, the check_for_transaction function should skip the check and return success") }) .save(&recv_persister) .expect("receiver should successfully monitor for the payment"); @@ -612,7 +612,7 @@ mod integration { // Receiver should be able to validate that the sender has broadcasted the Payjoin proposal. monitoring_payment - .check_for_broadcast(|txid| { + .check_for_transaction(|txid| { let get_tx_result = receiver.get_raw_transaction(txid); match get_tx_result { Ok(tx) => @@ -694,7 +694,7 @@ mod integration { // Receiver should be able to validate that the sender has broadcasted the Payjoin proposal. monitoring_payment - .check_for_broadcast(|txid| { + .check_for_transaction(|txid| { let get_tx_result = receiver.get_raw_transaction(txid); match get_tx_result { Ok(tx) => @@ -770,10 +770,10 @@ mod integration { ); // Receiver should be able to validate that the sender has broadcasted the fallback transaction. - // The check_for_broadcast closure should be called twice: first for the Payjoin proposal, which will not be found, + // The check_for_transaction closure should be called twice: first for the Payjoin proposal, which will not be found, // and then for the fallback transaction, which will be found.. monitoring_payment - .check_for_broadcast(|txid| { + .check_for_transaction(|txid| { let get_tx_result = receiver.get_raw_transaction(txid); match get_tx_result { Ok(tx) =>