@@ -100,6 +100,15 @@ impl SessionHistory {
100100 } )
101101 }
102102
103+ /// Fallback transaction from the session if present
104+ pub fn fallback_tx ( & self ) -> Option < bitcoin:: Transaction > {
105+ self . events . iter ( ) . find_map ( |event| match event {
106+ SessionEvent :: MaybeInputsOwned ( proposal) =>
107+ Some ( proposal. extract_tx_to_schedule_broadcast ( ) ) ,
108+ _ => None ,
109+ } )
110+ }
111+
103112 /// Psbt with receiver contributed inputs
104113 pub fn psbt_with_contributed_inputs ( & self ) -> Option < bitcoin:: Psbt > {
105114 self . events . iter ( ) . find_map ( |event| match event {
@@ -169,7 +178,7 @@ mod tests {
169178 use crate :: receive:: v1:: test:: unchecked_proposal_from_test_vector;
170179 use crate :: receive:: v2:: test:: SHARED_CONTEXT ;
171180 use crate :: receive:: v2:: {
172- PayjoinProposal , ProvisionalProposal , UncheckedProposal , WithContext ,
181+ MaybeInputsOwned , PayjoinProposal , ProvisionalProposal , UncheckedProposal , WithContext ,
173182 } ;
174183
175184 #[ test]
@@ -221,6 +230,7 @@ mod tests {
221230
222231 struct SessionHistoryExpectedOutcome {
223232 psbt_with_contributed_inputs : Option < bitcoin:: Psbt > ,
233+ fallback_tx : Option < bitcoin:: Transaction > ,
224234 }
225235
226236 struct SessionHistoryTest {
@@ -242,6 +252,7 @@ mod tests {
242252 session_history. psbt_with_contributed_inputs( ) ,
243253 test. expected_session_history. psbt_with_contributed_inputs
244254 ) ;
255+ assert_eq ! ( session_history. fallback_tx( ) , test. expected_session_history. fallback_tx) ;
245256 }
246257
247258 #[ test]
@@ -251,6 +262,7 @@ mod tests {
251262 events : vec ! [ SessionEvent :: Created ( session_context. clone( ) ) ] ,
252263 expected_session_history : SessionHistoryExpectedOutcome {
253264 psbt_with_contributed_inputs : None ,
265+ fallback_tx : None ,
254266 } ,
255267 expected_receiver_state : ReceiverTypeState :: WithContext ( Receiver {
256268 state : WithContext { context : session_context } ,
@@ -270,6 +282,7 @@ mod tests {
270282 ] ,
271283 expected_session_history : SessionHistoryExpectedOutcome {
272284 psbt_with_contributed_inputs : None ,
285+ fallback_tx : None ,
273286 } ,
274287 expected_receiver_state : ReceiverTypeState :: UncheckedProposal ( Receiver {
275288 state : UncheckedProposal {
@@ -295,6 +308,7 @@ mod tests {
295308 ] ,
296309 expected_session_history : SessionHistoryExpectedOutcome {
297310 psbt_with_contributed_inputs : None ,
311+ fallback_tx : None ,
298312 } ,
299313 expected_receiver_state : ReceiverTypeState :: UncheckedProposal ( Receiver {
300314 state : UncheckedProposal {
@@ -306,6 +320,31 @@ mod tests {
306320 run_session_history_test ( test) ;
307321 }
308322
323+ #[ test]
324+ fn getting_fallback_tx ( ) {
325+ let session_context = SHARED_CONTEXT . clone ( ) ;
326+ let mut events = vec ! [ ] ;
327+ let unchecked_proposal = unchecked_proposal_from_test_vector ( ) ;
328+ let maybe_inputs_owned = unchecked_proposal. clone ( ) . assume_interactive_receiver ( ) ;
329+ let expected_fallback = maybe_inputs_owned. extract_tx_to_schedule_broadcast ( ) ;
330+
331+ events. push ( SessionEvent :: Created ( session_context. clone ( ) ) ) ;
332+ events. push ( SessionEvent :: UncheckedProposal ( ( unchecked_proposal, None ) ) ) ;
333+ events. push ( SessionEvent :: MaybeInputsOwned ( maybe_inputs_owned. clone ( ) ) ) ;
334+
335+ let test = SessionHistoryTest {
336+ events,
337+ expected_session_history : SessionHistoryExpectedOutcome {
338+ psbt_with_contributed_inputs : None ,
339+ fallback_tx : Some ( expected_fallback) ,
340+ } ,
341+ expected_receiver_state : ReceiverTypeState :: MaybeInputsOwned ( Receiver {
342+ state : MaybeInputsOwned { v1 : maybe_inputs_owned, context : session_context } ,
343+ } ) ,
344+ } ;
345+ run_session_history_test ( test) ;
346+ }
347+
309348 #[ test]
310349 fn test_contributed_inputs ( ) {
311350 let session_context = SHARED_CONTEXT . clone ( ) ;
@@ -327,6 +366,7 @@ mod tests {
327366 . expect ( "Outputs should be identified" ) ;
328367 let wants_inputs = wants_outputs. clone ( ) . commit_outputs ( ) ;
329368 let provisional_proposal = wants_inputs. clone ( ) . commit_inputs ( ) ;
369+ let expected_fallback = maybe_inputs_owned. extract_tx_to_schedule_broadcast ( ) ;
330370
331371 events. push ( SessionEvent :: Created ( session_context. clone ( ) ) ) ;
332372 events. push ( SessionEvent :: UncheckedProposal ( ( unchecked_proposal, None ) ) ) ;
@@ -341,6 +381,7 @@ mod tests {
341381 events,
342382 expected_session_history : SessionHistoryExpectedOutcome {
343383 psbt_with_contributed_inputs : Some ( provisional_proposal. payjoin_psbt . clone ( ) ) ,
384+ fallback_tx : Some ( expected_fallback) ,
344385 } ,
345386 expected_receiver_state : ReceiverTypeState :: ProvisionalProposal ( Receiver {
346387 state : ProvisionalProposal { v1 : provisional_proposal, context : session_context } ,
@@ -374,6 +415,7 @@ mod tests {
374415 . clone ( )
375416 . finalize_proposal ( |psbt| Ok ( psbt. clone ( ) ) , None , None )
376417 . expect ( "Payjoin proposal should be finalized" ) ;
418+ let expected_fallback = maybe_inputs_owned. extract_tx_to_schedule_broadcast ( ) ;
377419
378420 events. push ( SessionEvent :: Created ( session_context. clone ( ) ) ) ;
379421 events. push ( SessionEvent :: UncheckedProposal ( ( unchecked_proposal, None ) ) ) ;
@@ -389,6 +431,7 @@ mod tests {
389431 events,
390432 expected_session_history : SessionHistoryExpectedOutcome {
391433 psbt_with_contributed_inputs : Some ( provisional_proposal. payjoin_psbt . clone ( ) ) ,
434+ fallback_tx : Some ( expected_fallback) ,
392435 } ,
393436 expected_receiver_state : ReceiverTypeState :: PayjoinProposal ( Receiver {
394437 state : PayjoinProposal { v1 : payjoin_proposal, context : session_context } ,
0 commit comments