@@ -25,17 +25,17 @@ use ldk_server_client::ldk_server_protos::api::{
2525 CloseChannelRequest , CloseChannelResponse , ForceCloseChannelRequest , ForceCloseChannelResponse ,
2626 GetBalancesRequest , GetBalancesResponse , GetNodeInfoRequest , GetNodeInfoResponse ,
2727 GetPaymentDetailsRequest , GetPaymentDetailsResponse , ListChannelsRequest , ListChannelsResponse ,
28- ListPaymentsRequest , ListPaymentsResponse , OnchainReceiveRequest , OnchainReceiveResponse ,
29- OnchainSendRequest , OnchainSendResponse , OpenChannelRequest , OpenChannelResponse ,
30- SpliceInRequest , SpliceInResponse , SpliceOutRequest , SpliceOutResponse ,
28+ ListForwardedPaymentsRequest , ListPaymentsRequest , OnchainReceiveRequest ,
29+ OnchainReceiveResponse , OnchainSendRequest , OnchainSendResponse , OpenChannelRequest ,
30+ OpenChannelResponse , SpliceInRequest , SpliceInResponse , SpliceOutRequest , SpliceOutResponse ,
3131 UpdateChannelConfigRequest , UpdateChannelConfigResponse ,
3232} ;
3333use ldk_server_client:: ldk_server_protos:: types:: {
3434 bolt11_invoice_description, Bolt11InvoiceDescription , ChannelConfig , PageToken ,
3535 RouteParametersConfig ,
3636} ;
3737use serde:: Serialize ;
38- use types:: CliListPaymentsResponse ;
38+ use types:: { CliListForwardedPaymentsResponse , CliListPaymentsResponse , CliPaginatedResponse } ;
3939
4040mod config;
4141mod types;
@@ -294,11 +294,22 @@ enum Commands {
294294 #[ arg( help = "Page token to continue from a previous page (format: token:index)" ) ]
295295 page_token : Option < String > ,
296296 } ,
297+ #[ command( about = "Get details of a specific payment by its payment ID" ) ]
297298 GetPaymentDetails {
298299 #[ arg( short, long, help = "The payment ID in hex-encoded form" ) ]
299300 payment_id : String ,
300301 } ,
301- #[ command( about = "Update the config for a previously opened channel" ) ]
302+ #[ command( about = "Retrieves list of all forwarded payments" ) ]
303+ ListForwardedPayments {
304+ #[ arg(
305+ short,
306+ long,
307+ help = "Fetch at least this many forwarded payments by iterating through multiple pages. Returns combined results with the last page token. If not provided, returns only a single page."
308+ ) ]
309+ number_of_payments : Option < u64 > ,
310+ #[ arg( long, help = "Page token to continue from a previous page (format: token:index)" ) ]
311+ page_token : Option < String > ,
312+ } ,
302313 UpdateChannelConfig {
303314 #[ arg( short, long, help = "The local user_channel_id of this channel" ) ]
304315 user_channel_id : String ,
@@ -589,14 +600,38 @@ async fn main() {
589600 . map ( |token_str| parse_page_token ( & token_str) . unwrap_or_else ( |e| handle_error ( e) ) ) ;
590601
591602 handle_response_result :: < _ , CliListPaymentsResponse > (
592- handle_list_payments ( client, number_of_payments, page_token) . await ,
603+ fetch_paginated (
604+ number_of_payments,
605+ page_token,
606+ |pt| client. list_payments ( ListPaymentsRequest { page_token : pt } ) ,
607+ |r| ( r. payments , r. next_page_token ) ,
608+ )
609+ . await ,
593610 ) ;
594611 } ,
595612 Commands :: GetPaymentDetails { payment_id } => {
596613 handle_response_result :: < _ , GetPaymentDetailsResponse > (
597614 client. get_payment_details ( GetPaymentDetailsRequest { payment_id } ) . await ,
598615 ) ;
599616 } ,
617+ Commands :: ListForwardedPayments { number_of_payments, page_token } => {
618+ let page_token = page_token
619+ . map ( |token_str| parse_page_token ( & token_str) . unwrap_or_else ( |e| handle_error ( e) ) ) ;
620+
621+ handle_response_result :: < _ , CliListForwardedPaymentsResponse > (
622+ fetch_paginated (
623+ number_of_payments,
624+ page_token,
625+ |pt| {
626+ client. list_forwarded_payments ( ListForwardedPaymentsRequest {
627+ page_token : pt,
628+ } )
629+ } ,
630+ |r| ( r. forwarded_payments , r. next_page_token ) ,
631+ )
632+ . await ,
633+ ) ;
634+ } ,
600635 Commands :: UpdateChannelConfig {
601636 user_channel_id,
602637 counterparty_node_id,
@@ -648,37 +683,40 @@ fn build_open_channel_config(
648683 } )
649684}
650685
651- async fn handle_list_payments (
652- client : LdkServerClient , number_of_payments : Option < u64 > , initial_page_token : Option < PageToken > ,
653- ) -> Result < ListPaymentsResponse , LdkServerError > {
654- if let Some ( count) = number_of_payments {
655- list_n_payments ( client, count, initial_page_token) . await
656- } else {
657- // Fetch single page
658- client. list_payments ( ListPaymentsRequest { page_token : initial_page_token } ) . await
659- }
660- }
661-
662- async fn list_n_payments (
663- client : LdkServerClient , target_count : u64 , initial_page_token : Option < PageToken > ,
664- ) -> Result < ListPaymentsResponse , LdkServerError > {
665- let mut payments = Vec :: with_capacity ( target_count as usize ) ;
666- let mut page_token = initial_page_token;
667- let mut next_page_token;
668-
669- loop {
670- let response = client. list_payments ( ListPaymentsRequest { page_token } ) . await ?;
671-
672- payments. extend ( response. payments ) ;
673- next_page_token = response. next_page_token ;
686+ async fn fetch_paginated < T , R , Fut > (
687+ target_count : Option < u64 > , initial_page_token : Option < PageToken > ,
688+ fetch_page : impl Fn ( Option < PageToken > ) -> Fut ,
689+ extract : impl Fn ( R ) -> ( Vec < T > , Option < PageToken > ) ,
690+ ) -> Result < CliPaginatedResponse < T > , LdkServerError >
691+ where
692+ Fut : std:: future:: Future < Output = Result < R , LdkServerError > > ,
693+ {
694+ match target_count {
695+ Some ( count) => {
696+ let mut items = Vec :: with_capacity ( count as usize ) ;
697+ let mut page_token = initial_page_token;
698+ let mut next_page_token;
699+
700+ loop {
701+ let response = fetch_page ( page_token) . await ?;
702+ let ( new_items, new_next_page_token) = extract ( response) ;
703+ items. extend ( new_items) ;
704+ next_page_token = new_next_page_token;
705+
706+ if items. len ( ) >= count as usize || next_page_token. is_none ( ) {
707+ break ;
708+ }
709+ page_token = next_page_token;
710+ }
674711
675- if payments. len ( ) >= target_count as usize || next_page_token. is_none ( ) {
676- break ;
677- }
678- page_token = next_page_token;
712+ Ok ( CliPaginatedResponse :: new ( items, next_page_token) )
713+ } ,
714+ None => {
715+ let response = fetch_page ( initial_page_token) . await ?;
716+ let ( items, next_page_token) = extract ( response) ;
717+ Ok ( CliPaginatedResponse :: new ( items, next_page_token) )
718+ } ,
679719 }
680-
681- Ok ( ListPaymentsResponse { payments, next_page_token } )
682720}
683721
684722fn handle_response_result < Rs , Js > ( response : Result < Rs , LdkServerError > )
0 commit comments