From 4abcebcde89637f93228a12686cdf7855f17af1f Mon Sep 17 00:00:00 2001 From: yse <70684173+hydra-yse@users.noreply.github.com> Date: Tue, 21 Jan 2025 08:06:18 +0100 Subject: [PATCH] feat: add `sort_ascending` flag to list_payments (#679) --- cli/src/commands.rs | 8 +++++++- .../include/breez_sdk_liquid.h | 1 + lib/bindings/src/breez_sdk_liquid.udl | 1 + lib/core/src/frb_generated.rs | 7 +++++++ lib/core/src/model.rs | 1 + lib/core/src/persist/mod.rs | 18 ++++++++++++++---- packages/dart/lib/src/frb_generated.dart | 8 ++++++-- packages/dart/lib/src/frb_generated.io.dart | 3 +++ packages/dart/lib/src/model.dart | 8 ++++++-- ...lutter_breez_liquid_bindings_generated.dart | 2 ++ .../com/breezsdkliquid/BreezSDKLiquidMapper.kt | 4 +++- .../ios/BreezSDKLiquidMapper.swift | 11 ++++++++++- packages/react-native/src/index.ts | 1 + 13 files changed, 62 insertions(+), 11 deletions(-) diff --git a/cli/src/commands.rs b/cli/src/commands.rs index 95eb9032e..aa2f99825 100644 --- a/cli/src/commands.rs +++ b/cli/src/commands.rs @@ -6,7 +6,7 @@ use std::time::Duration; use anyhow::{anyhow, Result}; use breez_sdk_liquid::prelude::*; -use clap::{arg, Parser}; +use clap::{arg, ArgAction, Parser}; use qrcode_rs::render::unicode; use qrcode_rs::{EcLevel, QrCode}; use rustyline::highlight::Highlighter; @@ -125,6 +125,10 @@ pub(crate) enum Command { /// Optional Liquid/Bitcoin address for Bitcoin payment method #[clap(short = 'a', long = "address")] address: Option, + + /// Whether or not to sort the payments by ascending timestamp + #[clap(long = "ascending", action = ArgAction::SetTrue)] + sort_ascending: Option, }, /// Retrieve a payment GetPayment { @@ -490,6 +494,7 @@ pub(crate) async fn handle_command( offset, destination, address, + sort_ascending, } => { let details = match (destination, address) { (Some(destination), None) => Some(ListPaymentDetails::Liquid { destination }), @@ -506,6 +511,7 @@ pub(crate) async fn handle_command( limit, offset, details, + sort_ascending, }) .await?; command_result!(payments) diff --git a/lib/bindings/langs/flutter/breez_sdk_liquid/include/breez_sdk_liquid.h b/lib/bindings/langs/flutter/breez_sdk_liquid/include/breez_sdk_liquid.h index 5b163dffa..4825aa4b4 100644 --- a/lib/bindings/langs/flutter/breez_sdk_liquid/include/breez_sdk_liquid.h +++ b/lib/bindings/langs/flutter/breez_sdk_liquid/include/breez_sdk_liquid.h @@ -127,6 +127,7 @@ typedef struct wire_cst_list_payments_request { uint32_t *offset; uint32_t *limit; struct wire_cst_list_payment_details *details; + bool *sort_ascending; } wire_cst_list_payments_request; typedef struct wire_cst_ln_url_auth_request_data { diff --git a/lib/bindings/src/breez_sdk_liquid.udl b/lib/bindings/src/breez_sdk_liquid.udl index a22a86386..f78dad260 100644 --- a/lib/bindings/src/breez_sdk_liquid.udl +++ b/lib/bindings/src/breez_sdk_liquid.udl @@ -539,6 +539,7 @@ dictionary ListPaymentsRequest { u32? offset = null; u32? limit = null; ListPaymentDetails? details = null; + boolean? sort_ascending = null; }; [Enum] diff --git a/lib/core/src/frb_generated.rs b/lib/core/src/frb_generated.rs index 2610446d7..ee3fe2c79 100644 --- a/lib/core/src/frb_generated.rs +++ b/lib/core/src/frb_generated.rs @@ -2928,6 +2928,7 @@ impl SseDecode for crate::model::ListPaymentsRequest { let mut var_offset = >::sse_decode(deserializer); let mut var_limit = >::sse_decode(deserializer); let mut var_details = >::sse_decode(deserializer); + let mut var_sortAscending = >::sse_decode(deserializer); return crate::model::ListPaymentsRequest { filters: var_filters, states: var_states, @@ -2936,6 +2937,7 @@ impl SseDecode for crate::model::ListPaymentsRequest { offset: var_offset, limit: var_limit, 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.limit.into_into_dart().into_dart(), self.details.into_into_dart().into_dart(), + self.sort_ascending.into_into_dart().into_dart(), ] .into_dart() } @@ -7405,6 +7408,7 @@ impl SseEncode for crate::model::ListPaymentsRequest { >::sse_encode(self.offset, serializer); >::sse_encode(self.limit, serializer); >::sse_encode(self.details, serializer); + >::sse_encode(self.sort_ascending, serializer); } } @@ -9644,6 +9648,7 @@ mod io { offset: self.offset.cst_decode(), limit: self.limit.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(), limit: core::ptr::null_mut(), details: core::ptr::null_mut(), + sort_ascending: core::ptr::null_mut(), } } } @@ -13304,6 +13310,7 @@ mod io { offset: *mut u32, limit: *mut u32, details: *mut wire_cst_list_payment_details, + sort_ascending: *mut bool, } #[repr(C)] #[derive(Clone, Copy)] diff --git a/lib/core/src/model.rs b/lib/core/src/model.rs index be9057247..5133703eb 100644 --- a/lib/core/src/model.rs +++ b/lib/core/src/model.rs @@ -620,6 +620,7 @@ pub struct ListPaymentsRequest { pub offset: Option, pub limit: Option, pub details: Option, + pub sort_ascending: Option, } /// An argument of [ListPaymentsRequest] when calling [crate::sdk::LiquidSdk::list_payments]. diff --git a/lib/core/src/persist/mod.rs b/lib/core/src/persist/mod.rs index 1719c1163..3656e2bb7 100644 --- a/lib/core/src/persist/mod.rs +++ b/lib/core/src/persist/mod.rs @@ -356,6 +356,7 @@ impl Persister { where_clause: Option<&str>, offset: Option, limit: Option, + sort_ascending: Option, ) -> String { 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 {} 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 {} OFFSET {} ", where_clause.unwrap_or("true"), + match sort_ascending.unwrap_or(false) { + true => "ASC", + false => "DESC", + }, limit.unwrap_or(u32::MAX), offset.unwrap_or(0), ) @@ -735,6 +740,7 @@ impl Persister { Some("(ptx.tx_id = ?1 OR COALESCE(rs.id, ss.id, cs.id) = ?1)"), None, None, + None, ), params![id], |row| self.sql_row_to_payment(row), @@ -752,7 +758,7 @@ impl Persister { Ok(self .get_connection()? .query_row( - &self.select_payment_query(Some(where_clause), None, None), + &self.select_payment_query(Some(where_clause), None, None, None), params![param], |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) let con = self.get_connection()?; - let mut stmt = - con.prepare(&self.select_payment_query(maybe_where_clause, req.offset, req.limit))?; + let mut stmt = con.prepare(&self.select_payment_query( + maybe_where_clause, + req.offset, + req.limit, + req.sort_ascending, + ))?; let payments: Vec = stmt .query_map(params_from_iter(where_params), |row| { self.sql_row_to_payment(row) diff --git a/packages/dart/lib/src/frb_generated.dart b/packages/dart/lib/src/frb_generated.dart index 6d6a6ebc6..2029141e3 100644 --- a/packages/dart/lib/src/frb_generated.dart +++ b/packages/dart/lib/src/frb_generated.dart @@ -2092,7 +2092,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ListPaymentsRequest dco_decode_list_payments_request(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs final arr = raw as List; - 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( filters: dco_decode_opt_list_payment_type(arr[0]), 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]), limit: dco_decode_opt_box_autoadd_u_32(arr[5]), 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_limit = sse_decode_opt_box_autoadd_u_32(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( filters: var_filters, states: var_states, @@ -4186,7 +4188,8 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { toTimestamp: var_toTimestamp, offset: var_offset, limit: var_limit, - details: var_details); + details: var_details, + sortAscending: var_sortAscending); } @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.limit, serializer); sse_encode_opt_box_autoadd_list_payment_details(self.details, serializer); + sse_encode_opt_box_autoadd_bool(self.sortAscending, serializer); } @protected diff --git a/packages/dart/lib/src/frb_generated.io.dart b/packages/dart/lib/src/frb_generated.io.dart index 542dcd615..22e72b5a8 100644 --- a/packages/dart/lib/src/frb_generated.io.dart +++ b/packages/dart/lib/src/frb_generated.io.dart @@ -2554,6 +2554,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { wireObj.offset = cst_encode_opt_box_autoadd_u_32(apiObj.offset); wireObj.limit = cst_encode_opt_box_autoadd_u_32(apiObj.limit); wireObj.details = cst_encode_opt_box_autoadd_list_payment_details(apiObj.details); + wireObj.sort_ascending = cst_encode_opt_box_autoadd_bool(apiObj.sortAscending); } @protected @@ -5860,6 +5861,8 @@ final class wire_cst_list_payments_request extends ffi.Struct { external ffi.Pointer limit; external ffi.Pointer details; + + external ffi.Pointer sort_ascending; } final class wire_cst_ln_url_auth_request_data extends ffi.Struct { diff --git a/packages/dart/lib/src/model.dart b/packages/dart/lib/src/model.dart index 7715ff729..4c9edfa1d 100644 --- a/packages/dart/lib/src/model.dart +++ b/packages/dart/lib/src/model.dart @@ -453,6 +453,7 @@ class ListPaymentsRequest { final int? offset; final int? limit; final ListPaymentDetails? details; + final bool? sortAscending; const ListPaymentsRequest({ this.filters, @@ -462,6 +463,7 @@ class ListPaymentsRequest { this.offset, this.limit, this.details, + this.sortAscending, }); @override @@ -472,7 +474,8 @@ class ListPaymentsRequest { toTimestamp.hashCode ^ offset.hashCode ^ limit.hashCode ^ - details.hashCode; + details.hashCode ^ + sortAscending.hashCode; @override bool operator ==(Object other) => @@ -485,7 +488,8 @@ class ListPaymentsRequest { toTimestamp == other.toTimestamp && offset == other.offset && limit == other.limit && - details == other.details; + details == other.details && + sortAscending == other.sortAscending; } /// Represents the payment LNURL info diff --git a/packages/flutter/lib/flutter_breez_liquid_bindings_generated.dart b/packages/flutter/lib/flutter_breez_liquid_bindings_generated.dart index c6f76f264..5c4578c3a 100644 --- a/packages/flutter/lib/flutter_breez_liquid_bindings_generated.dart +++ b/packages/flutter/lib/flutter_breez_liquid_bindings_generated.dart @@ -4190,6 +4190,8 @@ final class wire_cst_list_payments_request extends ffi.Struct { external ffi.Pointer limit; external ffi.Pointer details; + + external ffi.Pointer sort_ascending; } final class wire_cst_ln_url_auth_request_data extends ffi.Struct { diff --git a/packages/react-native/android/src/main/java/com/breezsdkliquid/BreezSDKLiquidMapper.kt b/packages/react-native/android/src/main/java/com/breezsdkliquid/BreezSDKLiquidMapper.kt index 0d7a5e1a3..8ff8a0275 100644 --- a/packages/react-native/android/src/main/java/com/breezsdkliquid/BreezSDKLiquidMapper.kt +++ b/packages/react-native/android/src/main/java/com/breezsdkliquid/BreezSDKLiquidMapper.kt @@ -957,7 +957,8 @@ fun asListPaymentsRequest(listPaymentsRequest: ReadableMap): ListPaymentsRequest } else { 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 = @@ -969,6 +970,7 @@ fun readableMapOf(listPaymentsRequest: ListPaymentsRequest): ReadableMap = "offset" to listPaymentsRequest.offset, "limit" to listPaymentsRequest.limit, "details" to listPaymentsRequest.details?.let { readableMapOf(it) }, + "sortAscending" to listPaymentsRequest.sortAscending, ) fun asListPaymentsRequestList(arr: ReadableArray): List { diff --git a/packages/react-native/ios/BreezSDKLiquidMapper.swift b/packages/react-native/ios/BreezSDKLiquidMapper.swift index 893276e1c..a69075ee6 100644 --- a/packages/react-native/ios/BreezSDKLiquidMapper.swift +++ b/packages/react-native/ios/BreezSDKLiquidMapper.swift @@ -1135,7 +1135,15 @@ enum BreezSDKLiquidMapper { 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?] { @@ -1147,6 +1155,7 @@ enum BreezSDKLiquidMapper { "offset": listPaymentsRequest.offset == nil ? nil : listPaymentsRequest.offset, "limit": listPaymentsRequest.limit == nil ? nil : listPaymentsRequest.limit, "details": listPaymentsRequest.details == nil ? nil : dictionaryOf(listPaymentDetails: listPaymentsRequest.details!), + "sortAscending": listPaymentsRequest.sortAscending == nil ? nil : listPaymentsRequest.sortAscending, ] } diff --git a/packages/react-native/src/index.ts b/packages/react-native/src/index.ts index 34e817dd5..6299921c9 100644 --- a/packages/react-native/src/index.ts +++ b/packages/react-native/src/index.ts @@ -183,6 +183,7 @@ export interface ListPaymentsRequest { offset?: number limit?: number details?: ListPaymentDetails + sortAscending?: boolean } export interface LnOfferBlindedPath {