11use std:: collections:: HashMap ;
22use std:: net:: SocketAddr ;
3- use std:: str:: FromStr ;
43use std:: sync:: Arc ;
54
65use anyhow:: { anyhow, Context , Result } ;
@@ -11,7 +10,7 @@ use hyper::server::conn::http1;
1110use hyper:: service:: service_fn;
1211use hyper:: { Method , Request , Response , StatusCode } ;
1312use hyper_util:: rt:: TokioIo ;
14- use payjoin:: bitcoin:: psbt :: Psbt ;
13+ use payjoin:: bitcoin:: consensus :: encode :: serialize_hex ;
1514use payjoin:: bitcoin:: { Amount , FeeRate } ;
1615use payjoin:: receive:: v1:: { PayjoinProposal , UncheckedOriginalPayload } ;
1716use payjoin:: receive:: Error ;
@@ -64,32 +63,44 @@ impl AppTrait for App {
6463 let uri = uri. check_pj_supported ( ) . map_err ( |_| anyhow ! ( "URI does not support Payjoin" ) ) ?;
6564 let amount = uri. amount . ok_or_else ( || anyhow ! ( "please specify the amount in the Uri" ) ) ?;
6665 let psbt = self . create_original_psbt ( & uri. address , amount, fee_rate) ?;
66+ let fallback_tx = psbt. clone ( ) . extract_tx ( ) ?;
6767 let ( req, ctx) = SenderBuilder :: new ( psbt, uri. clone ( ) )
6868 . build_recommended ( fee_rate)
6969 . with_context ( || "Failed to build payjoin request" ) ?
7070 . create_v1_post_request ( ) ;
7171 let http = http_agent ( & self . config ) ?;
7272 let body = String :: from_utf8 ( req. body . clone ( ) ) . unwrap ( ) ;
7373 println ! ( "Sending Original PSBT to {}" , req. url) ;
74- let response = http
74+ let response = match http
7575 . post ( req. url )
7676 . header ( "Content-Type" , req. content_type )
7777 . body ( body. clone ( ) )
7878 . send ( )
7979 . await
80- . with_context ( || "HTTP request failed" ) ?;
81- let fallback_tx = Psbt :: from_str ( & body)
82- . map_err ( |e| anyhow ! ( "Failed to load PSBT from base64: {}" , e) ) ?
83- . extract_tx ( ) ?;
84- println ! ( "Fallback transaction txid: {}" , fallback_tx. compute_txid( ) ) ;
85- println ! (
86- "Fallback transaction hex: {:#}" ,
87- payjoin:: bitcoin:: consensus:: encode:: serialize_hex( & fallback_tx)
88- ) ;
89- let psbt = ctx. process_response ( & response. bytes ( ) . await ?) . map_err ( |e| {
90- tracing:: debug!( "Error processing response: {e:?}" ) ;
91- anyhow ! ( "Failed to process response {e}" )
92- } ) ?;
80+ {
81+ Ok ( response) => response,
82+ Err ( e) => {
83+ tracing:: error!( "HTTP request failed: {e}" ) ;
84+ println ! ( "Payjoin failed. To broadcast the fallback transaction, run:" ) ;
85+ println ! (
86+ " bitcoin-cli -rpcwallet=<wallet> sendrawtransaction {:#}" ,
87+ serialize_hex( & fallback_tx)
88+ ) ;
89+ return Err ( anyhow ! ( "HTTP request failed: {e}" ) ) ;
90+ }
91+ } ;
92+ let psbt = match ctx. process_response ( & response. bytes ( ) . await ?) {
93+ Ok ( psbt) => psbt,
94+ Err ( e) => {
95+ tracing:: error!( "Error processing response: {e:?}" ) ;
96+ println ! ( "Payjoin failed. To broadcast the fallback transaction, run:" ) ;
97+ println ! (
98+ " bitcoin-cli -rpcwallet=<wallet> sendrawtransaction {:#}" ,
99+ serialize_hex( & fallback_tx)
100+ ) ;
101+ return Err ( anyhow ! ( "Failed to process response {e}" ) ) ;
102+ }
103+ } ;
93104
94105 self . process_pj_response ( psbt) ?;
95106 Ok ( ( ) )
0 commit comments