@@ -19,7 +19,7 @@ use crate::{
19
19
Application , Auth ,
20
20
} ;
21
21
use adapter:: { client:: Locked , Adapter , Dummy } ;
22
- use axum:: { Extension , Json } ;
22
+ use axum:: { Extension , Json , extract :: Path } ;
23
23
use futures:: future:: try_join_all;
24
24
use hyper:: { Body , Request , Response } ;
25
25
use primitives:: {
@@ -268,6 +268,57 @@ pub async fn get_spender_limits<C: Locked + 'static>(
268
268
Ok ( success_response ( serde_json:: to_string ( & res) ?) )
269
269
}
270
270
271
+ pub async fn get_spender_limits_axum < C : Locked + ' static > (
272
+ Path ( params) : Path < HashMap < String , String > > ,
273
+ Extension ( app) : Extension < Arc < Application < C > > > ,
274
+ Extension ( channel_context) : Extension < ChainOf < Channel > > ,
275
+ ) -> Result < Json < SpenderResponse > , ResponseError > {
276
+ let channel = & channel_context. context ;
277
+
278
+ let spender = params. get ( "addr" ) . ok_or ( ResponseError :: BadRequest ( "Invalid spender address" . to_string ( ) ) ) ?;
279
+ let spender = Address :: from_str ( spender) ?;
280
+
281
+ let latest_spendable = fetch_spendable ( app. pool . clone ( ) , & spender, & channel. id ( ) ) . await ?;
282
+
283
+ let latest_spendable = match latest_spendable {
284
+ Some ( spendable) => spendable,
285
+ None => {
286
+ create_or_update_spendable_document (
287
+ & app. adapter ,
288
+ app. pool . clone ( ) ,
289
+ & channel_context,
290
+ spender,
291
+ )
292
+ . await ?
293
+ }
294
+ } ;
295
+
296
+ let new_state = match get_corresponding_new_state ( & app. pool , & app. logger , channel) . await ? {
297
+ Some ( new_state) => new_state,
298
+ None => return Ok ( Json ( SpenderResponse {
299
+ spender : Spender {
300
+ total_deposited : latest_spendable. deposit . total ,
301
+ total_spent : None ,
302
+ } ,
303
+ } ) ) ,
304
+ } ;
305
+
306
+ let total_spent = new_state
307
+ . balances
308
+ . spenders
309
+ . get ( & spender)
310
+ . map ( |spent| spent. to_owned ( ) ) ;
311
+
312
+ // returned output
313
+ let res = SpenderResponse {
314
+ spender : Spender {
315
+ total_deposited : latest_spendable. deposit . total ,
316
+ total_spent,
317
+ } ,
318
+ } ;
319
+ Ok ( Json ( res) )
320
+ }
321
+
271
322
/// GET `/v5/channel/0xXXX.../spender/all` request.
272
323
///
273
324
/// Response: [`AllSpendersResponse`]
@@ -325,6 +376,56 @@ pub async fn get_all_spender_limits<C: Locked + 'static>(
325
376
Ok ( success_response ( serde_json:: to_string ( & res) ?) )
326
377
}
327
378
379
+ pub async fn get_all_spender_limits_axum < C : Locked + ' static > (
380
+ Extension ( app) : Extension < Arc < Application < C > > > ,
381
+ Extension ( channel_context) : Extension < ChainOf < Channel > > ,
382
+ Qs ( query) : Qs < AllSpendersQuery >
383
+ ) -> Result < Json < AllSpendersResponse > , ResponseError > {
384
+ let channel = channel_context. context ;
385
+
386
+ let limit = app. config . spendable_find_limit ;
387
+ let skip = query
388
+ . page
389
+ . checked_mul ( limit. into ( ) )
390
+ . ok_or_else ( || ResponseError :: FailedValidation ( "Page and/or limit is too large" . into ( ) ) ) ?;
391
+
392
+ let new_state = get_corresponding_new_state ( & app. pool , & app. logger , & channel) . await ?;
393
+
394
+ let mut all_spender_limits: HashMap < Address , Spender > = HashMap :: new ( ) ;
395
+
396
+ let ( all_spendables, pagination) =
397
+ get_all_spendables_for_channel ( app. pool . clone ( ) , & channel. id ( ) , skip, limit. into ( ) ) . await ?;
398
+
399
+ // Using for loop to avoid async closures
400
+ for spendable in all_spendables {
401
+ let spender = spendable. spender ;
402
+ let total_spent = match new_state {
403
+ Some ( ref new_state) => new_state. balances . spenders . get ( & spender) . map ( |balance| {
404
+ spendable
405
+ . deposit
406
+ . total
407
+ . checked_sub ( balance)
408
+ . unwrap_or_default ( )
409
+ } ) ,
410
+ None => None ,
411
+ } ;
412
+
413
+ let spender_info = Spender {
414
+ total_deposited : spendable. deposit . total ,
415
+ total_spent,
416
+ } ;
417
+
418
+ all_spender_limits. insert ( spender, spender_info) ;
419
+ }
420
+
421
+ let res = AllSpendersResponse {
422
+ spenders : all_spender_limits,
423
+ pagination,
424
+ } ;
425
+
426
+ Ok ( Json ( res) )
427
+ }
428
+
328
429
/// POST `/v5/channel/0xXXX.../spender/0xXXX...` request
329
430
///
330
431
/// Internally to make the validator worker add a spender leaf in `NewState` we'll just update `Accounting`
@@ -384,6 +485,63 @@ pub async fn add_spender_leaf<C: Locked + 'static>(
384
485
Ok ( success_response ( serde_json:: to_string ( & res) ?) )
385
486
}
386
487
488
+ /// POST `/v5/channel/0xXXX.../spender/0xXXX...` request
489
+ ///
490
+ /// Internally to make the validator worker add a spender leaf in `NewState` we'll just update `Accounting`
491
+ pub async fn add_spender_leaf_axum < C : Locked + ' static > (
492
+ Path ( params) : Path < HashMap < String , String > > ,
493
+ Extension ( app) : Extension < Arc < Application < C > > > ,
494
+ Extension ( channel) : Extension < ChainOf < Channel > > ,
495
+ ) -> Result < Json < SpenderResponse > , ResponseError > {
496
+ let spender = params. get ( "addr" ) . ok_or ( ResponseError :: BadRequest ( "Invalid spender address" . to_string ( ) ) ) ?;
497
+ let spender = Address :: from_str ( spender) ?;
498
+
499
+ update_accounting (
500
+ app. pool . clone ( ) ,
501
+ channel. context . id ( ) ,
502
+ spender,
503
+ Side :: Spender ,
504
+ UnifiedNum :: from_u64 ( 0 ) ,
505
+ )
506
+ . await ?;
507
+
508
+ let latest_spendable =
509
+ fetch_spendable ( app. pool . clone ( ) , & spender, & channel. context . id ( ) ) . await ?;
510
+
511
+ let latest_spendable = match latest_spendable {
512
+ Some ( spendable) => spendable,
513
+ None => {
514
+ create_or_update_spendable_document ( & app. adapter , app. pool . clone ( ) , & channel, spender)
515
+ . await ?
516
+ }
517
+ } ;
518
+
519
+ let new_state =
520
+ match get_corresponding_new_state ( & app. pool , & app. logger , & channel. context ) . await ? {
521
+ Some ( new_state) => new_state,
522
+ None => return Ok ( Json ( SpenderResponse {
523
+ spender : Spender {
524
+ total_deposited : latest_spendable. deposit . total ,
525
+ total_spent : None ,
526
+ } ,
527
+ } ) ) ,
528
+ } ;
529
+
530
+ let total_spent = new_state
531
+ . balances
532
+ . spenders
533
+ . get ( & spender)
534
+ . map ( |spent| spent. to_owned ( ) ) ;
535
+
536
+ let res = SpenderResponse {
537
+ spender : Spender {
538
+ total_deposited : latest_spendable. deposit . total ,
539
+ total_spent,
540
+ } ,
541
+ } ;
542
+ Ok ( Json ( res) )
543
+ }
544
+
387
545
async fn get_corresponding_new_state (
388
546
pool : & DbPool ,
389
547
logger : & Logger ,
0 commit comments