From 2ece61cb0d254b8557ba854211d3aaed180e7a1c Mon Sep 17 00:00:00 2001 From: Ross Savage Date: Wed, 8 Jan 2025 11:21:51 +0100 Subject: [PATCH] Add ReceiveAmount and extend PayAmount to handle assets --- cli/src/commands.rs | 45 ++- .../include/breez_sdk_liquid.h | 43 ++- lib/bindings/src/breez_sdk_liquid.udl | 16 +- lib/core/src/frb_generated.rs | 301 +++++++++++++--- lib/core/src/model.rs | 40 ++- lib/core/src/sdk.rs | 215 +++++++---- packages/dart/lib/src/frb_generated.dart | 165 +++++++-- packages/dart/lib/src/frb_generated.io.dart | 147 ++++++-- packages/dart/lib/src/model.dart | 70 ++-- packages/dart/lib/src/model.freezed.dart | 336 ++++++++++++++++-- ...utter_breez_liquid_bindings_generated.dart | 60 +++- .../breezsdkliquid/BreezSDKLiquidMapper.kt | 104 ++++-- .../ios/BreezSDKLiquidMapper.swift | 146 +++++--- packages/react-native/src/index.ts | 32 +- 14 files changed, 1342 insertions(+), 378 deletions(-) diff --git a/cli/src/commands.rs b/cli/src/commands.rs index d22b88143..6e3b3ee6e 100644 --- a/cli/src/commands.rs +++ b/cli/src/commands.rs @@ -36,7 +36,7 @@ pub(crate) enum Command { /// The amount in satoshi to pay, in case of a direct Liquid address /// or amount-less BIP21 #[arg(short, long)] - amount_sat: Option, + receiver_amount: Option, /// Optional id of the asset, in case of a direct Liquid address /// or amount-less BIP21 @@ -77,11 +77,11 @@ pub(crate) enum Command { #[arg(short = 'm', long = "method")] payment_method: Option, - /// Amount the payer will send, in satoshi units. If receiving a non Liquid Bitcoin + /// 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 #[arg(short, long)] - payer_amount_sat: Option, + payer_amount: Option, /// Optional id of the asset to receive when the 'payment_method' is "liquid" #[clap(long = "asset")] @@ -280,21 +280,29 @@ pub(crate) async fn handle_command( Ok(match command { Command::ReceivePayment { payment_method, - payer_amount_sat, + payer_amount, asset_id, description, use_description_hash, } => { + let amount = match asset_id { + Some(asset_id) => Some(ReceiveAmount::Asset { + asset_id, + payer_amount, + }), + None => { + payer_amount.map(|payer_amount_sat| ReceiveAmount::Bitcoin { payer_amount_sat }) + } + }; let prepare_response = sdk .prepare_receive_payment(&PrepareReceiveRequest { - payer_amount_sat, - asset_id, payment_method: payment_method.unwrap_or(PaymentMethod::Lightning), + amount: amount.clone(), }) .await?; let fees = prepare_response.fees_sat; - let confirmation_msg = match payer_amount_sat { + let confirmation_msg = match amount { Some(_) => format!("Fees: {fees} sat. Are the fees acceptable? (y/N)"), None => { let min = prepare_response.min_payer_amount_sat; @@ -348,14 +356,14 @@ pub(crate) async fn handle_command( invoice, offer, address, - amount_sat, + receiver_amount, asset_id, drain, delay, } => { let destination = match (invoice, offer, address) { (Some(invoice), None, None) => Ok(invoice), - (None, Some(offer), None) => match amount_sat { + (None, Some(offer), None) => match receiver_amount { Some(_) => Ok(offer), None => Err(anyhow!( "Must specify an amount for a BOLT12 offer." @@ -371,17 +379,22 @@ pub(crate) async fn handle_command( "Must specify either a BOLT11 invoice, a BOLT12 offer or a direct/BIP21 address." )) }?; - let amount = match (amount_sat, drain.unwrap_or(false)) { - (Some(amount_sat), _) => Some(PayAmount::Receiver { amount_sat }), - (_, true) => Some(PayAmount::Drain), - (_, _) => None, + let amount = match (asset_id, receiver_amount, drain.unwrap_or(false)) { + (Some(asset_id), Some(receiver_amount), _) => Some(PayAmount::Asset { + asset_id, + receiver_amount, + }), + (None, Some(receiver_amount_sat), _) => Some(PayAmount::Bitcoin { + receiver_amount_sat, + }), + (_, _, true) => Some(PayAmount::Drain), + _ => None, }; let prepare_response = sdk .prepare_send_payment(&PrepareSendRequest { destination, amount, - asset_id, }) .await?; @@ -418,8 +431,8 @@ pub(crate) async fn handle_command( } => { let amount = match drain.unwrap_or(false) { true => PayAmount::Drain, - false => PayAmount::Receiver { - amount_sat: receiver_amount_sat.ok_or(anyhow::anyhow!( + false => PayAmount::Bitcoin { + receiver_amount_sat: receiver_amount_sat.ok_or(anyhow::anyhow!( "Must specify `receiver_amount_sat` if not draining" ))?, }, 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 06ea9ac16..0e69f6287 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 @@ -355,12 +355,18 @@ typedef struct wire_cst_prepare_ln_url_pay_request { bool *validate_success_action_url; } wire_cst_prepare_ln_url_pay_request; -typedef struct wire_cst_PayAmount_Receiver { - uint64_t amount_sat; -} wire_cst_PayAmount_Receiver; +typedef struct wire_cst_PayAmount_Bitcoin { + uint64_t receiver_amount_sat; +} wire_cst_PayAmount_Bitcoin; + +typedef struct wire_cst_PayAmount_Asset { + struct wire_cst_list_prim_u_8_strict *asset_id; + uint64_t receiver_amount; +} wire_cst_PayAmount_Asset; typedef union PayAmountKind { - struct wire_cst_PayAmount_Receiver Receiver; + struct wire_cst_PayAmount_Bitcoin Bitcoin; + struct wire_cst_PayAmount_Asset Asset; } PayAmountKind; typedef struct wire_cst_pay_amount { @@ -373,10 +379,28 @@ typedef struct wire_cst_prepare_pay_onchain_request { uint32_t *fee_rate_sat_per_vbyte; } wire_cst_prepare_pay_onchain_request; +typedef struct wire_cst_ReceiveAmount_Bitcoin { + uint64_t payer_amount_sat; +} wire_cst_ReceiveAmount_Bitcoin; + +typedef struct wire_cst_ReceiveAmount_Asset { + struct wire_cst_list_prim_u_8_strict *asset_id; + uint64_t *payer_amount; +} wire_cst_ReceiveAmount_Asset; + +typedef union ReceiveAmountKind { + struct wire_cst_ReceiveAmount_Bitcoin Bitcoin; + struct wire_cst_ReceiveAmount_Asset Asset; +} ReceiveAmountKind; + +typedef struct wire_cst_receive_amount { + int32_t tag; + union ReceiveAmountKind kind; +} wire_cst_receive_amount; + typedef struct wire_cst_prepare_receive_request { int32_t payment_method; - uint64_t *payer_amount_sat; - struct wire_cst_list_prim_u_8_strict *asset_id; + struct wire_cst_receive_amount *amount; } wire_cst_prepare_receive_request; typedef struct wire_cst_prepare_refund_request { @@ -388,13 +412,11 @@ typedef struct wire_cst_prepare_refund_request { typedef struct wire_cst_prepare_send_request { struct wire_cst_list_prim_u_8_strict *destination; struct wire_cst_pay_amount *amount; - struct wire_cst_list_prim_u_8_strict *asset_id; } wire_cst_prepare_send_request; typedef struct wire_cst_prepare_receive_response { int32_t payment_method; - uint64_t *payer_amount_sat; - struct wire_cst_list_prim_u_8_strict *asset_id; + struct wire_cst_receive_amount *amount; uint64_t fees_sat; uint64_t *min_payer_amount_sat; uint64_t *max_payer_amount_sat; @@ -1339,6 +1361,8 @@ struct wire_cst_prepare_refund_request *frbgen_breez_liquid_cst_new_box_autoadd_ struct wire_cst_prepare_send_request *frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_request(void); +struct wire_cst_receive_amount *frbgen_breez_liquid_cst_new_box_autoadd_receive_amount(void); + struct wire_cst_receive_payment_request *frbgen_breez_liquid_cst_new_box_autoadd_receive_payment_request(void); struct wire_cst_refund_request *frbgen_breez_liquid_cst_new_box_autoadd_refund_request(void); @@ -1435,6 +1459,7 @@ static int64_t dummy_method_to_enforce_bundling(void) { dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request); dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_refund_request); dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_request); + dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_receive_amount); dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_receive_payment_request); dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_refund_request); dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_restore_request); diff --git a/lib/bindings/src/breez_sdk_liquid.udl b/lib/bindings/src/breez_sdk_liquid.udl index 4bd909537..fe18f12c6 100644 --- a/lib/bindings/src/breez_sdk_liquid.udl +++ b/lib/bindings/src/breez_sdk_liquid.udl @@ -409,7 +409,6 @@ dictionary LnUrlPayRequest { dictionary PrepareSendRequest { string destination; PayAmount? amount = null; - string? asset_id = null; }; [Enum] @@ -438,17 +437,21 @@ enum PaymentMethod { "LiquidAddress", }; +[Enum] +interface ReceiveAmount { + Bitcoin(u64 payer_amount_sat); + Asset(string asset_id, u64? payer_amount); +}; + dictionary PrepareReceiveRequest { PaymentMethod payment_method; - u64? payer_amount_sat = null; - string? asset_id = null; + ReceiveAmount? amount = null; }; dictionary PrepareReceiveResponse { PaymentMethod payment_method; u64 fees_sat; - u64? payer_amount_sat; - string? asset_id; + ReceiveAmount? amount; u64? min_payer_amount_sat; u64? max_payer_amount_sat; f64? swapper_feerate; @@ -482,7 +485,8 @@ dictionary OnchainPaymentLimitsResponse { [Enum] interface PayAmount { - Receiver(u64 amount_sat); + Bitcoin(u64 receiver_amount_sat); + Asset(string asset_id, u64 receiver_amount); Drain(); }; diff --git a/lib/core/src/frb_generated.rs b/lib/core/src/frb_generated.rs index 86c1eaf37..da6615874 100644 --- a/lib/core/src/frb_generated.rs +++ b/lib/core/src/frb_generated.rs @@ -3627,6 +3627,17 @@ impl SseDecode for Option { } } +impl SseDecode for Option { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + if (::sse_decode(deserializer)) { + return Some(::sse_decode(deserializer)); + } else { + return None; + } + } +} + impl SseDecode for Option { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -3725,12 +3736,20 @@ impl SseDecode for crate::model::PayAmount { let mut tag_ = ::sse_decode(deserializer); match tag_ { 0 => { - let mut var_amountSat = ::sse_decode(deserializer); - return crate::model::PayAmount::Receiver { - amount_sat: var_amountSat, + let mut var_receiverAmountSat = ::sse_decode(deserializer); + return crate::model::PayAmount::Bitcoin { + receiver_amount_sat: var_receiverAmountSat, }; } 1 => { + let mut var_assetId = ::sse_decode(deserializer); + let mut var_receiverAmount = ::sse_decode(deserializer); + return crate::model::PayAmount::Asset { + asset_id: var_assetId, + receiver_amount: var_receiverAmount, + }; + } + 2 => { return crate::model::PayAmount::Drain; } _ => { @@ -4060,12 +4079,10 @@ impl SseDecode for crate::model::PrepareReceiveRequest { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { let mut var_paymentMethod = ::sse_decode(deserializer); - let mut var_payerAmountSat = >::sse_decode(deserializer); - let mut var_assetId = >::sse_decode(deserializer); + let mut var_amount = >::sse_decode(deserializer); return crate::model::PrepareReceiveRequest { payment_method: var_paymentMethod, - payer_amount_sat: var_payerAmountSat, - asset_id: var_assetId, + amount: var_amount, }; } } @@ -4074,16 +4091,14 @@ impl SseDecode for crate::model::PrepareReceiveResponse { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { let mut var_paymentMethod = ::sse_decode(deserializer); - let mut var_payerAmountSat = >::sse_decode(deserializer); - let mut var_assetId = >::sse_decode(deserializer); + let mut var_amount = >::sse_decode(deserializer); let mut var_feesSat = ::sse_decode(deserializer); let mut var_minPayerAmountSat = >::sse_decode(deserializer); let mut var_maxPayerAmountSat = >::sse_decode(deserializer); let mut var_swapperFeerate = >::sse_decode(deserializer); return crate::model::PrepareReceiveResponse { payment_method: var_paymentMethod, - payer_amount_sat: var_payerAmountSat, - asset_id: var_assetId, + amount: var_amount, fees_sat: var_feesSat, min_payer_amount_sat: var_minPayerAmountSat, max_payer_amount_sat: var_maxPayerAmountSat, @@ -4125,11 +4140,9 @@ impl SseDecode for crate::model::PrepareSendRequest { fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { let mut var_destination = ::sse_decode(deserializer); let mut var_amount = >::sse_decode(deserializer); - let mut var_assetId = >::sse_decode(deserializer); return crate::model::PrepareSendRequest { destination: var_destination, amount: var_amount, - asset_id: var_assetId, }; } } @@ -4158,6 +4171,32 @@ impl SseDecode for crate::bindings::Rate { } } +impl SseDecode for crate::model::ReceiveAmount { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { + let mut tag_ = ::sse_decode(deserializer); + match tag_ { + 0 => { + let mut var_payerAmountSat = ::sse_decode(deserializer); + return crate::model::ReceiveAmount::Bitcoin { + payer_amount_sat: var_payerAmountSat, + }; + } + 1 => { + let mut var_assetId = ::sse_decode(deserializer); + let mut var_payerAmount = >::sse_decode(deserializer); + return crate::model::ReceiveAmount::Asset { + asset_id: var_assetId, + payer_amount: var_payerAmount, + }; + } + _ => { + unimplemented!(""); + } + } + } +} + impl SseDecode for crate::model::ReceivePaymentRequest { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self { @@ -5888,10 +5927,23 @@ impl flutter_rust_bridge::IntoIntoDart flutter_rust_bridge::for_generated::DartAbi { match self { - crate::model::PayAmount::Receiver { amount_sat } => { - [0.into_dart(), amount_sat.into_into_dart().into_dart()].into_dart() - } - crate::model::PayAmount::Drain => [1.into_dart()].into_dart(), + crate::model::PayAmount::Bitcoin { + receiver_amount_sat, + } => [ + 0.into_dart(), + receiver_amount_sat.into_into_dart().into_dart(), + ] + .into_dart(), + crate::model::PayAmount::Asset { + asset_id, + receiver_amount, + } => [ + 1.into_dart(), + asset_id.into_into_dart().into_dart(), + receiver_amount.into_into_dart().into_dart(), + ] + .into_dart(), + crate::model::PayAmount::Drain => [2.into_dart()].into_dart(), _ => { unimplemented!(""); } @@ -6271,8 +6323,7 @@ impl flutter_rust_bridge::IntoDart for crate::model::PrepareReceiveRequest { fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { [ self.payment_method.into_into_dart().into_dart(), - self.payer_amount_sat.into_into_dart().into_dart(), - self.asset_id.into_into_dart().into_dart(), + self.amount.into_into_dart().into_dart(), ] .into_dart() } @@ -6293,8 +6344,7 @@ impl flutter_rust_bridge::IntoDart for crate::model::PrepareReceiveResponse { fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { [ self.payment_method.into_into_dart().into_dart(), - self.payer_amount_sat.into_into_dart().into_dart(), - self.asset_id.into_into_dart().into_dart(), + self.amount.into_into_dart().into_dart(), self.fees_sat.into_into_dart().into_dart(), self.min_payer_amount_sat.into_into_dart().into_dart(), self.max_payer_amount_sat.into_into_dart().into_dart(), @@ -6364,7 +6414,6 @@ impl flutter_rust_bridge::IntoDart for crate::model::PrepareSendRequest { [ self.destination.into_into_dart().into_dart(), self.amount.into_into_dart().into_dart(), - self.asset_id.into_into_dart().into_dart(), ] .into_dart() } @@ -6423,6 +6472,36 @@ impl flutter_rust_bridge::IntoIntoDart> } } // Codec=Dco (DartCObject based), see doc to use other codecs +impl flutter_rust_bridge::IntoDart for crate::model::ReceiveAmount { + fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { + match self { + crate::model::ReceiveAmount::Bitcoin { payer_amount_sat } => { + [0.into_dart(), payer_amount_sat.into_into_dart().into_dart()].into_dart() + } + crate::model::ReceiveAmount::Asset { + asset_id, + payer_amount, + } => [ + 1.into_dart(), + asset_id.into_into_dart().into_dart(), + payer_amount.into_into_dart().into_dart(), + ] + .into_dart(), + _ => { + unimplemented!(""); + } + } + } +} +impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::model::ReceiveAmount {} +impl flutter_rust_bridge::IntoIntoDart + for crate::model::ReceiveAmount +{ + fn into_into_dart(self) -> crate::model::ReceiveAmount { + self + } +} +// Codec=Dco (DartCObject based), see doc to use other codecs impl flutter_rust_bridge::IntoDart for crate::model::ReceivePaymentRequest { fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { [ @@ -7941,6 +8020,16 @@ impl SseEncode for Option { } } +impl SseEncode for Option { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + ::sse_encode(self.is_some(), serializer); + if let Some(value) = self { + ::sse_encode(value, serializer); + } + } +} + impl SseEncode for Option { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { @@ -8025,12 +8114,22 @@ impl SseEncode for crate::model::PayAmount { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { match self { - crate::model::PayAmount::Receiver { amount_sat } => { + crate::model::PayAmount::Bitcoin { + receiver_amount_sat, + } => { ::sse_encode(0, serializer); - ::sse_encode(amount_sat, serializer); + ::sse_encode(receiver_amount_sat, serializer); } - crate::model::PayAmount::Drain => { + crate::model::PayAmount::Asset { + asset_id, + receiver_amount, + } => { ::sse_encode(1, serializer); + ::sse_encode(asset_id, serializer); + ::sse_encode(receiver_amount, serializer); + } + crate::model::PayAmount::Drain => { + ::sse_encode(2, serializer); } _ => { unimplemented!(""); @@ -8317,8 +8416,7 @@ impl SseEncode for crate::model::PrepareReceiveRequest { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { ::sse_encode(self.payment_method, serializer); - >::sse_encode(self.payer_amount_sat, serializer); - >::sse_encode(self.asset_id, serializer); + >::sse_encode(self.amount, serializer); } } @@ -8326,8 +8424,7 @@ impl SseEncode for crate::model::PrepareReceiveResponse { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { ::sse_encode(self.payment_method, serializer); - >::sse_encode(self.payer_amount_sat, serializer); - >::sse_encode(self.asset_id, serializer); + >::sse_encode(self.amount, serializer); ::sse_encode(self.fees_sat, serializer); >::sse_encode(self.min_payer_amount_sat, serializer); >::sse_encode(self.max_payer_amount_sat, serializer); @@ -8358,7 +8455,6 @@ impl SseEncode for crate::model::PrepareSendRequest { fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { ::sse_encode(self.destination, serializer); >::sse_encode(self.amount, serializer); - >::sse_encode(self.asset_id, serializer); } } @@ -8378,6 +8474,29 @@ impl SseEncode for crate::bindings::Rate { } } +impl SseEncode for crate::model::ReceiveAmount { + // Codec=Sse (Serialization based), see doc to use other codecs + fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { + match self { + crate::model::ReceiveAmount::Bitcoin { payer_amount_sat } => { + ::sse_encode(0, serializer); + ::sse_encode(payer_amount_sat, serializer); + } + crate::model::ReceiveAmount::Asset { + asset_id, + payer_amount, + } => { + ::sse_encode(1, serializer); + ::sse_encode(asset_id, serializer); + >::sse_encode(payer_amount, serializer); + } + _ => { + unimplemented!(""); + } + } + } +} + impl SseEncode for crate::model::ReceivePaymentRequest { // Codec=Sse (Serialization based), see doc to use other codecs fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) { @@ -9189,6 +9308,13 @@ mod io { CstDecode::::cst_decode(*wrap).into() } } + impl CstDecode for *mut wire_cst_receive_amount { + // Codec=Cst (C-struct based), see doc to use other codecs + fn cst_decode(self) -> crate::model::ReceiveAmount { + let wrap = unsafe { flutter_rust_bridge::for_generated::box_from_leak_ptr(self) }; + CstDecode::::cst_decode(*wrap).into() + } + } impl CstDecode for *mut wire_cst_receive_payment_request { // Codec=Cst (C-struct based), see doc to use other codecs fn cst_decode(self) -> crate::model::ReceivePaymentRequest { @@ -10126,12 +10252,19 @@ mod io { fn cst_decode(self) -> crate::model::PayAmount { match self.tag { 0 => { - let ans = unsafe { self.kind.Receiver }; - crate::model::PayAmount::Receiver { - amount_sat: ans.amount_sat.cst_decode(), + let ans = unsafe { self.kind.Bitcoin }; + crate::model::PayAmount::Bitcoin { + receiver_amount_sat: ans.receiver_amount_sat.cst_decode(), } } - 1 => crate::model::PayAmount::Drain, + 1 => { + let ans = unsafe { self.kind.Asset }; + crate::model::PayAmount::Asset { + asset_id: ans.asset_id.cst_decode(), + receiver_amount: ans.receiver_amount.cst_decode(), + } + } + 2 => crate::model::PayAmount::Drain, _ => unreachable!(), } } @@ -10347,8 +10480,7 @@ mod io { fn cst_decode(self) -> crate::model::PrepareReceiveRequest { crate::model::PrepareReceiveRequest { payment_method: self.payment_method.cst_decode(), - payer_amount_sat: self.payer_amount_sat.cst_decode(), - asset_id: self.asset_id.cst_decode(), + amount: self.amount.cst_decode(), } } } @@ -10357,8 +10489,7 @@ mod io { fn cst_decode(self) -> crate::model::PrepareReceiveResponse { crate::model::PrepareReceiveResponse { payment_method: self.payment_method.cst_decode(), - payer_amount_sat: self.payer_amount_sat.cst_decode(), - asset_id: self.asset_id.cst_decode(), + amount: self.amount.cst_decode(), fees_sat: self.fees_sat.cst_decode(), min_payer_amount_sat: self.min_payer_amount_sat.cst_decode(), max_payer_amount_sat: self.max_payer_amount_sat.cst_decode(), @@ -10392,7 +10523,6 @@ mod io { crate::model::PrepareSendRequest { destination: self.destination.cst_decode(), amount: self.amount.cst_decode(), - asset_id: self.asset_id.cst_decode(), } } } @@ -10414,6 +10544,27 @@ mod io { } } } + impl CstDecode for wire_cst_receive_amount { + // Codec=Cst (C-struct based), see doc to use other codecs + fn cst_decode(self) -> crate::model::ReceiveAmount { + match self.tag { + 0 => { + let ans = unsafe { self.kind.Bitcoin }; + crate::model::ReceiveAmount::Bitcoin { + payer_amount_sat: ans.payer_amount_sat.cst_decode(), + } + } + 1 => { + let ans = unsafe { self.kind.Asset }; + crate::model::ReceiveAmount::Asset { + asset_id: ans.asset_id.cst_decode(), + payer_amount: ans.payer_amount.cst_decode(), + } + } + _ => unreachable!(), + } + } + } impl CstDecode for wire_cst_receive_payment_request { // Codec=Cst (C-struct based), see doc to use other codecs fn cst_decode(self) -> crate::model::ReceivePaymentRequest { @@ -11596,8 +11747,7 @@ mod io { fn new_with_null_ptr() -> Self { Self { payment_method: Default::default(), - payer_amount_sat: core::ptr::null_mut(), - asset_id: core::ptr::null_mut(), + amount: core::ptr::null_mut(), } } } @@ -11610,8 +11760,7 @@ mod io { fn new_with_null_ptr() -> Self { Self { payment_method: Default::default(), - payer_amount_sat: core::ptr::null_mut(), - asset_id: core::ptr::null_mut(), + amount: core::ptr::null_mut(), fees_sat: Default::default(), min_payer_amount_sat: core::ptr::null_mut(), max_payer_amount_sat: core::ptr::null_mut(), @@ -11657,7 +11806,6 @@ mod io { Self { destination: core::ptr::null_mut(), amount: core::ptr::null_mut(), - asset_id: core::ptr::null_mut(), } } } @@ -11692,6 +11840,19 @@ mod io { Self::new_with_null_ptr() } } + impl NewWithNullPtr for wire_cst_receive_amount { + fn new_with_null_ptr() -> Self { + Self { + tag: -1, + kind: ReceiveAmountKind { nil__: () }, + } + } + } + impl Default for wire_cst_receive_amount { + fn default() -> Self { + Self::new_with_null_ptr() + } + } impl NewWithNullPtr for wire_cst_receive_payment_request { fn new_with_null_ptr() -> Self { Self { @@ -12643,6 +12804,14 @@ mod io { ) } + #[no_mangle] + pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_receive_amount( + ) -> *mut wire_cst_receive_amount { + flutter_rust_bridge::for_generated::new_leak_box_ptr( + wire_cst_receive_amount::new_with_null_ptr(), + ) + } + #[no_mangle] pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_receive_payment_request( ) -> *mut wire_cst_receive_payment_request { @@ -13717,13 +13886,20 @@ mod io { #[repr(C)] #[derive(Clone, Copy)] pub union PayAmountKind { - Receiver: wire_cst_PayAmount_Receiver, + Bitcoin: wire_cst_PayAmount_Bitcoin, + Asset: wire_cst_PayAmount_Asset, nil__: (), } #[repr(C)] #[derive(Clone, Copy)] - pub struct wire_cst_PayAmount_Receiver { - amount_sat: u64, + pub struct wire_cst_PayAmount_Bitcoin { + receiver_amount_sat: u64, + } + #[repr(C)] + #[derive(Clone, Copy)] + pub struct wire_cst_PayAmount_Asset { + asset_id: *mut wire_cst_list_prim_u_8_strict, + receiver_amount: u64, } #[repr(C)] #[derive(Clone, Copy)] @@ -13906,15 +14082,13 @@ mod io { #[derive(Clone, Copy)] pub struct wire_cst_prepare_receive_request { payment_method: i32, - payer_amount_sat: *mut u64, - asset_id: *mut wire_cst_list_prim_u_8_strict, + amount: *mut wire_cst_receive_amount, } #[repr(C)] #[derive(Clone, Copy)] pub struct wire_cst_prepare_receive_response { payment_method: i32, - payer_amount_sat: *mut u64, - asset_id: *mut wire_cst_list_prim_u_8_strict, + amount: *mut wire_cst_receive_amount, fees_sat: u64, min_payer_amount_sat: *mut u64, max_payer_amount_sat: *mut u64, @@ -13939,7 +14113,6 @@ mod io { pub struct wire_cst_prepare_send_request { destination: *mut wire_cst_list_prim_u_8_strict, amount: *mut wire_cst_pay_amount, - asset_id: *mut wire_cst_list_prim_u_8_strict, } #[repr(C)] #[derive(Clone, Copy)] @@ -13955,6 +14128,30 @@ mod io { } #[repr(C)] #[derive(Clone, Copy)] + pub struct wire_cst_receive_amount { + tag: i32, + kind: ReceiveAmountKind, + } + #[repr(C)] + #[derive(Clone, Copy)] + pub union ReceiveAmountKind { + Bitcoin: wire_cst_ReceiveAmount_Bitcoin, + Asset: wire_cst_ReceiveAmount_Asset, + nil__: (), + } + #[repr(C)] + #[derive(Clone, Copy)] + pub struct wire_cst_ReceiveAmount_Bitcoin { + payer_amount_sat: u64, + } + #[repr(C)] + #[derive(Clone, Copy)] + pub struct wire_cst_ReceiveAmount_Asset { + asset_id: *mut wire_cst_list_prim_u_8_strict, + payer_amount: *mut u64, + } + #[repr(C)] + #[derive(Clone, Copy)] pub struct wire_cst_receive_payment_request { prepare_response: wire_cst_prepare_receive_response, description: *mut wire_cst_list_prim_u_8_strict, diff --git a/lib/core/src/model.rs b/lib/core/src/model.rs index ceffbee73..3a27577f5 100644 --- a/lib/core/src/model.rs +++ b/lib/core/src/model.rs @@ -345,27 +345,32 @@ pub enum PaymentMethod { LiquidAddress, } +#[derive(Debug, Serialize, Clone)] +pub enum ReceiveAmount { + /// The amount in satoshi that should be paid + Bitcoin { payer_amount_sat: u64 }, + + /// The amount of an asset that should be paid + Asset { + asset_id: String, + payer_amount: Option, + }, +} + /// An argument when calling [crate::sdk::LiquidSdk::prepare_receive_payment]. #[derive(Debug, Serialize)] pub struct PrepareReceiveRequest { pub payment_method: PaymentMethod, - /// The payer amount in satoshi units. If receiving a non Liquid Bitcoin asset, this is the units - /// of the asset to receive. - pub payer_amount_sat: Option, - - /// The id of the asset to receive when the 'payment_method' is Liquid. - /// - /// Defaults to Liquid Bitcoin. - pub asset_id: Option, + /// The amount to be paid in either Bitcoin or another asset + pub amount: Option, } /// Returned when calling [crate::sdk::LiquidSdk::prepare_receive_payment]. #[derive(Debug, Serialize)] pub struct PrepareReceiveResponse { pub payment_method: PaymentMethod, - pub payer_amount_sat: Option, - pub asset_id: Option, + pub amount: Option, /// Generally represents the total fees that would be paid to send or receive this payment. /// @@ -447,10 +452,6 @@ pub struct PrepareSendRequest { /// Should only be set when paying directly onchain or to a BIP21 URI /// where no amount is specified, or when the caller wishes to drain pub amount: Option, - - /// Should only be set when paying directly onchain or to a BIP21 URI - /// where no asset id is specified - pub asset_id: Option, } /// Specifies the supported destinations which can be payed by the SDK @@ -490,8 +491,15 @@ pub struct SendPaymentResponse { #[derive(Debug, Serialize, Clone)] pub enum PayAmount { /// The amount in satoshi that will be received - Receiver { amount_sat: u64 }, - /// Indicates that all available funds should be sent + Bitcoin { receiver_amount_sat: u64 }, + + /// The amount of an asset that will be received + Asset { + asset_id: String, + receiver_amount: u64, + }, + + /// Indicates that all available Bitcoin funds should be sent Drain, } diff --git a/lib/core/src/sdk.rs b/lib/core/src/sdk.rs index c79014e44..af7d98c8f 100644 --- a/lib/core/src/sdk.rs +++ b/lib/core/src/sdk.rs @@ -886,10 +886,9 @@ impl LiquidSdk { /// * `destination` - Either a Liquid BIP21 URI/address, a BOLT11 invoice or a BOLT12 offer /// * `amount` - The optional amount of type [PayAmount]. Should only be specified /// when paying directly onchain or via amount-less BIP21. - /// - [PayAmount::Drain] which uses all funds - /// - [PayAmount::Receiver] which sets the amount the receiver should receive - /// * `asset_id` - The optional id of the asset to send. Should only be specified - /// when paying directly onchain or via amount-less BIP21. + /// - [PayAmount::Drain] which uses all Bitcoin funds + /// - [PayAmount::Bitcoin] which sets the amount in satoshi that will be received + /// - [PayAmount::Asset] which sets the amount of an asset that will be received /// /// # Returns /// Returns a [PrepareSendResponse] containing: @@ -911,22 +910,34 @@ impl LiquidSdk { Ok(InputType::LiquidAddress { address: mut liquid_address_data, }) => { - let amount = match (liquid_address_data.amount_sat, req.amount.clone()) { - (None, None) => { + let amount = match ( + liquid_address_data.amount_sat, + liquid_address_data.asset_id, + req.amount.clone(), + ) { + (None, _, None) => { return Err(PaymentError::AmountMissing { err: "Amount must be set when paying to a Liquid address".to_string(), }); } - (Some(bip21_amount_sat), None) => PayAmount::Receiver { - amount_sat: bip21_amount_sat, + (Some(amount_sat), Some(asset_id), None) => { + if asset_id.eq(LIQUID_BTC_ASSET_ID.as_str()) { + PayAmount::Bitcoin { + receiver_amount_sat: amount_sat, + } + } else { + PayAmount::Asset { + asset_id, + receiver_amount: amount_sat, + } + } + } + (Some(amount_sat), None, None) => PayAmount::Bitcoin { + receiver_amount_sat: amount_sat, }, - (_, Some(amount)) => amount, - }; - asset_id = match (liquid_address_data.asset_id.clone(), req.asset_id.clone()) { - (None, None) => LIQUID_BTC_ASSET_ID.to_string(), - (Some(asset_id), None) => asset_id, - (_, Some(asset_id)) => asset_id, + (_, _, Some(amount)) => amount, }; + ensure_sdk!( liquid_address_data.network == self.config.network.into(), PaymentError::InvalidNetwork { @@ -938,14 +949,8 @@ impl LiquidSdk { } ); - (receiver_amount_sat, fees_sat) = match amount { + (asset_id, receiver_amount_sat, fees_sat) = match amount { PayAmount::Drain => { - ensure_sdk!( - asset_id.eq(LIQUID_BTC_ASSET_ID.as_str()), - PaymentError::Generic { - err: "Cannot drain to a non Liquid Bitcoin asset".to_string(), - } - ); ensure_sdk!( get_info_res.pending_receive_sat == 0 && get_info_res.pending_send_sat == 0, @@ -958,17 +963,37 @@ impl LiquidSdk { .await?; let drain_amount_sat = get_info_res.balance_sat - drain_fees_sat; info!("Drain amount: {drain_amount_sat} sat"); - (drain_amount_sat, drain_fees_sat) + ( + LIQUID_BTC_ASSET_ID.to_string(), + drain_amount_sat, + drain_fees_sat, + ) + } + PayAmount::Bitcoin { + receiver_amount_sat, + } => { + let asset_id = LIQUID_BTC_ASSET_ID.to_string(); + let fees_sat = self + .estimate_onchain_tx_or_drain_tx_fee( + receiver_amount_sat, + &liquid_address_data.address, + &asset_id, + ) + .await?; + (asset_id, receiver_amount_sat, fees_sat) } - PayAmount::Receiver { amount_sat } => { + PayAmount::Asset { + asset_id, + receiver_amount, + } => { let fees_sat = self .estimate_onchain_tx_or_drain_tx_fee( - amount_sat, + receiver_amount, &liquid_address_data.address, &asset_id, ) .await?; - (amount_sat, fees_sat) + (asset_id, receiver_amount, fees_sat) } }; @@ -992,7 +1017,10 @@ impl LiquidSdk { "Expected invoice with an amount", ))? / 1000; - if let Some(PayAmount::Receiver { amount_sat }) = req.amount { + if let Some(PayAmount::Bitcoin { + receiver_amount_sat: amount_sat, + }) = req.amount + { ensure_sdk!( receiver_amount_sat == amount_sat, PaymentError::Generic { @@ -1026,7 +1054,9 @@ impl LiquidSdk { } Ok(InputType::Bolt12Offer { offer }) => { receiver_amount_sat = match req.amount { - Some(PayAmount::Receiver { amount_sat }) => Ok(amount_sat), + Some(PayAmount::Bitcoin { + receiver_amount_sat: amount_sat, + }) => Ok(amount_sat), _ => Err(PaymentError::amount_missing( "Expected PayAmount of type Receiver when processing a Bolt12 offer", )), @@ -1266,7 +1296,11 @@ impl LiquidSdk { ensure_sdk!(tx_fees_sat <= fees_sat, PaymentError::InvalidOrExpiredFees); let tx_id = tx.txid().to_string(); - let payer_amount_sat = receiver_amount_sat + tx_fees_sat; + let amount_sat = if asset_id.eq(LIQUID_BTC_ASSET_ID.as_str()) { + receiver_amount_sat + tx_fees_sat + } else { + receiver_amount_sat + }; info!( "Built onchain L-BTC tx with receiver_amount_sat = {receiver_amount_sat}, fees_sat = {fees_sat} and txid = {tx_id}" ); @@ -1279,7 +1313,7 @@ impl LiquidSdk { let tx_data = PaymentTxData { tx_id: tx_id.clone(), timestamp: Some(utils::now()), - amount_sat: payer_amount_sat, + amount_sat, fees_sat, payment_type: PaymentType::Send, is_confirmed: false, @@ -1492,7 +1526,7 @@ impl LiquidSdk { /// /// * `req` - the [PreparePayOnchainRequest] containing: /// * `amount` - which can be of two types: [PayAmount::Drain], which uses all funds, - /// and [PayAmount::Receiver], which sets the amount the receiver should receive + /// and [PayAmount::Bitcoin], which sets the amount the receiver should receive /// * `fee_rate_sat_per_vbyte` - the optional fee rate of the Bitcoin claim transaction. Defaults to the swapper estimated claim fee pub async fn prepare_pay_onchain( &self, @@ -1510,7 +1544,9 @@ impl LiquidSdk { info!("Preparing for onchain payment of kind: {:?}", req.amount); let (payer_amount_sat, receiver_amount_sat, total_fees_sat) = match req.amount { - PayAmount::Receiver { amount_sat } => { + PayAmount::Bitcoin { + receiver_amount_sat: amount_sat, + } => { let receiver_amount_sat = amount_sat; let user_lockup_amount_sat_without_service_fee = @@ -1554,6 +1590,11 @@ impl LiquidSdk { (payer_amount_sat, receiver_amount_sat, total_fees_sat) } + PayAmount::Asset { .. } => { + return Err(PaymentError::generic( + "Cannot send an asset to a Bitcoin address", + )) + } }; let res = PreparePayOnchainResponse { @@ -1774,23 +1815,33 @@ impl LiquidSdk { /// /// * `req` - the [PrepareReceiveRequest] containing: /// * `payment_method` - the supported payment methods; either an invoice, a Liquid address or a Bitcoin address - /// * `payer_amount_sat` - the amount in satoshis to be paid by the payer - /// * `asset_id` - the id of the asset to receive when receiving via Liquid address + /// * `amount` - The optional amount of type [ReceiveAmount] to be paid. + /// - [PayAmount::Bitcoin] which sets the amount in satoshi that should be paid + /// - [PayAmount::Asset] which sets the amount of an asset that should be paid pub async fn prepare_receive_payment( &self, req: &PrepareReceiveRequest, ) -> Result { self.ensure_is_started().await?; - let mut asset_id = None; let mut min_payer_amount_sat = None; let mut max_payer_amount_sat = None; let mut swapper_feerate = None; let fees_sat; match req.payment_method { PaymentMethod::Lightning => { - let Some(payer_amount_sat) = req.payer_amount_sat else { - return Err(PaymentError::AmountMissing { err: "`payer_amount_sat` must be specified when `PaymentMethod::Lightning` is used.".to_string() }); + let payer_amount_sat = match req.amount { + Some(ReceiveAmount::Asset { .. }) => { + return Err(PaymentError::generic( + "Cannot receive an asset when the payment method is Lightning", + )); + } + Some(ReceiveAmount::Bitcoin { payer_amount_sat }) => payer_amount_sat, + None => { + return Err(PaymentError::generic( + "Bitcoin payer amount must be set when the payment method is Lightning", + )); + } }; let reverse_pair = self .swapper @@ -1815,7 +1866,15 @@ impl LiquidSdk { ); } PaymentMethod::BitcoinAddress => { - let payer_amount_sat = req.payer_amount_sat; + let payer_amount_sat = match req.amount { + Some(ReceiveAmount::Asset { .. }) => { + return Err(PaymentError::generic( + "Cannot receive an asset the payment method is Bitcoin", + )); + } + Some(ReceiveAmount::Bitcoin { payer_amount_sat }) => Some(payer_amount_sat), + None => None, + }; let pair = self.get_and_validate_chain_pair(Direction::Incoming, payer_amount_sat)?; let claim_fees_sat = pair.fees.claim_estimate(); @@ -1832,19 +1891,18 @@ impl LiquidSdk { debug!("Preparing Chain Receive Swap with: payer_amount_sat {payer_amount_sat:?}, fees_sat {fees_sat}"); } PaymentMethod::LiquidAddress => { - asset_id = req - .asset_id - .clone() - .or(Some(LIQUID_BTC_ASSET_ID.to_string())); + let payer_amount_sat = match req.amount { + Some(ReceiveAmount::Asset { payer_amount, .. }) => payer_amount, + Some(ReceiveAmount::Bitcoin { payer_amount_sat }) => Some(payer_amount_sat), + None => None, + }; fees_sat = 0; - let payer_amount_sat = req.payer_amount_sat; - debug!("Preparing Liquid Receive Swap with: amount_sat {payer_amount_sat:?}, fees_sat {fees_sat}"); + debug!("Preparing Liquid Receive with: amount_sat {payer_amount_sat:?}, fees_sat {fees_sat}"); } }; Ok(PrepareReceiveResponse { - payer_amount_sat: req.payer_amount_sat, - asset_id, + amount: req.amount.clone(), fees_sat, payment_method: req.payment_method.clone(), min_payer_amount_sat, @@ -1875,16 +1933,25 @@ impl LiquidSdk { let PrepareReceiveResponse { payment_method, - payer_amount_sat: amount_sat, - asset_id, + amount, fees_sat, .. } = &req.prepare_response; match payment_method { PaymentMethod::Lightning => { - let Some(amount_sat) = amount_sat else { - return Err(PaymentError::AmountMissing { err: "`amount_sat` must be specified when `PaymentMethod::Lightning` is used.".to_string() }); + let amount_sat = match amount.clone() { + Some(ReceiveAmount::Asset { .. }) => { + return Err(PaymentError::generic( + "Cannot receive an asset when the payment method is Lightning", + )); + } + Some(ReceiveAmount::Bitcoin { payer_amount_sat }) => payer_amount_sat, + None => { + return Err(PaymentError::generic( + "Bitcoin payer amount must be set when the payment method is Lightning", + )); + } }; let (description, description_hash) = match ( req.description.clone(), @@ -1901,21 +1968,39 @@ impl LiquidSdk { }) } }; - self.create_receive_swap(*amount_sat, *fees_sat, description, description_hash) + self.create_receive_swap(amount_sat, *fees_sat, description, description_hash) .await } - PaymentMethod::BitcoinAddress => self.receive_onchain(*amount_sat, *fees_sat).await, + PaymentMethod::BitcoinAddress => { + let amount_sat = match amount.clone() { + Some(ReceiveAmount::Asset { .. }) => { + return Err(PaymentError::generic( + "Cannot receive an asset the payment method is Bitcoin", + )); + } + Some(ReceiveAmount::Bitcoin { payer_amount_sat }) => Some(payer_amount_sat), + None => None, + }; + self.receive_onchain(amount_sat, *fees_sat).await + } PaymentMethod::LiquidAddress => { - let Some(asset_id) = asset_id else { - return Err(PaymentError::Generic { err: "`asset_id` must be specified when `PaymentMethod::LiquidAddress` is used.".to_string() }); + let (asset_id, amount_sat) = match amount.clone() { + Some(ReceiveAmount::Asset { + asset_id, + payer_amount, + }) => (asset_id, payer_amount), + Some(ReceiveAmount::Bitcoin { payer_amount_sat }) => { + (LIQUID_BTC_ASSET_ID.to_string(), Some(payer_amount_sat)) + } + None => (LIQUID_BTC_ASSET_ID.to_string(), None), }; - let address = self.onchain_wallet.next_unused_address().await?.to_string(); + let address = self.onchain_wallet.next_unused_address().await?.to_string(); let receive_destination = match amount_sat { Some(amount_sat) => LiquidAddressData { address: address.to_string(), network: self.config.network.into(), - amount_sat: Some(*amount_sat), + amount_sat: Some(amount_sat), asset_id: Some(asset_id.clone()), label: None, message: req.description.clone(), @@ -2333,16 +2418,20 @@ impl LiquidSdk { let res = self .prepare_receive_payment(&PrepareReceiveRequest { payment_method: PaymentMethod::BitcoinAddress, - payer_amount_sat: Some(req.amount_sat), - asset_id: None, + amount: Some(ReceiveAmount::Bitcoin { + payer_amount_sat: req.amount_sat, + }), }) .await?; - let Some(amount_sat) = res.payer_amount_sat else { + let Some(ReceiveAmount::Bitcoin { + payer_amount_sat: amount_sat, + }) = res.amount + else { return Err(PaymentError::Generic { err: format!( - "Expected field `amount_sat` from response, got {:?}", - res.payer_amount_sat + "Error preparing receive payment, got amount: {:?}", + res.amount ), }); }; @@ -2832,7 +2921,6 @@ impl LiquidSdk { .prepare_send_payment(&PrepareSendRequest { destination: data.pr.clone(), amount: None, - asset_id: None, }) .await .map_err(|e| LnUrlPayError::Generic { err: e.to_string() })?; @@ -2975,8 +3063,9 @@ impl LiquidSdk { .prepare_receive_payment(&{ PrepareReceiveRequest { payment_method: PaymentMethod::Lightning, - payer_amount_sat: Some(req.amount_msat / 1_000), - asset_id: None, + amount: Some(ReceiveAmount::Bitcoin { + payer_amount_sat: req.amount_msat / 1_000, + }), } }) .await?; diff --git a/packages/dart/lib/src/frb_generated.dart b/packages/dart/lib/src/frb_generated.dart index 97e525015..a18c52ed1 100644 --- a/packages/dart/lib/src/frb_generated.dart +++ b/packages/dart/lib/src/frb_generated.dart @@ -1675,6 +1675,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return dco_decode_prepare_send_request(raw); } + @protected + ReceiveAmount dco_decode_box_autoadd_receive_amount(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return dco_decode_receive_amount(raw); + } + @protected ReceivePaymentRequest dco_decode_box_autoadd_receive_payment_request(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -2599,6 +2605,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return raw == null ? null : dco_decode_box_autoadd_payment(raw); } + @protected + ReceiveAmount? dco_decode_opt_box_autoadd_receive_amount(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + return raw == null ? null : dco_decode_box_autoadd_receive_amount(raw); + } + @protected SuccessAction? dco_decode_opt_box_autoadd_success_action(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -2652,10 +2664,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { // Codec=Dco (DartCObject based), see doc to use other codecs switch (raw[0]) { case 0: - return PayAmount_Receiver( - amountSat: dco_decode_u_64(raw[1]), + return PayAmount_Bitcoin( + receiverAmountSat: dco_decode_u_64(raw[1]), ); case 1: + return PayAmount_Asset( + assetId: dco_decode_String(raw[1]), + receiverAmount: dco_decode_u_64(raw[2]), + ); + case 2: return PayAmount_Drain(); default: throw Exception("unreachable"); @@ -2893,11 +2910,10 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { PrepareReceiveRequest dco_decode_prepare_receive_request(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs final arr = raw as List; - if (arr.length != 3) throw Exception('unexpected arr length: expect 3 but see ${arr.length}'); + if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}'); return PrepareReceiveRequest( paymentMethod: dco_decode_payment_method(arr[0]), - payerAmountSat: dco_decode_opt_box_autoadd_u_64(arr[1]), - assetId: dco_decode_opt_String(arr[2]), + amount: dco_decode_opt_box_autoadd_receive_amount(arr[1]), ); } @@ -2905,15 +2921,14 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { PrepareReceiveResponse dco_decode_prepare_receive_response(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 != 6) throw Exception('unexpected arr length: expect 6 but see ${arr.length}'); return PrepareReceiveResponse( paymentMethod: dco_decode_payment_method(arr[0]), - payerAmountSat: dco_decode_opt_box_autoadd_u_64(arr[1]), - assetId: dco_decode_opt_String(arr[2]), - feesSat: dco_decode_u_64(arr[3]), - minPayerAmountSat: dco_decode_opt_box_autoadd_u_64(arr[4]), - maxPayerAmountSat: dco_decode_opt_box_autoadd_u_64(arr[5]), - swapperFeerate: dco_decode_opt_box_autoadd_f_64(arr[6]), + amount: dco_decode_opt_box_autoadd_receive_amount(arr[1]), + feesSat: dco_decode_u_64(arr[2]), + minPayerAmountSat: dco_decode_opt_box_autoadd_u_64(arr[3]), + maxPayerAmountSat: dco_decode_opt_box_autoadd_u_64(arr[4]), + swapperFeerate: dco_decode_opt_box_autoadd_f_64(arr[5]), ); } @@ -2945,11 +2960,10 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { PrepareSendRequest dco_decode_prepare_send_request(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs final arr = raw as List; - if (arr.length != 3) throw Exception('unexpected arr length: expect 3 but see ${arr.length}'); + if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}'); return PrepareSendRequest( destination: dco_decode_String(arr[0]), amount: dco_decode_opt_box_autoadd_pay_amount(arr[1]), - assetId: dco_decode_opt_String(arr[2]), ); } @@ -2975,6 +2989,24 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { ); } + @protected + ReceiveAmount dco_decode_receive_amount(dynamic raw) { + // Codec=Dco (DartCObject based), see doc to use other codecs + switch (raw[0]) { + case 0: + return ReceiveAmount_Bitcoin( + payerAmountSat: dco_decode_u_64(raw[1]), + ); + case 1: + return ReceiveAmount_Asset( + assetId: dco_decode_String(raw[1]), + payerAmount: dco_decode_opt_box_autoadd_u_64(raw[2]), + ); + default: + throw Exception("unreachable"); + } + } + @protected ReceivePaymentRequest dco_decode_receive_payment_request(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -3712,6 +3744,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return (sse_decode_prepare_send_request(deserializer)); } + @protected + ReceiveAmount sse_decode_box_autoadd_receive_amount(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + return (sse_decode_receive_amount(deserializer)); + } + @protected ReceivePaymentRequest sse_decode_box_autoadd_receive_payment_request(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -4736,6 +4774,17 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { } } + @protected + ReceiveAmount? sse_decode_opt_box_autoadd_receive_amount(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + + if (sse_decode_bool(deserializer)) { + return (sse_decode_box_autoadd_receive_amount(deserializer)); + } else { + return null; + } + } + @protected SuccessAction? sse_decode_opt_box_autoadd_success_action(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -4831,9 +4880,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { var tag_ = sse_decode_i_32(deserializer); switch (tag_) { case 0: - var var_amountSat = sse_decode_u_64(deserializer); - return PayAmount_Receiver(amountSat: var_amountSat); + var var_receiverAmountSat = sse_decode_u_64(deserializer); + return PayAmount_Bitcoin(receiverAmountSat: var_receiverAmountSat); case 1: + var var_assetId = sse_decode_String(deserializer); + var var_receiverAmount = sse_decode_u_64(deserializer); + return PayAmount_Asset(assetId: var_assetId, receiverAmount: var_receiverAmount); + case 2: return PayAmount_Drain(); default: throw UnimplementedError(''); @@ -5077,26 +5130,22 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { PrepareReceiveRequest sse_decode_prepare_receive_request(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs var var_paymentMethod = sse_decode_payment_method(deserializer); - var var_payerAmountSat = sse_decode_opt_box_autoadd_u_64(deserializer); - var var_assetId = sse_decode_opt_String(deserializer); - return PrepareReceiveRequest( - paymentMethod: var_paymentMethod, payerAmountSat: var_payerAmountSat, assetId: var_assetId); + var var_amount = sse_decode_opt_box_autoadd_receive_amount(deserializer); + return PrepareReceiveRequest(paymentMethod: var_paymentMethod, amount: var_amount); } @protected PrepareReceiveResponse sse_decode_prepare_receive_response(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs var var_paymentMethod = sse_decode_payment_method(deserializer); - var var_payerAmountSat = sse_decode_opt_box_autoadd_u_64(deserializer); - var var_assetId = sse_decode_opt_String(deserializer); + var var_amount = sse_decode_opt_box_autoadd_receive_amount(deserializer); var var_feesSat = sse_decode_u_64(deserializer); var var_minPayerAmountSat = sse_decode_opt_box_autoadd_u_64(deserializer); var var_maxPayerAmountSat = sse_decode_opt_box_autoadd_u_64(deserializer); var var_swapperFeerate = sse_decode_opt_box_autoadd_f_64(deserializer); return PrepareReceiveResponse( paymentMethod: var_paymentMethod, - payerAmountSat: var_payerAmountSat, - assetId: var_assetId, + amount: var_amount, feesSat: var_feesSat, minPayerAmountSat: var_minPayerAmountSat, maxPayerAmountSat: var_maxPayerAmountSat, @@ -5129,8 +5178,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { // Codec=Sse (Serialization based), see doc to use other codecs var var_destination = sse_decode_String(deserializer); var var_amount = sse_decode_opt_box_autoadd_pay_amount(deserializer); - var var_assetId = sse_decode_opt_String(deserializer); - return PrepareSendRequest(destination: var_destination, amount: var_amount, assetId: var_assetId); + return PrepareSendRequest(destination: var_destination, amount: var_amount); } @protected @@ -5149,6 +5197,24 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return Rate(coin: var_coin, value: var_value); } + @protected + ReceiveAmount sse_decode_receive_amount(SseDeserializer deserializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + + var tag_ = sse_decode_i_32(deserializer); + switch (tag_) { + case 0: + var var_payerAmountSat = sse_decode_u_64(deserializer); + return ReceiveAmount_Bitcoin(payerAmountSat: var_payerAmountSat); + case 1: + var var_assetId = sse_decode_String(deserializer); + var var_payerAmount = sse_decode_opt_box_autoadd_u_64(deserializer); + return ReceiveAmount_Asset(assetId: var_assetId, payerAmount: var_payerAmount); + default: + throw UnimplementedError(''); + } + } + @protected ReceivePaymentRequest sse_decode_receive_payment_request(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -5945,6 +6011,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_prepare_send_request(self, serializer); } + @protected + void sse_encode_box_autoadd_receive_amount(ReceiveAmount self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + sse_encode_receive_amount(self, serializer); + } + @protected void sse_encode_box_autoadd_receive_payment_request(ReceivePaymentRequest self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -6763,6 +6835,16 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { } } + @protected + void sse_encode_opt_box_autoadd_receive_amount(ReceiveAmount? self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + + sse_encode_bool(self != null, serializer); + if (self != null) { + sse_encode_box_autoadd_receive_amount(self, serializer); + } + } + @protected void sse_encode_opt_box_autoadd_success_action(SuccessAction? self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -6848,11 +6930,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { void sse_encode_pay_amount(PayAmount self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs switch (self) { - case PayAmount_Receiver(amountSat: final amountSat): + case PayAmount_Bitcoin(receiverAmountSat: final receiverAmountSat): sse_encode_i_32(0, serializer); - sse_encode_u_64(amountSat, serializer); - case PayAmount_Drain(): + sse_encode_u_64(receiverAmountSat, serializer); + case PayAmount_Asset(assetId: final assetId, receiverAmount: final receiverAmount): sse_encode_i_32(1, serializer); + sse_encode_String(assetId, serializer); + sse_encode_u_64(receiverAmount, serializer); + case PayAmount_Drain(): + sse_encode_i_32(2, serializer); } } @@ -7057,16 +7143,14 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { void sse_encode_prepare_receive_request(PrepareReceiveRequest self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs sse_encode_payment_method(self.paymentMethod, serializer); - sse_encode_opt_box_autoadd_u_64(self.payerAmountSat, serializer); - sse_encode_opt_String(self.assetId, serializer); + sse_encode_opt_box_autoadd_receive_amount(self.amount, serializer); } @protected void sse_encode_prepare_receive_response(PrepareReceiveResponse self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs sse_encode_payment_method(self.paymentMethod, serializer); - sse_encode_opt_box_autoadd_u_64(self.payerAmountSat, serializer); - sse_encode_opt_String(self.assetId, serializer); + sse_encode_opt_box_autoadd_receive_amount(self.amount, serializer); sse_encode_u_64(self.feesSat, serializer); sse_encode_opt_box_autoadd_u_64(self.minPayerAmountSat, serializer); sse_encode_opt_box_autoadd_u_64(self.maxPayerAmountSat, serializer); @@ -7094,7 +7178,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { // Codec=Sse (Serialization based), see doc to use other codecs sse_encode_String(self.destination, serializer); sse_encode_opt_box_autoadd_pay_amount(self.amount, serializer); - sse_encode_opt_String(self.assetId, serializer); } @protected @@ -7111,6 +7194,20 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_f_64(self.value, serializer); } + @protected + void sse_encode_receive_amount(ReceiveAmount self, SseSerializer serializer) { + // Codec=Sse (Serialization based), see doc to use other codecs + switch (self) { + case ReceiveAmount_Bitcoin(payerAmountSat: final payerAmountSat): + sse_encode_i_32(0, serializer); + sse_encode_u_64(payerAmountSat, serializer); + case ReceiveAmount_Asset(assetId: final assetId, payerAmount: final payerAmount): + sse_encode_i_32(1, serializer); + sse_encode_String(assetId, serializer); + sse_encode_opt_box_autoadd_u_64(payerAmount, serializer); + } + } + @protected void sse_encode_receive_payment_request(ReceivePaymentRequest self, SseSerializer serializer) { // Codec=Sse (Serialization based), see doc to use other codecs diff --git a/packages/dart/lib/src/frb_generated.io.dart b/packages/dart/lib/src/frb_generated.io.dart index 4cef7c793..f363461c2 100644 --- a/packages/dart/lib/src/frb_generated.io.dart +++ b/packages/dart/lib/src/frb_generated.io.dart @@ -203,6 +203,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected PrepareSendRequest dco_decode_box_autoadd_prepare_send_request(dynamic raw); + @protected + ReceiveAmount dco_decode_box_autoadd_receive_amount(dynamic raw); + @protected ReceivePaymentRequest dco_decode_box_autoadd_receive_payment_request(dynamic raw); @@ -455,6 +458,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected Payment? dco_decode_opt_box_autoadd_payment(dynamic raw); + @protected + ReceiveAmount? dco_decode_opt_box_autoadd_receive_amount(dynamic raw); + @protected SuccessAction? dco_decode_opt_box_autoadd_success_action(dynamic raw); @@ -542,6 +548,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected Rate dco_decode_rate(dynamic raw); + @protected + ReceiveAmount dco_decode_receive_amount(dynamic raw); + @protected ReceivePaymentRequest dco_decode_receive_payment_request(dynamic raw); @@ -804,6 +813,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected PrepareSendRequest sse_decode_box_autoadd_prepare_send_request(SseDeserializer deserializer); + @protected + ReceiveAmount sse_decode_box_autoadd_receive_amount(SseDeserializer deserializer); + @protected ReceivePaymentRequest sse_decode_box_autoadd_receive_payment_request(SseDeserializer deserializer); @@ -1058,6 +1070,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected Payment? sse_decode_opt_box_autoadd_payment(SseDeserializer deserializer); + @protected + ReceiveAmount? sse_decode_opt_box_autoadd_receive_amount(SseDeserializer deserializer); + @protected SuccessAction? sse_decode_opt_box_autoadd_success_action(SseDeserializer deserializer); @@ -1145,6 +1160,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected Rate sse_decode_rate(SseDeserializer deserializer); + @protected + ReceiveAmount sse_decode_receive_amount(SseDeserializer deserializer); + @protected ReceivePaymentRequest sse_decode_receive_payment_request(SseDeserializer deserializer); @@ -1607,6 +1625,14 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { return ptr; } + @protected + ffi.Pointer cst_encode_box_autoadd_receive_amount(ReceiveAmount raw) { + // Codec=Cst (C-struct based), see doc to use other codecs + final ptr = wire.cst_new_box_autoadd_receive_amount(); + cst_api_fill_to_wire_receive_amount(raw, ptr.ref); + return ptr; + } + @protected ffi.Pointer cst_encode_box_autoadd_receive_payment_request( ReceivePaymentRequest raw) { @@ -1915,6 +1941,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { return raw == null ? ffi.nullptr : cst_encode_box_autoadd_payment(raw); } + @protected + ffi.Pointer cst_encode_opt_box_autoadd_receive_amount(ReceiveAmount? raw) { + // Codec=Cst (C-struct based), see doc to use other codecs + return raw == null ? ffi.nullptr : cst_encode_box_autoadd_receive_amount(raw); + } + @protected ffi.Pointer cst_encode_opt_box_autoadd_success_action(SuccessAction? raw) { // Codec=Cst (C-struct based), see doc to use other codecs @@ -2287,6 +2319,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { cst_api_fill_to_wire_prepare_send_request(apiObj, wireObj.ref); } + @protected + void cst_api_fill_to_wire_box_autoadd_receive_amount( + ReceiveAmount apiObj, ffi.Pointer wireObj) { + cst_api_fill_to_wire_receive_amount(apiObj, wireObj.ref); + } + @protected void cst_api_fill_to_wire_box_autoadd_receive_payment_request( ReceivePaymentRequest apiObj, ffi.Pointer wireObj) { @@ -2921,14 +2959,22 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void cst_api_fill_to_wire_pay_amount(PayAmount apiObj, wire_cst_pay_amount wireObj) { - if (apiObj is PayAmount_Receiver) { - var pre_amount_sat = cst_encode_u_64(apiObj.amountSat); + if (apiObj is PayAmount_Bitcoin) { + var pre_receiver_amount_sat = cst_encode_u_64(apiObj.receiverAmountSat); wireObj.tag = 0; - wireObj.kind.Receiver.amount_sat = pre_amount_sat; + wireObj.kind.Bitcoin.receiver_amount_sat = pre_receiver_amount_sat; return; } - if (apiObj is PayAmount_Drain) { + if (apiObj is PayAmount_Asset) { + var pre_asset_id = cst_encode_String(apiObj.assetId); + var pre_receiver_amount = cst_encode_u_64(apiObj.receiverAmount); wireObj.tag = 1; + wireObj.kind.Asset.asset_id = pre_asset_id; + wireObj.kind.Asset.receiver_amount = pre_receiver_amount; + return; + } + if (apiObj is PayAmount_Drain) { + wireObj.tag = 2; return; } } @@ -3165,16 +3211,14 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { void cst_api_fill_to_wire_prepare_receive_request( PrepareReceiveRequest apiObj, wire_cst_prepare_receive_request wireObj) { wireObj.payment_method = cst_encode_payment_method(apiObj.paymentMethod); - wireObj.payer_amount_sat = cst_encode_opt_box_autoadd_u_64(apiObj.payerAmountSat); - wireObj.asset_id = cst_encode_opt_String(apiObj.assetId); + wireObj.amount = cst_encode_opt_box_autoadd_receive_amount(apiObj.amount); } @protected void cst_api_fill_to_wire_prepare_receive_response( PrepareReceiveResponse apiObj, wire_cst_prepare_receive_response wireObj) { wireObj.payment_method = cst_encode_payment_method(apiObj.paymentMethod); - wireObj.payer_amount_sat = cst_encode_opt_box_autoadd_u_64(apiObj.payerAmountSat); - wireObj.asset_id = cst_encode_opt_String(apiObj.assetId); + wireObj.amount = cst_encode_opt_box_autoadd_receive_amount(apiObj.amount); wireObj.fees_sat = cst_encode_u_64(apiObj.feesSat); wireObj.min_payer_amount_sat = cst_encode_opt_box_autoadd_u_64(apiObj.minPayerAmountSat); wireObj.max_payer_amount_sat = cst_encode_opt_box_autoadd_u_64(apiObj.maxPayerAmountSat); @@ -3202,7 +3246,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { PrepareSendRequest apiObj, wire_cst_prepare_send_request wireObj) { wireObj.destination = cst_encode_String(apiObj.destination); wireObj.amount = cst_encode_opt_box_autoadd_pay_amount(apiObj.amount); - wireObj.asset_id = cst_encode_opt_String(apiObj.assetId); } @protected @@ -3218,6 +3261,24 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { wireObj.value = cst_encode_f_64(apiObj.value); } + @protected + void cst_api_fill_to_wire_receive_amount(ReceiveAmount apiObj, wire_cst_receive_amount wireObj) { + if (apiObj is ReceiveAmount_Bitcoin) { + var pre_payer_amount_sat = cst_encode_u_64(apiObj.payerAmountSat); + wireObj.tag = 0; + wireObj.kind.Bitcoin.payer_amount_sat = pre_payer_amount_sat; + return; + } + if (apiObj is ReceiveAmount_Asset) { + var pre_asset_id = cst_encode_String(apiObj.assetId); + var pre_payer_amount = cst_encode_opt_box_autoadd_u_64(apiObj.payerAmount); + wireObj.tag = 1; + wireObj.kind.Asset.asset_id = pre_asset_id; + wireObj.kind.Asset.payer_amount = pre_payer_amount; + return; + } + } + @protected void cst_api_fill_to_wire_receive_payment_request( ReceivePaymentRequest apiObj, wire_cst_receive_payment_request wireObj) { @@ -3704,6 +3765,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_encode_box_autoadd_prepare_send_request(PrepareSendRequest self, SseSerializer serializer); + @protected + void sse_encode_box_autoadd_receive_amount(ReceiveAmount self, SseSerializer serializer); + @protected void sse_encode_box_autoadd_receive_payment_request(ReceivePaymentRequest self, SseSerializer serializer); @@ -3960,6 +4024,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_encode_opt_box_autoadd_payment(Payment? self, SseSerializer serializer); + @protected + void sse_encode_opt_box_autoadd_receive_amount(ReceiveAmount? self, SseSerializer serializer); + @protected void sse_encode_opt_box_autoadd_success_action(SuccessAction? self, SseSerializer serializer); @@ -4048,6 +4115,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_encode_rate(Rate self, SseSerializer serializer); + @protected + void sse_encode_receive_amount(ReceiveAmount self, SseSerializer serializer); + @protected void sse_encode_receive_payment_request(ReceivePaymentRequest self, SseSerializer serializer); @@ -5400,6 +5470,16 @@ class RustLibWire implements BaseWire { late final _cst_new_box_autoadd_prepare_send_request = _cst_new_box_autoadd_prepare_send_requestPtr .asFunction Function()>(); + ffi.Pointer cst_new_box_autoadd_receive_amount() { + return _cst_new_box_autoadd_receive_amount(); + } + + late final _cst_new_box_autoadd_receive_amountPtr = + _lookup Function()>>( + 'frbgen_breez_liquid_cst_new_box_autoadd_receive_amount'); + late final _cst_new_box_autoadd_receive_amount = + _cst_new_box_autoadd_receive_amountPtr.asFunction Function()>(); + ffi.Pointer cst_new_box_autoadd_receive_payment_request() { return _cst_new_box_autoadd_receive_payment_request(); } @@ -6211,13 +6291,22 @@ final class wire_cst_prepare_ln_url_pay_request extends ffi.Struct { external ffi.Pointer validate_success_action_url; } -final class wire_cst_PayAmount_Receiver extends ffi.Struct { +final class wire_cst_PayAmount_Bitcoin extends ffi.Struct { @ffi.Uint64() - external int amount_sat; + external int receiver_amount_sat; +} + +final class wire_cst_PayAmount_Asset extends ffi.Struct { + external ffi.Pointer asset_id; + + @ffi.Uint64() + external int receiver_amount; } final class PayAmountKind extends ffi.Union { - external wire_cst_PayAmount_Receiver Receiver; + external wire_cst_PayAmount_Bitcoin Bitcoin; + + external wire_cst_PayAmount_Asset Asset; } final class wire_cst_pay_amount extends ffi.Struct { @@ -6233,13 +6322,35 @@ final class wire_cst_prepare_pay_onchain_request extends ffi.Struct { external ffi.Pointer fee_rate_sat_per_vbyte; } +final class wire_cst_ReceiveAmount_Bitcoin extends ffi.Struct { + @ffi.Uint64() + external int payer_amount_sat; +} + +final class wire_cst_ReceiveAmount_Asset extends ffi.Struct { + external ffi.Pointer asset_id; + + external ffi.Pointer payer_amount; +} + +final class ReceiveAmountKind extends ffi.Union { + external wire_cst_ReceiveAmount_Bitcoin Bitcoin; + + external wire_cst_ReceiveAmount_Asset Asset; +} + +final class wire_cst_receive_amount extends ffi.Struct { + @ffi.Int32() + external int tag; + + external ReceiveAmountKind kind; +} + final class wire_cst_prepare_receive_request extends ffi.Struct { @ffi.Int32() external int payment_method; - external ffi.Pointer payer_amount_sat; - - external ffi.Pointer asset_id; + external ffi.Pointer amount; } final class wire_cst_prepare_refund_request extends ffi.Struct { @@ -6255,17 +6366,13 @@ final class wire_cst_prepare_send_request extends ffi.Struct { external ffi.Pointer destination; external ffi.Pointer amount; - - external ffi.Pointer asset_id; } final class wire_cst_prepare_receive_response extends ffi.Struct { @ffi.Int32() external int payment_method; - external ffi.Pointer payer_amount_sat; - - external ffi.Pointer asset_id; + external ffi.Pointer amount; @ffi.Uint64() external int fees_sat; diff --git a/packages/dart/lib/src/model.dart b/packages/dart/lib/src/model.dart index dec78414d..b21facd87 100644 --- a/packages/dart/lib/src/model.dart +++ b/packages/dart/lib/src/model.dart @@ -665,11 +665,17 @@ sealed class PayAmount with _$PayAmount { const PayAmount._(); /// The amount in satoshi that will be received - const factory PayAmount.receiver({ - required BigInt amountSat, - }) = PayAmount_Receiver; + const factory PayAmount.bitcoin({ + required BigInt receiverAmountSat, + }) = PayAmount_Bitcoin; + + /// The amount of an asset that will be received + const factory PayAmount.asset({ + required String assetId, + required BigInt receiverAmount, + }) = PayAmount_Asset; - /// Indicates that all available funds should be sent + /// Indicates that all available Bitcoin funds should be sent const factory PayAmount.drain() = PayAmount_Drain; } @@ -1130,23 +1136,16 @@ class PreparePayOnchainResponse { class PrepareReceiveRequest { final PaymentMethod paymentMethod; - /// The payer amount in satoshi units. If receiving a non Liquid Bitcoin asset, this is the units - /// of the asset to receive. - final BigInt? payerAmountSat; - - /// The id of the asset to receive when the 'payment_method' is Liquid. - /// - /// Defaults to Liquid Bitcoin. - final String? assetId; + /// The amount to be paid in either Bitcoin or another asset + final ReceiveAmount? amount; const PrepareReceiveRequest({ required this.paymentMethod, - this.payerAmountSat, - this.assetId, + this.amount, }); @override - int get hashCode => paymentMethod.hashCode ^ payerAmountSat.hashCode ^ assetId.hashCode; + int get hashCode => paymentMethod.hashCode ^ amount.hashCode; @override bool operator ==(Object other) => @@ -1154,15 +1153,13 @@ class PrepareReceiveRequest { other is PrepareReceiveRequest && runtimeType == other.runtimeType && paymentMethod == other.paymentMethod && - payerAmountSat == other.payerAmountSat && - assetId == other.assetId; + amount == other.amount; } /// Returned when calling [crate::sdk::LiquidSdk::prepare_receive_payment]. class PrepareReceiveResponse { final PaymentMethod paymentMethod; - final BigInt? payerAmountSat; - final String? assetId; + final ReceiveAmount? amount; /// Generally represents the total fees that would be paid to send or receive this payment. /// @@ -1191,8 +1188,7 @@ class PrepareReceiveResponse { const PrepareReceiveResponse({ required this.paymentMethod, - this.payerAmountSat, - this.assetId, + this.amount, required this.feesSat, this.minPayerAmountSat, this.maxPayerAmountSat, @@ -1202,8 +1198,7 @@ class PrepareReceiveResponse { @override int get hashCode => paymentMethod.hashCode ^ - payerAmountSat.hashCode ^ - assetId.hashCode ^ + amount.hashCode ^ feesSat.hashCode ^ minPayerAmountSat.hashCode ^ maxPayerAmountSat.hashCode ^ @@ -1215,8 +1210,7 @@ class PrepareReceiveResponse { other is PrepareReceiveResponse && runtimeType == other.runtimeType && paymentMethod == other.paymentMethod && - payerAmountSat == other.payerAmountSat && - assetId == other.assetId && + amount == other.amount && feesSat == other.feesSat && minPayerAmountSat == other.minPayerAmountSat && maxPayerAmountSat == other.maxPayerAmountSat && @@ -1288,18 +1282,13 @@ class PrepareSendRequest { /// where no amount is specified, or when the caller wishes to drain final PayAmount? amount; - /// Should only be set when paying directly onchain or to a BIP21 URI - /// where no asset id is specified - final String? assetId; - const PrepareSendRequest({ required this.destination, this.amount, - this.assetId, }); @override - int get hashCode => destination.hashCode ^ amount.hashCode ^ assetId.hashCode; + int get hashCode => destination.hashCode ^ amount.hashCode; @override bool operator ==(Object other) => @@ -1307,8 +1296,7 @@ class PrepareSendRequest { other is PrepareSendRequest && runtimeType == other.runtimeType && destination == other.destination && - amount == other.amount && - assetId == other.assetId; + amount == other.amount; } /// Returned when calling [crate::sdk::LiquidSdk::prepare_send_payment]. @@ -1333,6 +1321,22 @@ class PrepareSendResponse { feesSat == other.feesSat; } +@freezed +sealed class ReceiveAmount with _$ReceiveAmount { + const ReceiveAmount._(); + + /// The amount in satoshi that should be paid + const factory ReceiveAmount.bitcoin({ + required BigInt payerAmountSat, + }) = ReceiveAmount_Bitcoin; + + /// The amount of an asset that should be paid + const factory ReceiveAmount.asset({ + required String assetId, + BigInt? payerAmount, + }) = ReceiveAmount_Asset; +} + /// An argument when calling [crate::sdk::LiquidSdk::receive_payment]. class ReceivePaymentRequest { final PrepareReceiveResponse prepareResponse; diff --git a/packages/dart/lib/src/model.freezed.dart b/packages/dart/lib/src/model.freezed.dart index ebf24d5ec..a6a28b0d7 100644 --- a/packages/dart/lib/src/model.freezed.dart +++ b/packages/dart/lib/src/model.freezed.dart @@ -625,20 +625,20 @@ class _$PayAmountCopyWithImpl<$Res, $Val extends PayAmount> implements $PayAmoun } /// @nodoc -abstract class _$$PayAmount_ReceiverImplCopyWith<$Res> { - factory _$$PayAmount_ReceiverImplCopyWith( - _$PayAmount_ReceiverImpl value, $Res Function(_$PayAmount_ReceiverImpl) then) = - __$$PayAmount_ReceiverImplCopyWithImpl<$Res>; +abstract class _$$PayAmount_BitcoinImplCopyWith<$Res> { + factory _$$PayAmount_BitcoinImplCopyWith( + _$PayAmount_BitcoinImpl value, $Res Function(_$PayAmount_BitcoinImpl) then) = + __$$PayAmount_BitcoinImplCopyWithImpl<$Res>; @useResult - $Res call({BigInt amountSat}); + $Res call({BigInt receiverAmountSat}); } /// @nodoc -class __$$PayAmount_ReceiverImplCopyWithImpl<$Res> - extends _$PayAmountCopyWithImpl<$Res, _$PayAmount_ReceiverImpl> - implements _$$PayAmount_ReceiverImplCopyWith<$Res> { - __$$PayAmount_ReceiverImplCopyWithImpl( - _$PayAmount_ReceiverImpl _value, $Res Function(_$PayAmount_ReceiverImpl) _then) +class __$$PayAmount_BitcoinImplCopyWithImpl<$Res> + extends _$PayAmountCopyWithImpl<$Res, _$PayAmount_BitcoinImpl> + implements _$$PayAmount_BitcoinImplCopyWith<$Res> { + __$$PayAmount_BitcoinImplCopyWithImpl( + _$PayAmount_BitcoinImpl _value, $Res Function(_$PayAmount_BitcoinImpl) _then) : super(_value, _then); /// Create a copy of PayAmount @@ -646,12 +646,12 @@ class __$$PayAmount_ReceiverImplCopyWithImpl<$Res> @pragma('vm:prefer-inline') @override $Res call({ - Object? amountSat = null, + Object? receiverAmountSat = null, }) { - return _then(_$PayAmount_ReceiverImpl( - amountSat: null == amountSat - ? _value.amountSat - : amountSat // ignore: cast_nullable_to_non_nullable + return _then(_$PayAmount_BitcoinImpl( + receiverAmountSat: null == receiverAmountSat + ? _value.receiverAmountSat + : receiverAmountSat // ignore: cast_nullable_to_non_nullable as BigInt, )); } @@ -659,50 +659,138 @@ class __$$PayAmount_ReceiverImplCopyWithImpl<$Res> /// @nodoc -class _$PayAmount_ReceiverImpl extends PayAmount_Receiver { - const _$PayAmount_ReceiverImpl({required this.amountSat}) : super._(); +class _$PayAmount_BitcoinImpl extends PayAmount_Bitcoin { + const _$PayAmount_BitcoinImpl({required this.receiverAmountSat}) : super._(); @override - final BigInt amountSat; + final BigInt receiverAmountSat; @override String toString() { - return 'PayAmount.receiver(amountSat: $amountSat)'; + return 'PayAmount.bitcoin(receiverAmountSat: $receiverAmountSat)'; } @override bool operator ==(Object other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$PayAmount_ReceiverImpl && - (identical(other.amountSat, amountSat) || other.amountSat == amountSat)); + other is _$PayAmount_BitcoinImpl && + (identical(other.receiverAmountSat, receiverAmountSat) || + other.receiverAmountSat == receiverAmountSat)); } @override - int get hashCode => Object.hash(runtimeType, amountSat); + int get hashCode => Object.hash(runtimeType, receiverAmountSat); /// Create a copy of PayAmount /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) @override @pragma('vm:prefer-inline') - _$$PayAmount_ReceiverImplCopyWith<_$PayAmount_ReceiverImpl> get copyWith => - __$$PayAmount_ReceiverImplCopyWithImpl<_$PayAmount_ReceiverImpl>(this, _$identity); + _$$PayAmount_BitcoinImplCopyWith<_$PayAmount_BitcoinImpl> get copyWith => + __$$PayAmount_BitcoinImplCopyWithImpl<_$PayAmount_BitcoinImpl>(this, _$identity); } -abstract class PayAmount_Receiver extends PayAmount { - const factory PayAmount_Receiver({required final BigInt amountSat}) = _$PayAmount_ReceiverImpl; - const PayAmount_Receiver._() : super._(); +abstract class PayAmount_Bitcoin extends PayAmount { + const factory PayAmount_Bitcoin({required final BigInt receiverAmountSat}) = _$PayAmount_BitcoinImpl; + const PayAmount_Bitcoin._() : super._(); - BigInt get amountSat; + BigInt get receiverAmountSat; /// Create a copy of PayAmount /// with the given fields replaced by the non-null parameter values. @JsonKey(includeFromJson: false, includeToJson: false) - _$$PayAmount_ReceiverImplCopyWith<_$PayAmount_ReceiverImpl> get copyWith => + _$$PayAmount_BitcoinImplCopyWith<_$PayAmount_BitcoinImpl> get copyWith => throw _privateConstructorUsedError; } +/// @nodoc +abstract class _$$PayAmount_AssetImplCopyWith<$Res> { + factory _$$PayAmount_AssetImplCopyWith( + _$PayAmount_AssetImpl value, $Res Function(_$PayAmount_AssetImpl) then) = + __$$PayAmount_AssetImplCopyWithImpl<$Res>; + @useResult + $Res call({String assetId, BigInt receiverAmount}); +} + +/// @nodoc +class __$$PayAmount_AssetImplCopyWithImpl<$Res> extends _$PayAmountCopyWithImpl<$Res, _$PayAmount_AssetImpl> + implements _$$PayAmount_AssetImplCopyWith<$Res> { + __$$PayAmount_AssetImplCopyWithImpl( + _$PayAmount_AssetImpl _value, $Res Function(_$PayAmount_AssetImpl) _then) + : super(_value, _then); + + /// Create a copy of PayAmount + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? assetId = null, + Object? receiverAmount = null, + }) { + return _then(_$PayAmount_AssetImpl( + assetId: null == assetId + ? _value.assetId + : assetId // ignore: cast_nullable_to_non_nullable + as String, + receiverAmount: null == receiverAmount + ? _value.receiverAmount + : receiverAmount // ignore: cast_nullable_to_non_nullable + as BigInt, + )); + } +} + +/// @nodoc + +class _$PayAmount_AssetImpl extends PayAmount_Asset { + const _$PayAmount_AssetImpl({required this.assetId, required this.receiverAmount}) : super._(); + + @override + final String assetId; + @override + final BigInt receiverAmount; + + @override + String toString() { + return 'PayAmount.asset(assetId: $assetId, receiverAmount: $receiverAmount)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$PayAmount_AssetImpl && + (identical(other.assetId, assetId) || other.assetId == assetId) && + (identical(other.receiverAmount, receiverAmount) || other.receiverAmount == receiverAmount)); + } + + @override + int get hashCode => Object.hash(runtimeType, assetId, receiverAmount); + + /// Create a copy of PayAmount + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$PayAmount_AssetImplCopyWith<_$PayAmount_AssetImpl> get copyWith => + __$$PayAmount_AssetImplCopyWithImpl<_$PayAmount_AssetImpl>(this, _$identity); +} + +abstract class PayAmount_Asset extends PayAmount { + const factory PayAmount_Asset({required final String assetId, required final BigInt receiverAmount}) = + _$PayAmount_AssetImpl; + const PayAmount_Asset._() : super._(); + + String get assetId; + BigInt get receiverAmount; + + /// Create a copy of PayAmount + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + _$$PayAmount_AssetImplCopyWith<_$PayAmount_AssetImpl> get copyWith => throw _privateConstructorUsedError; +} + /// @nodoc abstract class _$$PayAmount_DrainImplCopyWith<$Res> { factory _$$PayAmount_DrainImplCopyWith( @@ -1249,6 +1337,196 @@ abstract class PaymentDetails_Bitcoin extends PaymentDetails { throw _privateConstructorUsedError; } +/// @nodoc +mixin _$ReceiveAmount {} + +/// @nodoc +abstract class $ReceiveAmountCopyWith<$Res> { + factory $ReceiveAmountCopyWith(ReceiveAmount value, $Res Function(ReceiveAmount) then) = + _$ReceiveAmountCopyWithImpl<$Res, ReceiveAmount>; +} + +/// @nodoc +class _$ReceiveAmountCopyWithImpl<$Res, $Val extends ReceiveAmount> implements $ReceiveAmountCopyWith<$Res> { + _$ReceiveAmountCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ReceiveAmount + /// with the given fields replaced by the non-null parameter values. +} + +/// @nodoc +abstract class _$$ReceiveAmount_BitcoinImplCopyWith<$Res> { + factory _$$ReceiveAmount_BitcoinImplCopyWith( + _$ReceiveAmount_BitcoinImpl value, $Res Function(_$ReceiveAmount_BitcoinImpl) then) = + __$$ReceiveAmount_BitcoinImplCopyWithImpl<$Res>; + @useResult + $Res call({BigInt payerAmountSat}); +} + +/// @nodoc +class __$$ReceiveAmount_BitcoinImplCopyWithImpl<$Res> + extends _$ReceiveAmountCopyWithImpl<$Res, _$ReceiveAmount_BitcoinImpl> + implements _$$ReceiveAmount_BitcoinImplCopyWith<$Res> { + __$$ReceiveAmount_BitcoinImplCopyWithImpl( + _$ReceiveAmount_BitcoinImpl _value, $Res Function(_$ReceiveAmount_BitcoinImpl) _then) + : super(_value, _then); + + /// Create a copy of ReceiveAmount + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? payerAmountSat = null, + }) { + return _then(_$ReceiveAmount_BitcoinImpl( + payerAmountSat: null == payerAmountSat + ? _value.payerAmountSat + : payerAmountSat // ignore: cast_nullable_to_non_nullable + as BigInt, + )); + } +} + +/// @nodoc + +class _$ReceiveAmount_BitcoinImpl extends ReceiveAmount_Bitcoin { + const _$ReceiveAmount_BitcoinImpl({required this.payerAmountSat}) : super._(); + + @override + final BigInt payerAmountSat; + + @override + String toString() { + return 'ReceiveAmount.bitcoin(payerAmountSat: $payerAmountSat)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ReceiveAmount_BitcoinImpl && + (identical(other.payerAmountSat, payerAmountSat) || other.payerAmountSat == payerAmountSat)); + } + + @override + int get hashCode => Object.hash(runtimeType, payerAmountSat); + + /// Create a copy of ReceiveAmount + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ReceiveAmount_BitcoinImplCopyWith<_$ReceiveAmount_BitcoinImpl> get copyWith => + __$$ReceiveAmount_BitcoinImplCopyWithImpl<_$ReceiveAmount_BitcoinImpl>(this, _$identity); +} + +abstract class ReceiveAmount_Bitcoin extends ReceiveAmount { + const factory ReceiveAmount_Bitcoin({required final BigInt payerAmountSat}) = _$ReceiveAmount_BitcoinImpl; + const ReceiveAmount_Bitcoin._() : super._(); + + BigInt get payerAmountSat; + + /// Create a copy of ReceiveAmount + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ReceiveAmount_BitcoinImplCopyWith<_$ReceiveAmount_BitcoinImpl> get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class _$$ReceiveAmount_AssetImplCopyWith<$Res> { + factory _$$ReceiveAmount_AssetImplCopyWith( + _$ReceiveAmount_AssetImpl value, $Res Function(_$ReceiveAmount_AssetImpl) then) = + __$$ReceiveAmount_AssetImplCopyWithImpl<$Res>; + @useResult + $Res call({String assetId, BigInt? payerAmount}); +} + +/// @nodoc +class __$$ReceiveAmount_AssetImplCopyWithImpl<$Res> + extends _$ReceiveAmountCopyWithImpl<$Res, _$ReceiveAmount_AssetImpl> + implements _$$ReceiveAmount_AssetImplCopyWith<$Res> { + __$$ReceiveAmount_AssetImplCopyWithImpl( + _$ReceiveAmount_AssetImpl _value, $Res Function(_$ReceiveAmount_AssetImpl) _then) + : super(_value, _then); + + /// Create a copy of ReceiveAmount + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? assetId = null, + Object? payerAmount = freezed, + }) { + return _then(_$ReceiveAmount_AssetImpl( + assetId: null == assetId + ? _value.assetId + : assetId // ignore: cast_nullable_to_non_nullable + as String, + payerAmount: freezed == payerAmount + ? _value.payerAmount + : payerAmount // ignore: cast_nullable_to_non_nullable + as BigInt?, + )); + } +} + +/// @nodoc + +class _$ReceiveAmount_AssetImpl extends ReceiveAmount_Asset { + const _$ReceiveAmount_AssetImpl({required this.assetId, this.payerAmount}) : super._(); + + @override + final String assetId; + @override + final BigInt? payerAmount; + + @override + String toString() { + return 'ReceiveAmount.asset(assetId: $assetId, payerAmount: $payerAmount)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ReceiveAmount_AssetImpl && + (identical(other.assetId, assetId) || other.assetId == assetId) && + (identical(other.payerAmount, payerAmount) || other.payerAmount == payerAmount)); + } + + @override + int get hashCode => Object.hash(runtimeType, assetId, payerAmount); + + /// Create a copy of ReceiveAmount + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ReceiveAmount_AssetImplCopyWith<_$ReceiveAmount_AssetImpl> get copyWith => + __$$ReceiveAmount_AssetImplCopyWithImpl<_$ReceiveAmount_AssetImpl>(this, _$identity); +} + +abstract class ReceiveAmount_Asset extends ReceiveAmount { + const factory ReceiveAmount_Asset({required final String assetId, final BigInt? payerAmount}) = + _$ReceiveAmount_AssetImpl; + const ReceiveAmount_Asset._() : super._(); + + String get assetId; + BigInt? get payerAmount; + + /// Create a copy of ReceiveAmount + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ReceiveAmount_AssetImplCopyWith<_$ReceiveAmount_AssetImpl> get copyWith => + throw _privateConstructorUsedError; +} + /// @nodoc mixin _$SdkEvent {} diff --git a/packages/flutter/lib/flutter_breez_liquid_bindings_generated.dart b/packages/flutter/lib/flutter_breez_liquid_bindings_generated.dart index 93118565c..cea3aadfe 100644 --- a/packages/flutter/lib/flutter_breez_liquid_bindings_generated.dart +++ b/packages/flutter/lib/flutter_breez_liquid_bindings_generated.dart @@ -1338,6 +1338,17 @@ class FlutterBreezLiquidBindings { _frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_requestPtr .asFunction Function()>(); + ffi.Pointer frbgen_breez_liquid_cst_new_box_autoadd_receive_amount() { + return _frbgen_breez_liquid_cst_new_box_autoadd_receive_amount(); + } + + late final _frbgen_breez_liquid_cst_new_box_autoadd_receive_amountPtr = + _lookup Function()>>( + 'frbgen_breez_liquid_cst_new_box_autoadd_receive_amount'); + late final _frbgen_breez_liquid_cst_new_box_autoadd_receive_amount = + _frbgen_breez_liquid_cst_new_box_autoadd_receive_amountPtr + .asFunction Function()>(); + ffi.Pointer frbgen_breez_liquid_cst_new_box_autoadd_receive_payment_request() { return _frbgen_breez_liquid_cst_new_box_autoadd_receive_payment_request(); @@ -4540,13 +4551,22 @@ final class wire_cst_prepare_ln_url_pay_request extends ffi.Struct { external ffi.Pointer validate_success_action_url; } -final class wire_cst_PayAmount_Receiver extends ffi.Struct { +final class wire_cst_PayAmount_Bitcoin extends ffi.Struct { @ffi.Uint64() - external int amount_sat; + external int receiver_amount_sat; +} + +final class wire_cst_PayAmount_Asset extends ffi.Struct { + external ffi.Pointer asset_id; + + @ffi.Uint64() + external int receiver_amount; } final class PayAmountKind extends ffi.Union { - external wire_cst_PayAmount_Receiver Receiver; + external wire_cst_PayAmount_Bitcoin Bitcoin; + + external wire_cst_PayAmount_Asset Asset; } final class wire_cst_pay_amount extends ffi.Struct { @@ -4562,13 +4582,35 @@ final class wire_cst_prepare_pay_onchain_request extends ffi.Struct { external ffi.Pointer fee_rate_sat_per_vbyte; } +final class wire_cst_ReceiveAmount_Bitcoin extends ffi.Struct { + @ffi.Uint64() + external int payer_amount_sat; +} + +final class wire_cst_ReceiveAmount_Asset extends ffi.Struct { + external ffi.Pointer asset_id; + + external ffi.Pointer payer_amount; +} + +final class ReceiveAmountKind extends ffi.Union { + external wire_cst_ReceiveAmount_Bitcoin Bitcoin; + + external wire_cst_ReceiveAmount_Asset Asset; +} + +final class wire_cst_receive_amount extends ffi.Struct { + @ffi.Int32() + external int tag; + + external ReceiveAmountKind kind; +} + final class wire_cst_prepare_receive_request extends ffi.Struct { @ffi.Int32() external int payment_method; - external ffi.Pointer payer_amount_sat; - - external ffi.Pointer asset_id; + external ffi.Pointer amount; } final class wire_cst_prepare_refund_request extends ffi.Struct { @@ -4584,17 +4626,13 @@ final class wire_cst_prepare_send_request extends ffi.Struct { external ffi.Pointer destination; external ffi.Pointer amount; - - external ffi.Pointer asset_id; } final class wire_cst_prepare_receive_response extends ffi.Struct { @ffi.Int32() external int payment_method; - external ffi.Pointer payer_amount_sat; - - external ffi.Pointer asset_id; + external ffi.Pointer amount; @ffi.Uint64() external int fees_sat; 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 9547f6c76..05ba2ab65 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 @@ -1938,25 +1938,21 @@ fun asPrepareReceiveRequest(prepareReceiveRequest: ReadableMap): PrepareReceiveR return null } val paymentMethod = prepareReceiveRequest.getString("paymentMethod")?.let { asPaymentMethod(it) }!! - val payerAmountSat = - if (hasNonNullKey( - prepareReceiveRequest, - "payerAmountSat", - ) - ) { - prepareReceiveRequest.getDouble("payerAmountSat").toULong() + val amount = + if (hasNonNullKey(prepareReceiveRequest, "amount")) { + prepareReceiveRequest.getMap("amount")?.let { + asReceiveAmount(it) + } } else { null } - val assetId = if (hasNonNullKey(prepareReceiveRequest, "assetId")) prepareReceiveRequest.getString("assetId") else null - return PrepareReceiveRequest(paymentMethod, payerAmountSat, assetId) + return PrepareReceiveRequest(paymentMethod, amount) } fun readableMapOf(prepareReceiveRequest: PrepareReceiveRequest): ReadableMap = readableMapOf( "paymentMethod" to prepareReceiveRequest.paymentMethod.name.lowercase(), - "payerAmountSat" to prepareReceiveRequest.payerAmountSat, - "assetId" to prepareReceiveRequest.assetId, + "amount" to prepareReceiveRequest.amount?.let { readableMapOf(it) }, ) fun asPrepareReceiveRequestList(arr: ReadableArray): List { @@ -1983,17 +1979,14 @@ fun asPrepareReceiveResponse(prepareReceiveResponse: ReadableMap): PrepareReceiv } val paymentMethod = prepareReceiveResponse.getString("paymentMethod")?.let { asPaymentMethod(it) }!! val feesSat = prepareReceiveResponse.getDouble("feesSat").toULong() - val payerAmountSat = - if (hasNonNullKey( - prepareReceiveResponse, - "payerAmountSat", - ) - ) { - prepareReceiveResponse.getDouble("payerAmountSat").toULong() + val amount = + if (hasNonNullKey(prepareReceiveResponse, "amount")) { + prepareReceiveResponse.getMap("amount")?.let { + asReceiveAmount(it) + } } else { null } - val assetId = if (hasNonNullKey(prepareReceiveResponse, "assetId")) prepareReceiveResponse.getString("assetId") else null val minPayerAmountSat = if (hasNonNullKey( prepareReceiveResponse, @@ -2024,15 +2017,14 @@ fun asPrepareReceiveResponse(prepareReceiveResponse: ReadableMap): PrepareReceiv } else { null } - return PrepareReceiveResponse(paymentMethod, feesSat, payerAmountSat, assetId, minPayerAmountSat, maxPayerAmountSat, swapperFeerate) + return PrepareReceiveResponse(paymentMethod, feesSat, amount, minPayerAmountSat, maxPayerAmountSat, swapperFeerate) } fun readableMapOf(prepareReceiveResponse: PrepareReceiveResponse): ReadableMap = readableMapOf( "paymentMethod" to prepareReceiveResponse.paymentMethod.name.lowercase(), "feesSat" to prepareReceiveResponse.feesSat, - "payerAmountSat" to prepareReceiveResponse.payerAmountSat, - "assetId" to prepareReceiveResponse.assetId, + "amount" to prepareReceiveResponse.amount?.let { readableMapOf(it) }, "minPayerAmountSat" to prepareReceiveResponse.minPayerAmountSat, "maxPayerAmountSat" to prepareReceiveResponse.maxPayerAmountSat, "swapperFeerate" to prepareReceiveResponse.swapperFeerate, @@ -2132,15 +2124,13 @@ fun asPrepareSendRequest(prepareSendRequest: ReadableMap): PrepareSendRequest? { } val destination = prepareSendRequest.getString("destination")!! val amount = if (hasNonNullKey(prepareSendRequest, "amount")) prepareSendRequest.getMap("amount")?.let { asPayAmount(it) } else null - val assetId = if (hasNonNullKey(prepareSendRequest, "assetId")) prepareSendRequest.getString("assetId") else null - return PrepareSendRequest(destination, amount, assetId) + return PrepareSendRequest(destination, amount) } fun readableMapOf(prepareSendRequest: PrepareSendRequest): ReadableMap = readableMapOf( "destination" to prepareSendRequest.destination, "amount" to prepareSendRequest.amount?.let { readableMapOf(it) }, - "assetId" to prepareSendRequest.assetId, ) fun asPrepareSendRequestList(arr: ReadableArray): List { @@ -3175,9 +3165,14 @@ fun asNetworkList(arr: ReadableArray): List { fun asPayAmount(payAmount: ReadableMap): PayAmount? { val type = payAmount.getString("type") - if (type == "receiver") { - val amountSat = payAmount.getDouble("amountSat").toULong() - return PayAmount.Receiver(amountSat) + if (type == "bitcoin") { + val receiverAmountSat = payAmount.getDouble("receiverAmountSat").toULong() + return PayAmount.Bitcoin(receiverAmountSat) + } + if (type == "asset") { + val assetId = payAmount.getString("assetId")!! + val receiverAmount = payAmount.getDouble("receiverAmount").toULong() + return PayAmount.Asset(assetId, receiverAmount) } if (type == "drain") { return PayAmount.Drain @@ -3188,9 +3183,14 @@ fun asPayAmount(payAmount: ReadableMap): PayAmount? { fun readableMapOf(payAmount: PayAmount): ReadableMap? { val map = Arguments.createMap() when (payAmount) { - is PayAmount.Receiver -> { - pushToMap(map, "type", "receiver") - pushToMap(map, "amountSat", payAmount.amountSat) + is PayAmount.Bitcoin -> { + pushToMap(map, "type", "bitcoin") + pushToMap(map, "receiverAmountSat", payAmount.receiverAmountSat) + } + is PayAmount.Asset -> { + pushToMap(map, "type", "asset") + pushToMap(map, "assetId", payAmount.assetId) + pushToMap(map, "receiverAmount", payAmount.receiverAmount) } is PayAmount.Drain -> { pushToMap(map, "type", "drain") @@ -3360,6 +3360,48 @@ fun asPaymentTypeList(arr: ReadableArray): List { return list } +fun asReceiveAmount(receiveAmount: ReadableMap): ReceiveAmount? { + val type = receiveAmount.getString("type") + + if (type == "bitcoin") { + val payerAmountSat = receiveAmount.getDouble("payerAmountSat").toULong() + return ReceiveAmount.Bitcoin(payerAmountSat) + } + if (type == "asset") { + val assetId = receiveAmount.getString("assetId")!! + val payerAmount = if (hasNonNullKey(receiveAmount, "payerAmount")) receiveAmount.getDouble("payerAmount").toULong() else null + return ReceiveAmount.Asset(assetId, payerAmount) + } + return null +} + +fun readableMapOf(receiveAmount: ReceiveAmount): ReadableMap? { + val map = Arguments.createMap() + when (receiveAmount) { + is ReceiveAmount.Bitcoin -> { + pushToMap(map, "type", "bitcoin") + pushToMap(map, "payerAmountSat", receiveAmount.payerAmountSat) + } + is ReceiveAmount.Asset -> { + pushToMap(map, "type", "asset") + pushToMap(map, "assetId", receiveAmount.assetId) + pushToMap(map, "payerAmount", receiveAmount.payerAmount) + } + } + return map +} + +fun asReceiveAmountList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toList()) { + when (value) { + is ReadableMap -> list.add(asReceiveAmount(value)!!) + else -> throw SdkException.Generic(errUnexpectedType(value)) + } + } + return list +} + fun asSdkEvent(sdkEvent: ReadableMap): SdkEvent? { val type = sdkEvent.getString("type") diff --git a/packages/react-native/ios/BreezSDKLiquidMapper.swift b/packages/react-native/ios/BreezSDKLiquidMapper.swift index d26da06da..51d43b646 100644 --- a/packages/react-native/ios/BreezSDKLiquidMapper.swift +++ b/packages/react-native/ios/BreezSDKLiquidMapper.swift @@ -2250,29 +2250,18 @@ enum BreezSDKLiquidMapper { } let paymentMethod = try asPaymentMethod(paymentMethod: paymentMethodTmp) - var payerAmountSat: UInt64? - if hasNonNilKey(data: prepareReceiveRequest, key: "payerAmountSat") { - guard let payerAmountSatTmp = prepareReceiveRequest["payerAmountSat"] as? UInt64 else { - throw SdkError.Generic(message: errUnexpectedValue(fieldName: "payerAmountSat")) - } - payerAmountSat = payerAmountSatTmp - } - var assetId: String? - if hasNonNilKey(data: prepareReceiveRequest, key: "assetId") { - guard let assetIdTmp = prepareReceiveRequest["assetId"] as? String else { - throw SdkError.Generic(message: errUnexpectedValue(fieldName: "assetId")) - } - assetId = assetIdTmp + var amount: ReceiveAmount? + if let amountTmp = prepareReceiveRequest["amount"] as? [String: Any?] { + amount = try asReceiveAmount(receiveAmount: amountTmp) } - return PrepareReceiveRequest(paymentMethod: paymentMethod, payerAmountSat: payerAmountSat, assetId: assetId) + return PrepareReceiveRequest(paymentMethod: paymentMethod, amount: amount) } static func dictionaryOf(prepareReceiveRequest: PrepareReceiveRequest) -> [String: Any?] { return [ "paymentMethod": valueOf(paymentMethod: prepareReceiveRequest.paymentMethod), - "payerAmountSat": prepareReceiveRequest.payerAmountSat == nil ? nil : prepareReceiveRequest.payerAmountSat, - "assetId": prepareReceiveRequest.assetId == nil ? nil : prepareReceiveRequest.assetId, + "amount": prepareReceiveRequest.amount == nil ? nil : dictionaryOf(receiveAmount: prepareReceiveRequest.amount!), ] } @@ -2302,20 +2291,11 @@ enum BreezSDKLiquidMapper { guard let feesSat = prepareReceiveResponse["feesSat"] as? UInt64 else { throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "feesSat", typeName: "PrepareReceiveResponse")) } - var payerAmountSat: UInt64? - if hasNonNilKey(data: prepareReceiveResponse, key: "payerAmountSat") { - guard let payerAmountSatTmp = prepareReceiveResponse["payerAmountSat"] as? UInt64 else { - throw SdkError.Generic(message: errUnexpectedValue(fieldName: "payerAmountSat")) - } - payerAmountSat = payerAmountSatTmp - } - var assetId: String? - if hasNonNilKey(data: prepareReceiveResponse, key: "assetId") { - guard let assetIdTmp = prepareReceiveResponse["assetId"] as? String else { - throw SdkError.Generic(message: errUnexpectedValue(fieldName: "assetId")) - } - assetId = assetIdTmp + var amount: ReceiveAmount? + if let amountTmp = prepareReceiveResponse["amount"] as? [String: Any?] { + amount = try asReceiveAmount(receiveAmount: amountTmp) } + var minPayerAmountSat: UInt64? if hasNonNilKey(data: prepareReceiveResponse, key: "minPayerAmountSat") { guard let minPayerAmountSatTmp = prepareReceiveResponse["minPayerAmountSat"] as? UInt64 else { @@ -2338,15 +2318,14 @@ enum BreezSDKLiquidMapper { swapperFeerate = swapperFeerateTmp } - return PrepareReceiveResponse(paymentMethod: paymentMethod, feesSat: feesSat, payerAmountSat: payerAmountSat, assetId: assetId, minPayerAmountSat: minPayerAmountSat, maxPayerAmountSat: maxPayerAmountSat, swapperFeerate: swapperFeerate) + return PrepareReceiveResponse(paymentMethod: paymentMethod, feesSat: feesSat, amount: amount, minPayerAmountSat: minPayerAmountSat, maxPayerAmountSat: maxPayerAmountSat, swapperFeerate: swapperFeerate) } static func dictionaryOf(prepareReceiveResponse: PrepareReceiveResponse) -> [String: Any?] { return [ "paymentMethod": valueOf(paymentMethod: prepareReceiveResponse.paymentMethod), "feesSat": prepareReceiveResponse.feesSat, - "payerAmountSat": prepareReceiveResponse.payerAmountSat == nil ? nil : prepareReceiveResponse.payerAmountSat, - "assetId": prepareReceiveResponse.assetId == nil ? nil : prepareReceiveResponse.assetId, + "amount": prepareReceiveResponse.amount == nil ? nil : dictionaryOf(receiveAmount: prepareReceiveResponse.amount!), "minPayerAmountSat": prepareReceiveResponse.minPayerAmountSat == nil ? nil : prepareReceiveResponse.minPayerAmountSat, "maxPayerAmountSat": prepareReceiveResponse.maxPayerAmountSat == nil ? nil : prepareReceiveResponse.maxPayerAmountSat, "swapperFeerate": prepareReceiveResponse.swapperFeerate == nil ? nil : prepareReceiveResponse.swapperFeerate, @@ -2461,22 +2440,13 @@ enum BreezSDKLiquidMapper { amount = try asPayAmount(payAmount: amountTmp) } - var assetId: String? - if hasNonNilKey(data: prepareSendRequest, key: "assetId") { - guard let assetIdTmp = prepareSendRequest["assetId"] as? String else { - throw SdkError.Generic(message: errUnexpectedValue(fieldName: "assetId")) - } - assetId = assetIdTmp - } - - return PrepareSendRequest(destination: destination, amount: amount, assetId: assetId) + return PrepareSendRequest(destination: destination, amount: amount) } static func dictionaryOf(prepareSendRequest: PrepareSendRequest) -> [String: Any?] { return [ "destination": prepareSendRequest.destination, "amount": prepareSendRequest.amount == nil ? nil : dictionaryOf(payAmount: prepareSendRequest.amount!), - "assetId": prepareSendRequest.assetId == nil ? nil : prepareSendRequest.assetId, ] } @@ -3882,11 +3852,20 @@ enum BreezSDKLiquidMapper { static func asPayAmount(payAmount: [String: Any?]) throws -> PayAmount { let type = payAmount["type"] as! String - if type == "receiver" { - guard let _amountSat = payAmount["amountSat"] as? UInt64 else { - throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "amountSat", typeName: "PayAmount")) + if type == "bitcoin" { + guard let _receiverAmountSat = payAmount["receiverAmountSat"] as? UInt64 else { + throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "receiverAmountSat", typeName: "PayAmount")) } - return PayAmount.receiver(amountSat: _amountSat) + return PayAmount.bitcoin(receiverAmountSat: _receiverAmountSat) + } + if type == "asset" { + guard let _assetId = payAmount["assetId"] as? String else { + throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "assetId", typeName: "PayAmount")) + } + guard let _receiverAmount = payAmount["receiverAmount"] as? UInt64 else { + throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "receiverAmount", typeName: "PayAmount")) + } + return PayAmount.asset(assetId: _assetId, receiverAmount: _receiverAmount) } if type == "drain" { return PayAmount.drain @@ -3897,12 +3876,21 @@ enum BreezSDKLiquidMapper { static func dictionaryOf(payAmount: PayAmount) -> [String: Any?] { switch payAmount { - case let .receiver( - amountSat + case let .bitcoin( + receiverAmountSat ): return [ - "type": "receiver", - "amountSat": amountSat, + "type": "bitcoin", + "receiverAmountSat": receiverAmountSat, + ] + + case let .asset( + assetId, receiverAmount + ): + return [ + "type": "asset", + "assetId": assetId, + "receiverAmount": receiverAmount, ] case .drain: @@ -4203,6 +4191,64 @@ enum BreezSDKLiquidMapper { return list } + static func asReceiveAmount(receiveAmount: [String: Any?]) throws -> ReceiveAmount { + let type = receiveAmount["type"] as! String + if type == "bitcoin" { + guard let _payerAmountSat = receiveAmount["payerAmountSat"] as? UInt64 else { + throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "payerAmountSat", typeName: "ReceiveAmount")) + } + return ReceiveAmount.bitcoin(payerAmountSat: _payerAmountSat) + } + if type == "asset" { + guard let _assetId = receiveAmount["assetId"] as? String else { + throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "assetId", typeName: "ReceiveAmount")) + } + let _payerAmount = receiveAmount["payerAmount"] as? UInt64 + + return ReceiveAmount.asset(assetId: _assetId, payerAmount: _payerAmount) + } + + throw SdkError.Generic(message: "Unexpected type \(type) for enum ReceiveAmount") + } + + static func dictionaryOf(receiveAmount: ReceiveAmount) -> [String: Any?] { + switch receiveAmount { + case let .bitcoin( + payerAmountSat + ): + return [ + "type": "bitcoin", + "payerAmountSat": payerAmountSat, + ] + + case let .asset( + assetId, payerAmount + ): + return [ + "type": "asset", + "assetId": assetId, + "payerAmount": payerAmount == nil ? nil : payerAmount, + ] + } + } + + static func arrayOf(receiveAmountList: [ReceiveAmount]) -> [Any] { + return receiveAmountList.map { v -> [String: Any?] in return dictionaryOf(receiveAmount: v) } + } + + static func asReceiveAmountList(arr: [Any]) throws -> [ReceiveAmount] { + var list = [ReceiveAmount]() + for value in arr { + if let val = value as? [String: Any?] { + var receiveAmount = try asReceiveAmount(receiveAmount: val) + list.append(receiveAmount) + } else { + throw SdkError.Generic(message: errUnexpectedType(typeName: "ReceiveAmount")) + } + } + return list + } + static func asSdkEvent(sdkEvent: [String: Any?]) throws -> SdkEvent { let type = sdkEvent["type"] as! String if type == "paymentFailed" { diff --git a/packages/react-native/src/index.ts b/packages/react-native/src/index.ts index 7f9f55507..51f3d9766 100644 --- a/packages/react-native/src/index.ts +++ b/packages/react-native/src/index.ts @@ -340,15 +340,13 @@ export interface PreparePayOnchainResponse { export interface PrepareReceiveRequest { paymentMethod: PaymentMethod - payerAmountSat?: number - assetId?: string + amount?: ReceiveAmount } export interface PrepareReceiveResponse { paymentMethod: PaymentMethod feesSat: number - payerAmountSat?: number - assetId?: string + amount?: ReceiveAmount minPayerAmountSat?: number maxPayerAmountSat?: number swapperFeerate?: number @@ -369,7 +367,6 @@ export interface PrepareRefundResponse { export interface PrepareSendRequest { destination: string amount?: PayAmount - assetId?: string } export interface PrepareSendResponse { @@ -621,13 +618,18 @@ export enum Network { } export enum PayAmountVariant { - RECEIVER = "receiver", + BITCOIN = "bitcoin", + ASSET = "asset", DRAIN = "drain" } export type PayAmount = { - type: PayAmountVariant.RECEIVER, - amountSat: number + type: PayAmountVariant.BITCOIN, + receiverAmountSat: number +} | { + type: PayAmountVariant.ASSET, + assetId: string + receiverAmount: number } | { type: PayAmountVariant.DRAIN } @@ -684,6 +686,20 @@ export enum PaymentType { SEND = "send" } +export enum ReceiveAmountVariant { + BITCOIN = "bitcoin", + ASSET = "asset" +} + +export type ReceiveAmount = { + type: ReceiveAmountVariant.BITCOIN, + payerAmountSat: number +} | { + type: ReceiveAmountVariant.ASSET, + assetId: string + payerAmount?: number +} + export enum SdkEventVariant { PAYMENT_FAILED = "paymentFailed", PAYMENT_PENDING = "paymentPending",