Skip to content

Commit 2faead0

Browse files
committed
Implement proper pagination for list-payments cli
1 parent a88e44d commit 2faead0

File tree

1 file changed

+55
-15
lines changed

1 file changed

+55
-15
lines changed

ldk-server-cli/src/main.rs

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ use ldk_server_client::error::LdkServerErrorCode::{
77
use ldk_server_client::ldk_server_protos::api::{
88
Bolt11ReceiveRequest, Bolt11SendRequest, Bolt12ReceiveRequest, Bolt12SendRequest,
99
CloseChannelRequest, ForceCloseChannelRequest, GetBalancesRequest, GetNodeInfoRequest,
10-
ListChannelsRequest, ListPaymentsRequest, OnchainReceiveRequest, OnchainSendRequest,
11-
OpenChannelRequest,
10+
ListChannelsRequest, ListPaymentsRequest, ListPaymentsResponse, OnchainReceiveRequest,
11+
OnchainSendRequest, OpenChannelRequest,
1212
};
1313
use ldk_server_client::ldk_server_protos::types::{
14-
bolt11_invoice_description, Bolt11InvoiceDescription, PageToken, Payment,
14+
bolt11_invoice_description, Bolt11InvoiceDescription, PageToken,
1515
};
1616
use std::fmt::Debug;
1717

@@ -106,9 +106,15 @@ enum Commands {
106106
ListPayments {
107107
#[arg(short, long)]
108108
#[arg(
109-
help = "Minimum number of payments to return. If not provided, only the first page of the paginated list is returned."
109+
help = "Fetch at least this many payments by iterating through multiple pages. Returns combined results with the last page token. If not provided, returns only a single page."
110110
)]
111111
number_of_payments: Option<u64>,
112+
#[arg(long)]
113+
#[arg(help = "Page token value to continue from a previous page")]
114+
page_token_value: Option<String>,
115+
#[arg(long)]
116+
#[arg(help = "Page token index to continue from a previous page")]
117+
page_token_index: Option<i64>,
112118
},
113119
}
114120

@@ -230,30 +236,64 @@ async fn main() {
230236
Commands::ListChannels => {
231237
handle_response_result(client.list_channels(ListChannelsRequest {}).await);
232238
},
233-
Commands::ListPayments { number_of_payments } => {
234-
handle_response_result(list_n_payments(client, number_of_payments).await);
239+
Commands::ListPayments { number_of_payments, page_token_value, page_token_index } => {
240+
handle_response_result(
241+
handle_list_payments(
242+
client,
243+
number_of_payments,
244+
page_token_value,
245+
page_token_index,
246+
)
247+
.await,
248+
);
235249
},
236250
}
237251
}
238252

253+
async fn handle_list_payments(
254+
client: LdkServerClient, number_of_payments: Option<u64>, page_token_value: Option<String>,
255+
page_token_index: Option<i64>,
256+
) -> Result<ListPaymentsResponse, LdkServerError> {
257+
if page_token_value.is_some() != page_token_index.is_some() {
258+
return Err(LdkServerError::new(
259+
InternalError,
260+
"Both --page-token-value and --page-token-index must be provided together".to_string(),
261+
));
262+
}
263+
264+
let initial_page_token = match (page_token_value, page_token_index) {
265+
(Some(token), Some(index)) => Some(PageToken { token, index }),
266+
_ => None,
267+
};
268+
269+
if let Some(count) = number_of_payments {
270+
list_n_payments(client, count, initial_page_token).await
271+
} else {
272+
// Fetch single page
273+
client.list_payments(ListPaymentsRequest { page_token: initial_page_token }).await
274+
}
275+
}
276+
239277
async fn list_n_payments(
240-
client: LdkServerClient, number_of_payments: Option<u64>,
241-
) -> Result<Vec<Payment>, LdkServerError> {
242-
let mut payments = Vec::new();
243-
let mut page_token: Option<PageToken> = None;
244-
// If no count is specified, just list the first page.
245-
let target_count = number_of_payments.unwrap_or(0);
278+
client: LdkServerClient, target_count: u64, initial_page_token: Option<PageToken>,
279+
) -> Result<ListPaymentsResponse, LdkServerError> {
280+
let mut payments = Vec::with_capacity(target_count as usize);
281+
let mut page_token = initial_page_token;
282+
let mut next_page_token;
246283

247284
loop {
248285
let response = client.list_payments(ListPaymentsRequest { page_token }).await?;
249286

250287
payments.extend(response.payments);
251-
if payments.len() >= target_count as usize || response.next_page_token.is_none() {
288+
next_page_token = response.next_page_token;
289+
290+
if payments.len() >= target_count as usize || next_page_token.is_none() {
252291
break;
253292
}
254-
page_token = response.next_page_token;
293+
page_token = next_page_token.clone();
255294
}
256-
Ok(payments)
295+
296+
Ok(ListPaymentsResponse { payments, next_page_token })
257297
}
258298

259299
fn handle_response_result<Rs: Debug>(response: Result<Rs, LdkServerError>) {

0 commit comments

Comments
 (0)