diff --git a/cli/src/commands.rs b/cli/src/commands.rs index 6e3b3ee6e..eda6151f0 100644 --- a/cli/src/commands.rs +++ b/cli/src/commands.rs @@ -33,8 +33,9 @@ pub(crate) enum Command { #[arg(long)] address: Option, - /// The amount in satoshi to pay, in case of a direct Liquid address - /// or amount-less BIP21 + /// The amount to pay, in case of a direct Liquid address or amount-less BIP21. + /// If an asset id is provided, it is the base unit of that asset depending on its + /// precision, otherwise in satoshi. #[arg(short, long)] receiver_amount: Option, @@ -77,9 +78,9 @@ pub(crate) enum Command { #[arg(short = 'm', long = "method")] payment_method: Option, - /// Amount the payer will send, in satoshi. If receiving a non Liquid Bitcoin - /// asset, this is the units of the asset to receive. - /// If not specified, it will generate a BIP21 URI/Liquid address with no amount + /// The amount the payer should send. If an asset id is provided, it is the base + /// unit of that asset depending on its precision, otherwise in satoshi. + /// If not specified, it will generate a BIP21 URI/address with no amount. #[arg(short, long)] payer_amount: Option, @@ -530,7 +531,9 @@ pub(crate) async fn handle_command( destination, }) } - (None, None, Some(address)) => Some(ListPaymentDetails::Bitcoin { address }), + (None, None, Some(address)) => Some(ListPaymentDetails::Bitcoin { + address: Some(address), + }), _ => None, }; diff --git a/lib/bindings/src/breez_sdk_liquid.udl b/lib/bindings/src/breez_sdk_liquid.udl index 6550ae727..f2b005781 100644 --- a/lib/bindings/src/breez_sdk_liquid.udl +++ b/lib/bindings/src/breez_sdk_liquid.udl @@ -557,7 +557,7 @@ dictionary ListPaymentsRequest { [Enum] interface ListPaymentDetails { Liquid(string? asset_id, string? destination); - Bitcoin(string address); + Bitcoin(string? address); }; [Enum] diff --git a/lib/core/src/frb_generated.rs b/lib/core/src/frb_generated.rs index 1d8e06c72..7f3ee308d 100644 --- a/lib/core/src/frb_generated.rs +++ b/lib/core/src/frb_generated.rs @@ -2908,7 +2908,7 @@ impl SseDecode for crate::model::ListPaymentDetails { }; } 1 => { - let mut var_address = ::sse_decode(deserializer); + let mut var_address = >::sse_decode(deserializer); return crate::model::ListPaymentDetails::Bitcoin { address: var_address, }; @@ -7527,7 +7527,7 @@ impl SseEncode for crate::model::ListPaymentDetails { } crate::model::ListPaymentDetails::Bitcoin { address } => { ::sse_encode(1, serializer); - ::sse_encode(address, serializer); + >::sse_encode(address, serializer); } _ => { unimplemented!(""); diff --git a/lib/core/src/model.rs b/lib/core/src/model.rs index 1a2598ed4..a51e1bf14 100644 --- a/lib/core/src/model.rs +++ b/lib/core/src/model.rs @@ -694,14 +694,19 @@ pub struct ListPaymentsRequest { /// An argument of [ListPaymentsRequest] when calling [crate::sdk::LiquidSdk::list_payments]. #[derive(Debug, Serialize)] pub enum ListPaymentDetails { - /// The Liquid BIP21 URI or address of the payment + /// A Liquid payment Liquid { + /// Optional asset id asset_id: Option, + /// Optional BIP21 URI or address destination: Option, }, - /// The Bitcoin address of the payment - Bitcoin { address: String }, + /// A Bitcoin payment + Bitcoin { + /// Optional address + address: Option, + }, } /// An argument when calling [crate::sdk::LiquidSdk::get_payment]. diff --git a/lib/core/src/persist/mod.rs b/lib/core/src/persist/mod.rs index 7b524b5c7..22d3d7b28 100644 --- a/lib/core/src/persist/mod.rs +++ b/lib/core/src/persist/mod.rs @@ -854,14 +854,16 @@ fn filter_to_where_clause(req: &ListPaymentsRequest) -> (String, Vec { - // Use the lockup address if it's incoming, else use the claim address where_clause.push("cs.id IS NOT NULL".to_string()); - where_clause.push( - "(cs.direction = 0 AND cs.lockup_address = ? OR cs.direction = 1 AND cs.claim_address = ?)" - .to_string(), - ); - where_params.push(Box::new(address)); - where_params.push(Box::new(address)); + if let Some(address) = address { + // Use the lockup address if it's incoming, else use the claim address + where_clause.push( + "(cs.direction = 0 AND cs.lockup_address = ? OR cs.direction = 1 AND cs.claim_address = ?)" + .to_string(), + ); + where_params.push(Box::new(address)); + where_params.push(Box::new(address)); + } } ListPaymentDetails::Liquid { asset_id, diff --git a/packages/dart/lib/src/frb_generated.dart b/packages/dart/lib/src/frb_generated.dart index 8775aa170..d2b5acf5e 100644 --- a/packages/dart/lib/src/frb_generated.dart +++ b/packages/dart/lib/src/frb_generated.dart @@ -2093,7 +2093,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); case 1: return ListPaymentDetails_Bitcoin( - address: dco_decode_String(raw[1]), + address: dco_decode_opt_String(raw[1]), ); default: throw Exception("unreachable"); @@ -4219,7 +4219,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { var var_destination = sse_decode_opt_String(deserializer); return ListPaymentDetails_Liquid(assetId: var_assetId, destination: var_destination); case 1: - var var_address = sse_decode_String(deserializer); + var var_address = sse_decode_opt_String(deserializer); return ListPaymentDetails_Bitcoin(address: var_address); default: throw UnimplementedError(''); @@ -6428,7 +6428,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_opt_String(destination, serializer); case ListPaymentDetails_Bitcoin(address: final address): sse_encode_i_32(1, serializer); - sse_encode_String(address, serializer); + sse_encode_opt_String(address, serializer); } } diff --git a/packages/dart/lib/src/frb_generated.io.dart b/packages/dart/lib/src/frb_generated.io.dart index b80d11af0..09e2b7700 100644 --- a/packages/dart/lib/src/frb_generated.io.dart +++ b/packages/dart/lib/src/frb_generated.io.dart @@ -2605,7 +2605,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { return; } if (apiObj is ListPaymentDetails_Bitcoin) { - var pre_address = cst_encode_String(apiObj.address); + var pre_address = cst_encode_opt_String(apiObj.address); wireObj.tag = 1; wireObj.kind.Bitcoin.address = pre_address; return; diff --git a/packages/dart/lib/src/model.dart b/packages/dart/lib/src/model.dart index 38ac547de..33dc066e9 100644 --- a/packages/dart/lib/src/model.dart +++ b/packages/dart/lib/src/model.dart @@ -451,15 +451,19 @@ enum LiquidNetwork { sealed class ListPaymentDetails with _$ListPaymentDetails { const ListPaymentDetails._(); - /// The Liquid BIP21 URI or address of the payment + /// A Liquid payment const factory ListPaymentDetails.liquid({ + /// Optional asset id String? assetId, + + /// Optional BIP21 URI or address String? destination, }) = ListPaymentDetails_Liquid; - /// The Bitcoin address of the payment + /// A Bitcoin payment const factory ListPaymentDetails.bitcoin({ - required String address, + /// Optional address + String? address, }) = ListPaymentDetails_Bitcoin; } diff --git a/packages/dart/lib/src/model.freezed.dart b/packages/dart/lib/src/model.freezed.dart index e029882da..d9a6d70be 100644 --- a/packages/dart/lib/src/model.freezed.dart +++ b/packages/dart/lib/src/model.freezed.dart @@ -207,8 +207,11 @@ class __$$ListPaymentDetails_LiquidImplCopyWithImpl<$Res> class _$ListPaymentDetails_LiquidImpl extends ListPaymentDetails_Liquid { const _$ListPaymentDetails_LiquidImpl({this.assetId, this.destination}) : super._(); + /// Optional asset id @override final String? assetId; + + /// Optional BIP21 URI or address @override final String? destination; @@ -243,7 +246,10 @@ abstract class ListPaymentDetails_Liquid extends ListPaymentDetails { _$ListPaymentDetails_LiquidImpl; const ListPaymentDetails_Liquid._() : super._(); + /// Optional asset id String? get assetId; + + /// Optional BIP21 URI or address String? get destination; /// Create a copy of ListPaymentDetails @@ -259,7 +265,7 @@ abstract class _$$ListPaymentDetails_BitcoinImplCopyWith<$Res> { _$ListPaymentDetails_BitcoinImpl value, $Res Function(_$ListPaymentDetails_BitcoinImpl) then) = __$$ListPaymentDetails_BitcoinImplCopyWithImpl<$Res>; @useResult - $Res call({String address}); + $Res call({String? address}); } /// @nodoc @@ -275,13 +281,13 @@ class __$$ListPaymentDetails_BitcoinImplCopyWithImpl<$Res> @pragma('vm:prefer-inline') @override $Res call({ - Object? address = null, + Object? address = freezed, }) { return _then(_$ListPaymentDetails_BitcoinImpl( - address: null == address + address: freezed == address ? _value.address : address // ignore: cast_nullable_to_non_nullable - as String, + as String?, )); } } @@ -289,10 +295,11 @@ class __$$ListPaymentDetails_BitcoinImplCopyWithImpl<$Res> /// @nodoc class _$ListPaymentDetails_BitcoinImpl extends ListPaymentDetails_Bitcoin { - const _$ListPaymentDetails_BitcoinImpl({required this.address}) : super._(); + const _$ListPaymentDetails_BitcoinImpl({this.address}) : super._(); + /// Optional address @override - final String address; + final String? address; @override String toString() { @@ -320,11 +327,11 @@ class _$ListPaymentDetails_BitcoinImpl extends ListPaymentDetails_Bitcoin { } abstract class ListPaymentDetails_Bitcoin extends ListPaymentDetails { - const factory ListPaymentDetails_Bitcoin({required final String address}) = - _$ListPaymentDetails_BitcoinImpl; + const factory ListPaymentDetails_Bitcoin({final String? address}) = _$ListPaymentDetails_BitcoinImpl; const ListPaymentDetails_Bitcoin._() : super._(); - String get address; + /// Optional address + String? get address; /// Create a copy of ListPaymentDetails /// with the given fields replaced by the non-null parameter values. 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 4a4e6155c..9fdc00b9c 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 @@ -3048,7 +3048,7 @@ fun asListPaymentDetails(listPaymentDetails: ReadableMap): ListPaymentDetails? { return ListPaymentDetails.Liquid(assetId, destination) } if (type == "bitcoin") { - val address = listPaymentDetails.getString("address")!! + val address = if (hasNonNullKey(listPaymentDetails, "address")) listPaymentDetails.getString("address") else null return ListPaymentDetails.Bitcoin(address) } return null diff --git a/packages/react-native/ios/BreezSDKLiquidMapper.swift b/packages/react-native/ios/BreezSDKLiquidMapper.swift index 94c24900f..02e95c56b 100644 --- a/packages/react-native/ios/BreezSDKLiquidMapper.swift +++ b/packages/react-native/ios/BreezSDKLiquidMapper.swift @@ -3624,9 +3624,8 @@ enum BreezSDKLiquidMapper { return ListPaymentDetails.liquid(assetId: _assetId, destination: _destination) } if type == "bitcoin" { - guard let _address = listPaymentDetails["address"] as? String else { - throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "address", typeName: "ListPaymentDetails")) - } + let _address = listPaymentDetails["address"] as? String + return ListPaymentDetails.bitcoin(address: _address) } @@ -3649,7 +3648,7 @@ enum BreezSDKLiquidMapper { ): return [ "type": "bitcoin", - "address": address, + "address": address == nil ? nil : address, ] } } diff --git a/packages/react-native/src/index.ts b/packages/react-native/src/index.ts index c2f29aba6..4e6ecbc01 100644 --- a/packages/react-native/src/index.ts +++ b/packages/react-native/src/index.ts @@ -571,7 +571,7 @@ export type ListPaymentDetails = { destination?: string } | { type: ListPaymentDetailsVariant.BITCOIN, - address: string + address?: string } export enum LnUrlCallbackStatusVariant {