feat: add sort_ascending flag to list_payments (#679)

This commit is contained in:
yse
2025-01-21 08:06:18 +01:00
committed by GitHub
parent 4bd9e5e855
commit 4abcebcde8
13 changed files with 62 additions and 11 deletions

View File

@@ -6,7 +6,7 @@ use std::time::Duration;
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use breez_sdk_liquid::prelude::*; use breez_sdk_liquid::prelude::*;
use clap::{arg, Parser}; use clap::{arg, ArgAction, Parser};
use qrcode_rs::render::unicode; use qrcode_rs::render::unicode;
use qrcode_rs::{EcLevel, QrCode}; use qrcode_rs::{EcLevel, QrCode};
use rustyline::highlight::Highlighter; use rustyline::highlight::Highlighter;
@@ -125,6 +125,10 @@ pub(crate) enum Command {
/// Optional Liquid/Bitcoin address for Bitcoin payment method /// Optional Liquid/Bitcoin address for Bitcoin payment method
#[clap(short = 'a', long = "address")] #[clap(short = 'a', long = "address")]
address: Option<String>, address: Option<String>,
/// Whether or not to sort the payments by ascending timestamp
#[clap(long = "ascending", action = ArgAction::SetTrue)]
sort_ascending: Option<bool>,
}, },
/// Retrieve a payment /// Retrieve a payment
GetPayment { GetPayment {
@@ -490,6 +494,7 @@ pub(crate) async fn handle_command(
offset, offset,
destination, destination,
address, address,
sort_ascending,
} => { } => {
let details = match (destination, address) { let details = match (destination, address) {
(Some(destination), None) => Some(ListPaymentDetails::Liquid { destination }), (Some(destination), None) => Some(ListPaymentDetails::Liquid { destination }),
@@ -506,6 +511,7 @@ pub(crate) async fn handle_command(
limit, limit,
offset, offset,
details, details,
sort_ascending,
}) })
.await?; .await?;
command_result!(payments) command_result!(payments)

View File

@@ -127,6 +127,7 @@ typedef struct wire_cst_list_payments_request {
uint32_t *offset; uint32_t *offset;
uint32_t *limit; uint32_t *limit;
struct wire_cst_list_payment_details *details; struct wire_cst_list_payment_details *details;
bool *sort_ascending;
} wire_cst_list_payments_request; } wire_cst_list_payments_request;
typedef struct wire_cst_ln_url_auth_request_data { typedef struct wire_cst_ln_url_auth_request_data {

View File

@@ -539,6 +539,7 @@ dictionary ListPaymentsRequest {
u32? offset = null; u32? offset = null;
u32? limit = null; u32? limit = null;
ListPaymentDetails? details = null; ListPaymentDetails? details = null;
boolean? sort_ascending = null;
}; };
[Enum] [Enum]

View File

@@ -2928,6 +2928,7 @@ impl SseDecode for crate::model::ListPaymentsRequest {
let mut var_offset = <Option<u32>>::sse_decode(deserializer); let mut var_offset = <Option<u32>>::sse_decode(deserializer);
let mut var_limit = <Option<u32>>::sse_decode(deserializer); let mut var_limit = <Option<u32>>::sse_decode(deserializer);
let mut var_details = <Option<crate::model::ListPaymentDetails>>::sse_decode(deserializer); let mut var_details = <Option<crate::model::ListPaymentDetails>>::sse_decode(deserializer);
let mut var_sortAscending = <Option<bool>>::sse_decode(deserializer);
return crate::model::ListPaymentsRequest { return crate::model::ListPaymentsRequest {
filters: var_filters, filters: var_filters,
states: var_states, states: var_states,
@@ -2936,6 +2937,7 @@ impl SseDecode for crate::model::ListPaymentsRequest {
offset: var_offset, offset: var_offset,
limit: var_limit, limit: var_limit,
details: var_details, details: var_details,
sort_ascending: var_sortAscending,
}; };
} }
} }
@@ -5243,6 +5245,7 @@ impl flutter_rust_bridge::IntoDart for crate::model::ListPaymentsRequest {
self.offset.into_into_dart().into_dart(), self.offset.into_into_dart().into_dart(),
self.limit.into_into_dart().into_dart(), self.limit.into_into_dart().into_dart(),
self.details.into_into_dart().into_dart(), self.details.into_into_dart().into_dart(),
self.sort_ascending.into_into_dart().into_dart(),
] ]
.into_dart() .into_dart()
} }
@@ -7405,6 +7408,7 @@ impl SseEncode for crate::model::ListPaymentsRequest {
<Option<u32>>::sse_encode(self.offset, serializer); <Option<u32>>::sse_encode(self.offset, serializer);
<Option<u32>>::sse_encode(self.limit, serializer); <Option<u32>>::sse_encode(self.limit, serializer);
<Option<crate::model::ListPaymentDetails>>::sse_encode(self.details, serializer); <Option<crate::model::ListPaymentDetails>>::sse_encode(self.details, serializer);
<Option<bool>>::sse_encode(self.sort_ascending, serializer);
} }
} }
@@ -9644,6 +9648,7 @@ mod io {
offset: self.offset.cst_decode(), offset: self.offset.cst_decode(),
limit: self.limit.cst_decode(), limit: self.limit.cst_decode(),
details: self.details.cst_decode(), details: self.details.cst_decode(),
sort_ascending: self.sort_ascending.cst_decode(),
} }
} }
} }
@@ -11089,6 +11094,7 @@ mod io {
offset: core::ptr::null_mut(), offset: core::ptr::null_mut(),
limit: core::ptr::null_mut(), limit: core::ptr::null_mut(),
details: core::ptr::null_mut(), details: core::ptr::null_mut(),
sort_ascending: core::ptr::null_mut(),
} }
} }
} }
@@ -13304,6 +13310,7 @@ mod io {
offset: *mut u32, offset: *mut u32,
limit: *mut u32, limit: *mut u32,
details: *mut wire_cst_list_payment_details, details: *mut wire_cst_list_payment_details,
sort_ascending: *mut bool,
} }
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]

