@@ -16,7 +16,7 @@ use hyper_util::rt::TokioIo;
16
16
use payjoin:: bitcoin:: psbt:: Psbt ;
17
17
use payjoin:: bitcoin:: { self , FeeRate } ;
18
18
use payjoin:: receive:: v1:: { PayjoinProposal , UncheckedProposal } ;
19
- use payjoin:: receive:: Error ;
19
+ use payjoin:: receive:: ReplyableError ;
20
20
use payjoin:: send:: v1:: SenderBuilder ;
21
21
use payjoin:: { Uri , UriExt } ;
22
22
use tokio:: net:: TcpListener ;
@@ -225,7 +225,7 @@ impl App {
225
225
. handle_payjoin_post ( req)
226
226
. await
227
227
. map_err ( |e| match e {
228
- Error :: Validation ( e) => {
228
+ ReplyableError :: V1 ( e) => {
229
229
log:: error!( "Error handling request: {}" , e) ;
230
230
Response :: builder ( ) . status ( 400 ) . body ( full ( e. to_string ( ) ) ) . unwrap ( )
231
231
}
@@ -246,12 +246,12 @@ impl App {
246
246
fn handle_get_bip21 (
247
247
& self ,
248
248
amount : Option < Amount > ,
249
- ) -> Result < Response < BoxBody < Bytes , hyper:: Error > > , Error > {
249
+ ) -> Result < Response < BoxBody < Bytes , hyper:: Error > > , ReplyableError > {
250
250
let address = self
251
251
. bitcoind ( )
252
- . map_err ( |e| Error :: Implementation ( e. into ( ) ) ) ?
252
+ . map_err ( |e| ReplyableError :: Implementation ( e. into ( ) ) ) ?
253
253
. get_new_address ( None , None )
254
- . map_err ( |e| Error :: Implementation ( e. into ( ) ) ) ?
254
+ . map_err ( |e| ReplyableError :: Implementation ( e. into ( ) ) ) ?
255
255
. assume_checked ( ) ;
256
256
let uri_string = if let Some ( amount) = amount {
257
257
format ! (
@@ -264,7 +264,7 @@ impl App {
264
264
format ! ( "{}?pj={}" , address. to_qr_uri( ) , self . config. pj_endpoint)
265
265
} ;
266
266
let uri = Uri :: try_from ( uri_string. clone ( ) ) . map_err ( |_| {
267
- Error :: Implementation ( anyhow ! ( "Could not parse payjoin URI string." ) . into ( ) )
267
+ ReplyableError :: Implementation ( anyhow ! ( "Could not parse payjoin URI string." ) . into ( ) )
268
268
} ) ?;
269
269
let _ = uri. assume_checked ( ) ; // we just got it from bitcoind above
270
270
@@ -274,12 +274,16 @@ impl App {
274
274
async fn handle_payjoin_post (
275
275
& self ,
276
276
req : Request < Incoming > ,
277
- ) -> Result < Response < BoxBody < Bytes , hyper:: Error > > , Error > {
277
+ ) -> Result < Response < BoxBody < Bytes , hyper:: Error > > , ReplyableError > {
278
278
let ( parts, body) = req. into_parts ( ) ;
279
279
let headers = Headers ( & parts. headers ) ;
280
280
let query_string = parts. uri . query ( ) . unwrap_or ( "" ) ;
281
- let body =
282
- body. collect ( ) . await . map_err ( |e| Error :: Implementation ( e. into ( ) ) ) ?. aggregate ( ) . reader ( ) ;
281
+ let body = body
282
+ . collect ( )
283
+ . await
284
+ . map_err ( |e| ReplyableError :: Implementation ( e. into ( ) ) ) ?
285
+ . aggregate ( )
286
+ . reader ( ) ;
283
287
let proposal = UncheckedProposal :: from_request ( body, query_string, headers) ?;
284
288
285
289
let payjoin_proposal = self . process_v1_proposal ( proposal) ?;
@@ -292,25 +296,30 @@ impl App {
292
296
Ok ( Response :: new ( full ( body) ) )
293
297
}
294
298
295
- fn process_v1_proposal ( & self , proposal : UncheckedProposal ) -> Result < PayjoinProposal , Error > {
296
- let bitcoind = self . bitcoind ( ) . map_err ( |e| Error :: Implementation ( e. into ( ) ) ) ?;
299
+ fn process_v1_proposal (
300
+ & self ,
301
+ proposal : UncheckedProposal ,
302
+ ) -> Result < PayjoinProposal , ReplyableError > {
303
+ let bitcoind = self . bitcoind ( ) . map_err ( |e| ReplyableError :: Implementation ( e. into ( ) ) ) ?;
297
304
298
305
// in a payment processor where the sender could go offline, this is where you schedule to broadcast the original_tx
299
306
let _to_broadcast_in_failure_case = proposal. extract_tx_to_schedule_broadcast ( ) ;
300
307
301
308
// The network is used for checks later
302
- let network =
303
- bitcoind. get_blockchain_info ( ) . map_err ( |e| Error :: Implementation ( e. into ( ) ) ) ?. chain ;
309
+ let network = bitcoind
310
+ . get_blockchain_info ( )
311
+ . map_err ( |e| ReplyableError :: Implementation ( e. into ( ) ) ) ?
312
+ . chain ;
304
313
305
314
// Receive Check 1: Can Broadcast
306
315
let proposal = proposal. check_broadcast_suitability ( None , |tx| {
307
316
let raw_tx = bitcoin:: consensus:: encode:: serialize_hex ( & tx) ;
308
317
let mempool_results = bitcoind
309
318
. test_mempool_accept ( & [ raw_tx] )
310
- . map_err ( |e| Error :: Implementation ( e. into ( ) ) ) ?;
319
+ . map_err ( |e| ReplyableError :: Implementation ( e. into ( ) ) ) ?;
311
320
match mempool_results. first ( ) {
312
321
Some ( result) => Ok ( result. allowed ) ,
313
- None => Err ( Error :: Implementation (
322
+ None => Err ( ReplyableError :: Implementation (
314
323
anyhow ! ( "No mempool results returned on broadcast check" ) . into ( ) ,
315
324
) ) ,
316
325
}
@@ -323,7 +332,7 @@ impl App {
323
332
bitcoind
324
333
. get_address_info ( & address)
325
334
. map ( |info| info. is_mine . unwrap_or ( false ) )
326
- . map_err ( |e| Error :: Implementation ( e. into ( ) ) )
335
+ . map_err ( |e| ReplyableError :: Implementation ( e. into ( ) ) )
327
336
} else {
328
337
Ok ( false )
329
338
}
@@ -332,7 +341,9 @@ impl App {
332
341
333
342
// Receive Check 3: have we seen this input before? More of a check for non-interactive i.e. payment processor receivers.
334
343
let payjoin = proposal. check_no_inputs_seen_before ( |input| {
335
- self . db . insert_input_seen_before ( * input) . map_err ( |e| Error :: Implementation ( e. into ( ) ) )
344
+ self . db
345
+ . insert_input_seen_before ( * input)
346
+ . map_err ( |e| ReplyableError :: Implementation ( e. into ( ) ) )
336
347
} ) ?;
337
348
log:: trace!( "check3" ) ;
338
349
@@ -341,7 +352,7 @@ impl App {
341
352
bitcoind
342
353
. get_address_info ( & address)
343
354
. map ( |info| info. is_mine . unwrap_or ( false ) )
344
- . map_err ( |e| Error :: Implementation ( e. into ( ) ) )
355
+ . map_err ( |e| ReplyableError :: Implementation ( e. into ( ) ) )
345
356
} else {
346
357
Ok ( false )
347
358
}
@@ -351,12 +362,12 @@ impl App {
351
362
. substitute_receiver_script (
352
363
& bitcoind
353
364
. get_new_address ( None , None )
354
- . map_err ( |e| Error :: Implementation ( e. into ( ) ) ) ?
365
+ . map_err ( |e| ReplyableError :: Implementation ( e. into ( ) ) ) ?
355
366
. require_network ( network)
356
- . map_err ( |e| Error :: Implementation ( e. into ( ) ) ) ?
367
+ . map_err ( |e| ReplyableError :: Implementation ( e. into ( ) ) ) ?
357
368
. script_pubkey ( ) ,
358
369
)
359
- . map_err ( |e| Error :: Implementation ( e. into ( ) ) ) ?
370
+ . map_err ( |e| ReplyableError :: Implementation ( e. into ( ) ) ) ?
360
371
. commit_outputs ( ) ;
361
372
362
373
let provisional_payjoin = try_contributing_inputs ( payjoin. clone ( ) , & bitcoind)
@@ -370,9 +381,10 @@ impl App {
370
381
bitcoind
371
382
. wallet_process_psbt ( & psbt. to_string ( ) , None , None , Some ( false ) )
372
383
. map ( |res| {
373
- Psbt :: from_str ( & res. psbt ) . map_err ( |e| Error :: Implementation ( e. into ( ) ) )
384
+ Psbt :: from_str ( & res. psbt )
385
+ . map_err ( |e| ReplyableError :: Implementation ( e. into ( ) ) )
374
386
} )
375
- . map_err ( |e| Error :: Implementation ( e. into ( ) ) ) ?
387
+ . map_err ( |e| ReplyableError :: Implementation ( e. into ( ) ) ) ?
376
388
} ,
377
389
None ,
378
390
self . config . max_fee_rate ,
0 commit comments