View File

@@ -620,6 +620,7 @@ pub struct ListPaymentsRequest {
pub offset: Option<u32>, pub offset: Option<u32>,
pub limit: Option<u32>, pub limit: Option<u32>,
pub details: Option<ListPaymentDetails>, pub details: Option<ListPaymentDetails>,
pub sort_ascending: Option<bool>,
} }
/// An argument of [ListPaymentsRequest] when calling [crate::sdk::LiquidSdk::list_payments]. /// An argument of [ListPaymentsRequest] when calling [crate::sdk::LiquidSdk::list_payments].

View File

@@ -356,6 +356,7 @@ impl Persister {
where_clause: Option<&str>, where_clause: Option<&str>,
offset: Option<u32>, offset: Option<u32>,
limit: Option<u32>, limit: Option<u32>,
sort_ascending: Option<bool>,
) -> String { ) -> String {
format!( format!(
" "
@@ -438,11 +439,15 @@ impl Persister {
AND ptx.tx_id NOT IN (SELECT refund_tx_id FROM chain_swaps WHERE refund_tx_id NOT NULL)) AND ptx.tx_id NOT IN (SELECT refund_tx_id FROM chain_swaps WHERE refund_tx_id NOT NULL))
AND {} AND {}
ORDER BY -- Order by swap creation time or tx timestamp (in case of direct tx) ORDER BY -- Order by swap creation time or tx timestamp (in case of direct tx)
COALESCE(rs.created_at, ss.created_at, cs.created_at, ptx.timestamp) DESC COALESCE(rs.created_at, ss.created_at, cs.created_at, ptx.timestamp) {}
LIMIT {} LIMIT {}
OFFSET {} OFFSET {}
", ",
where_clause.unwrap_or("true"), where_clause.unwrap_or("true"),
match sort_ascending.unwrap_or(false) {
true => "ASC",
false => "DESC",
},
limit.unwrap_or(u32::MAX), limit.unwrap_or(u32::MAX),
offset.unwrap_or(0), offset.unwrap_or(0),
) )
@@ -735,6 +740,7 @@ impl Persister {
Some("(ptx.tx_id = ?1 OR COALESCE(rs.id, ss.id, cs.id) = ?1)"), Some("(ptx.tx_id = ?1 OR COALESCE(rs.id, ss.id, cs.id) = ?1)"),
None, None,
None, None,
None,
), ),
params![id], params![id],
|row| self.sql_row_to_payment(row), |row| self.sql_row_to_payment(row),
@@ -752,7 +758,7 @@ impl Persister {
Ok(self Ok(self
.get_connection()? .get_connection()?
.query_row( .query_row(
&self.select_payment_query(Some(where_clause), None, None), &self.select_payment_query(Some(where_clause), None, None, None),
params![param], params![param],
|row| self.sql_row_to_payment(row), |row| self.sql_row_to_payment(row),
) )
@@ -768,8 +774,12 @@ impl Persister {
// Assumes there is no swap chaining (send swap lockup tx = receive swap claim tx) // Assumes there is no swap chaining (send swap lockup tx = receive swap claim tx)
let con = self.get_connection()?; let con = self.get_connection()?;
let mut stmt = let mut stmt = con.prepare(&self.select_payment_query(
con.prepare(&self.select_payment_query(maybe_where_clause, req.offset, req.limit))?; maybe_where_clause,
req.offset,
req.limit,
req.sort_ascending,
))?;
let payments: Vec<Payment> = stmt let payments: Vec<Payment> = stmt
.query_map(params_from_iter(where_params), |row| { .query_map(params_from_iter(where_params), |row| {
self.sql_row_to_payment(row) self.sql_row_to_payment(row)

View File

@@ -2092,7 +2092,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
ListPaymentsRequest dco_decode_list_payments_request(dynamic raw) { ListPaymentsRequest dco_decode_list_payments_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs // Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>; final arr = raw as List<dynamic>;
if (arr.length != 7) throw Exception('unexpected arr length: expect 7 but see ${arr.length}'); if (arr.length != 8) throw Exception('unexpected arr length: expect 8 but see ${arr.length}');
return ListPaymentsRequest( return ListPaymentsRequest(
filters: dco_decode_opt_list_payment_type(arr[0]), filters: dco_decode_opt_list_payment_type(arr[0]),
states: dco_decode_opt_list_payment_state(arr[1]), states: dco_decode_opt_list_payment_state(arr[1]),
@@ -2101,6 +2101,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
offset: dco_decode_opt_box_autoadd_u_32(arr[4]), offset: dco_decode_opt_box_autoadd_u_32(arr[4]),
limit: dco_decode_opt_box_autoadd_u_32(arr[5]), limit: dco_decode_opt_box_autoadd_u_32(arr[5]),
details: dco_decode_opt_box_autoadd_list_payment_details(arr[6]), details: dco_decode_opt_box_autoadd_list_payment_details(arr[6]),
sortAscending: dco_decode_opt_box_autoadd_bool(arr[7]),
); );
} }
@@ -4179,6 +4180,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
var var_offset = sse_decode_opt_box_autoadd_u_32(deserializer); var var_offset = sse_decode_opt_box_autoadd_u_32(deserializer);
var var_limit = sse_decode_opt_box_autoadd_u_32(deserializer); var var_limit = sse_decode_opt_box_autoadd_u_32(deserializer);
var var_details = sse_decode_opt_box_autoadd_list_payment_details(deserializer); var var_details = sse_decode_opt_box_autoadd_list_payment_details(deserializer);
var var_sortAscending = sse_decode_opt_box_autoadd_bool(deserializer);
return ListPaymentsRequest( return ListPaymentsRequest(
filters: var_filters, filters: var_filters,
states: var_states, states: var_states,
@@ -4186,7 +4188,8 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
toTimestamp: var_toTimestamp, toTimestamp: var_toTimestamp,
offset: var_offset, offset: var_offset,
limit: var_limit, limit: var_limit,
details: var_details); details: var_details,
sortAscending: var_sortAscending);
} }
@protected @protected
@@ -6321,6 +6324,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_opt_box_autoadd_u_32(self.offset, serializer); sse_encode_opt_box_autoadd_u_32(self.offset, serializer);
sse_encode_opt_box_autoadd_u_32(self.limit, serializer); sse_encode_opt_box_autoadd_u_32(self.limit, serializer);
sse_encode_opt_box_autoadd_list_payment_details(self.details, serializer); sse_encode_opt_box_autoadd_list_payment_details(self.details, serializer);
sse_encode_opt_box_autoadd_bool(self.sortAscending, serializer);
} }
@protected @protected

View File

@@ -2554,6 +2554,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
wireObj.offset = cst_encode_opt_box_autoadd_u_32(apiObj.offset); wireObj.offset = cst_encode_opt_box_autoadd_u_32(apiObj.offset);
wireObj.limit = cst_encode_opt_box_autoadd_u_32(apiObj.limit); wireObj.limit = cst_encode_opt_box_autoadd_u_32(apiObj.limit);
wireObj.details = cst_encode_opt_box_autoadd_list_payment_details(apiObj.details); wireObj.details = cst_encode_opt_box_autoadd_list_payment_details(apiObj.details);
wireObj.sort_ascending = cst_encode_opt_box_autoadd_bool(apiObj.sortAscending);
} }
@protected @protected
@@ -5860,6 +5861,8 @@ final class wire_cst_list_payments_request extends ffi.Struct {
external ffi.Pointer<ffi.Uint32> limit; external ffi.Pointer<ffi.Uint32> limit;
external ffi.Pointer<wire_cst_list_payment_details> details; external ffi.Pointer<wire_cst_list_payment_details> details;
external ffi.Pointer<ffi.Bool> sort_ascending;
} }
final class wire_cst_ln_url_auth_request_data extends ffi.Struct { final class wire_cst_ln_url_auth_request_data extends ffi.Struct {

View File

@@ -453,6 +453,7 @@ class ListPaymentsRequest {
final int? offset; final int? offset;
final int? limit; final int? limit;
final ListPaymentDetails? details; final ListPaymentDetails? details;
final bool? sortAscending;
const ListPaymentsRequest({ const ListPaymentsRequest({
this.filters, this.filters,
@@ -462,6 +463,7 @@ class ListPaymentsRequest {
this.offset, this.offset,
this.limit, this.limit,
this.details, this.details,
this.sortAscending,
}); });
@override @override
@@ -472,7 +474,8 @@ class ListPaymentsRequest {
toTimestamp.hashCode ^ toTimestamp.hashCode ^
offset.hashCode ^ offset.hashCode ^
limit.hashCode ^ limit.hashCode ^
details.hashCode; details.hashCode ^
sortAscending.hashCode;
@override @override
bool operator ==(Object other) => bool operator ==(Object other) =>
@@ -485,7 +488,8 @@ class ListPaymentsRequest {
toTimestamp == other.toTimestamp && toTimestamp == other.toTimestamp &&
offset == other.offset && offset == other.offset &&
limit == other.limit && limit == other.limit &&
details == other.details; details == other.details &&
sortAscending == other.sortAscending;
} }
/// Represents the payment LNURL info /// Represents the payment LNURL info

View File

@@ -4190,6 +4190,8 @@ final class wire_cst_list_payments_request extends ffi.Struct {
external ffi.Pointer<ffi.Uint32> limit; external ffi.Pointer<ffi.Uint32> limit;
external ffi.Pointer<wire_cst_list_payment_details> details; external ffi.Pointer<wire_cst_list_payment_details> details;
external ffi.Pointer<ffi.Bool> sort_ascending;
} }
final class wire_cst_ln_url_auth_request_data extends ffi.Struct { final class wire_cst_ln_url_auth_request_data extends ffi.Struct {

View File

@@ -957,7 +957,8 @@ fun asListPaymentsRequest(listPaymentsRequest: ReadableMap): ListPaymentsRequest
} else { } else {
null null
} }
return ListPaymentsRequest(filters, states, fromTimestamp, toTimestamp, offset, limit, details) val sortAscending = if (hasNonNullKey(listPaymentsRequest, "sortAscending")) listPaymentsRequest.getBoolean("sortAscending") else null
return ListPaymentsRequest(filters, states, fromTimestamp, toTimestamp, offset, limit, details, sortAscending)
} }
fun readableMapOf(listPaymentsRequest: ListPaymentsRequest): ReadableMap = fun readableMapOf(listPaymentsRequest: ListPaymentsRequest): ReadableMap =
@@ -969,6 +970,7 @@ fun readableMapOf(listPaymentsRequest: ListPaymentsRequest): ReadableMap =
"offset" to listPaymentsRequest.offset, "offset" to listPaymentsRequest.offset,
"limit" to listPaymentsRequest.limit, "limit" to listPaymentsRequest.limit,
"details" to listPaymentsRequest.details?.let { readableMapOf(it) }, "details" to listPaymentsRequest.details?.let { readableMapOf(it) },
"sortAscending" to listPaymentsRequest.sortAscending,
) )
fun asListPaymentsRequestList(arr: ReadableArray): List<ListPaymentsRequest> { fun asListPaymentsRequestList(arr: ReadableArray): List<ListPaymentsRequest> {

View File

@@ -1135,7 +1135,15 @@ enum BreezSDKLiquidMapper {
details = try asListPaymentDetails(listPaymentDetails: detailsTmp) details = try asListPaymentDetails(listPaymentDetails: detailsTmp)
} }
return ListPaymentsRequest(filters: filters, states: states, fromTimestamp: fromTimestamp, toTimestamp: toTimestamp, offset: offset, limit: limit, details: details) var sortAscending: Bool?
if hasNonNilKey(data: listPaymentsRequest, key: "sortAscending") {
guard let sortAscendingTmp = listPaymentsRequest["sortAscending"] as? Bool else {
throw SdkError.Generic(message: errUnexpectedValue(fieldName: "sortAscending"))
}
sortAscending = sortAscendingTmp
}
return ListPaymentsRequest(filters: filters, states: states, fromTimestamp: fromTimestamp, toTimestamp: toTimestamp, offset: offset, limit: limit, details: details, sortAscending: sortAscending)
} }
static func dictionaryOf(listPaymentsRequest: ListPaymentsRequest) -> [String: Any?] { static func dictionaryOf(listPaymentsRequest: ListPaymentsRequest) -> [String: Any?] {
@@ -1147,6 +1155,7 @@ enum BreezSDKLiquidMapper {
"offset": listPaymentsRequest.offset == nil ? nil : listPaymentsRequest.offset, "offset": listPaymentsRequest.offset == nil ? nil : listPaymentsRequest.offset,
"limit": listPaymentsRequest.limit == nil ? nil : listPaymentsRequest.limit, "limit": listPaymentsRequest.limit == nil ? nil : listPaymentsRequest.limit,
"details": listPaymentsRequest.details == nil ? nil : dictionaryOf(listPaymentDetails: listPaymentsRequest.details!), "details": listPaymentsRequest.details == nil ? nil : dictionaryOf(listPaymentDetails: listPaymentsRequest.details!),
"sortAscending": listPaymentsRequest.sortAscending == nil ? nil : listPaymentsRequest.sortAscending,
] ]
} }

View File

@@ -183,6 +183,7 @@ export interface ListPaymentsRequest {
offset?: number offset?: number
limit?: number limit?: number
details?: ListPaymentDetails details?: ListPaymentDetails
sortAscending?: boolean
} }
export interface LnOfferBlindedPath { export interface LnOfferBlindedPath {