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 2286e00..c7f7efe 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 @@ -299,7 +299,7 @@ typedef struct wire_cst_payment { uint64_t fees_sat; int32_t payment_type; int32_t status; - struct wire_cst_payment_details *details; + struct wire_cst_payment_details details; } wire_cst_payment; typedef struct wire_cst_SdkEvent_PaymentFailed { @@ -1069,8 +1069,6 @@ struct wire_cst_pay_onchain_request *frbgen_breez_liquid_cst_new_box_autoadd_pay struct wire_cst_payment *frbgen_breez_liquid_cst_new_box_autoadd_payment(void); -struct wire_cst_payment_details *frbgen_breez_liquid_cst_new_box_autoadd_payment_details(void); - struct wire_cst_prepare_buy_bitcoin_request *frbgen_breez_liquid_cst_new_box_autoadd_prepare_buy_bitcoin_request(void); struct wire_cst_prepare_pay_onchain_request *frbgen_breez_liquid_cst_new_box_autoadd_prepare_pay_onchain_request(void); @@ -1149,7 +1147,6 @@ static int64_t dummy_method_to_enforce_bundling(void) { dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_message_success_action_data); dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_pay_onchain_request); dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_payment); - dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_payment_details); dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_buy_bitcoin_request); dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_pay_onchain_request); dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request); diff --git a/lib/bindings/src/breez_sdk_liquid.udl b/lib/bindings/src/breez_sdk_liquid.udl index c5ff514..ea6c94c 100644 --- a/lib/bindings/src/breez_sdk_liquid.udl +++ b/lib/bindings/src/breez_sdk_liquid.udl @@ -475,9 +475,9 @@ dictionary Payment { u64 fees_sat; PaymentType payment_type; PaymentState status; + PaymentDetails details; string? destination = null; string? tx_id = null; - PaymentDetails? details = null; }; enum PaymentType { diff --git a/lib/core/Cargo.toml b/lib/core/Cargo.toml index bb8d9cd..f641060 100644 --- a/lib/core/Cargo.toml +++ b/lib/core/Cargo.toml @@ -17,9 +17,7 @@ bip39 = "2.0.0" boltz-client = { git = "https://github.com/SatoshiPortal/boltz-rust", rev = "c140193dab075093e1cfdcc1dd608be8e828d1ef" } chrono = "0.4" env_logger = "0.11" -flutter_rust_bridge = { version = "=2.3.0", features = [ - "chrono", -], optional = true } +flutter_rust_bridge = { version = "=2.3.0", features = ["chrono"], optional = true } log = { workspace = true } lwk_common = "0.7.0" lwk_signer = "0.7.0" diff --git a/lib/core/src/chain_swap.rs b/lib/core/src/chain_swap.rs index 54de2fb..7f31efa 100644 --- a/lib/core/src/chain_swap.rs +++ b/lib/core/src/chain_swap.rs @@ -410,7 +410,7 @@ impl ChainSwapStateHandler { fees_sat: lockup_tx_fees_sat + swap.claim_fees_sat, payment_type: PaymentType::Send, is_confirmed: false, - }, None)?; + }, None, None)?; self.update_swap_info(id, Pending, None, Some(&lockup_tx_id), None, None) .await?; @@ -663,6 +663,7 @@ impl ChainSwapStateHandler { is_confirmed: false, }, None, + None, )?; } diff --git a/lib/core/src/frb_generated.rs b/lib/core/src/frb_generated.rs index 15d9b04..779b61e 100644 --- a/lib/core/src/frb_generated.rs +++ b/lib/core/src/frb_generated.rs @@ -3005,17 +3005,6 @@ 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 { @@ -3096,7 +3085,7 @@ impl SseDecode for crate::model::Payment { let mut var_feesSat = ::sse_decode(deserializer); let mut var_paymentType = ::sse_decode(deserializer); let mut var_status = ::sse_decode(deserializer); - let mut var_details = >::sse_decode(deserializer); + let mut var_details = ::sse_decode(deserializer); return crate::model::Payment { destination: var_destination, tx_id: var_txId, @@ -6493,16 +6482,6 @@ 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) { @@ -6571,7 +6550,7 @@ impl SseEncode for crate::model::Payment { ::sse_encode(self.fees_sat, serializer); ::sse_encode(self.payment_type, serializer); ::sse_encode(self.status, serializer); - >::sse_encode(self.details, serializer); + ::sse_encode(self.details, serializer); } } @@ -7461,13 +7440,6 @@ mod io { CstDecode::::cst_decode(*wrap).into() } } - impl CstDecode for *mut wire_cst_payment_details { - // Codec=Cst (C-struct based), see doc to use other codecs - fn cst_decode(self) -> crate::model::PaymentDetails { - let wrap = unsafe { flutter_rust_bridge::for_generated::box_from_leak_ptr(self) }; - CstDecode::::cst_decode(*wrap).into() - } - } impl CstDecode for *mut wire_cst_prepare_buy_bitcoin_request { @@ -9328,7 +9300,7 @@ mod io { fees_sat: Default::default(), payment_type: Default::default(), status: Default::default(), - details: core::ptr::null_mut(), + details: Default::default(), } } } @@ -10292,14 +10264,6 @@ mod io { flutter_rust_bridge::for_generated::new_leak_box_ptr(wire_cst_payment::new_with_null_ptr()) } - #[no_mangle] - pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_payment_details( - ) -> *mut wire_cst_payment_details { - flutter_rust_bridge::for_generated::new_leak_box_ptr( - wire_cst_payment_details::new_with_null_ptr(), - ) - } - #[no_mangle] pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_prepare_buy_bitcoin_request( ) -> *mut wire_cst_prepare_buy_bitcoin_request { @@ -11173,7 +11137,7 @@ mod io { fees_sat: u64, payment_type: i32, status: i32, - details: *mut wire_cst_payment_details, + details: wire_cst_payment_details, } #[repr(C)] #[derive(Clone, Copy)] diff --git a/lib/core/src/model.rs b/lib/core/src/model.rs index 3fe5f64..337d07a 100644 --- a/lib/core/src/model.rs +++ b/lib/core/src/model.rs @@ -1145,7 +1145,7 @@ pub struct Payment { /// The details of a payment, depending on its [destination](Payment::destination) and /// [type](Payment::payment_type) - pub details: Option, + pub details: PaymentDetails, } impl Payment { pub(crate) fn from_pending_swap(swap: PaymentSwapData, payment_type: PaymentType) -> Payment { @@ -1162,23 +1162,22 @@ impl Payment { fees_sat: swap.payer_amount_sat - swap.receiver_amount_sat, payment_type, status: swap.status, - details: Some(PaymentDetails::Lightning { + details: PaymentDetails::Lightning { swap_id: swap.swap_id, preimage: swap.preimage, bolt11: swap.bolt11, description: swap.description, refund_tx_id: swap.refund_tx_id, refund_tx_amount_sat: swap.refund_tx_amount_sat, - }), + }, } } pub(crate) fn from_tx_data( tx: PaymentTxData, swap: Option, - payment_details: Option, + details: PaymentDetails, ) -> Payment { - let description = swap.as_ref().map(|s| s.description.clone()); Payment { tx_id: Some(tx.tx_id), // When the swap is present and of type send and receive, we retrieve the destination from the invoice. @@ -1202,8 +1201,8 @@ impl Payment { claim_address, .. }) => claim_address.clone(), - _ => match &payment_details { - Some(PaymentDetails::Liquid { destination, .. }) => Some(destination.clone()), + _ => match &details { + PaymentDetails::Liquid { destination, .. } => Some(destination.clone()), _ => None, }, }, @@ -1227,48 +1226,7 @@ impl Payment { false => PaymentState::Pending, }, }, - details: match swap { - Some( - PaymentSwapData { - swap_type: PaymentSwapType::Receive, - swap_id, - bolt11, - refund_tx_id, - preimage, - refund_tx_amount_sat, - .. - } - | PaymentSwapData { - swap_type: PaymentSwapType::Send, - swap_id, - bolt11, - preimage, - refund_tx_id, - refund_tx_amount_sat, - .. - }, - ) => Some(PaymentDetails::Lightning { - swap_id, - preimage, - bolt11, - refund_tx_id, - refund_tx_amount_sat, - description: description.unwrap_or("Liquid transfer".to_string()), - }), - Some(PaymentSwapData { - swap_type: PaymentSwapType::Chain, - swap_id, - refund_tx_id, - refund_tx_amount_sat, - .. - }) => Some(PaymentDetails::Bitcoin { - swap_id, - refund_tx_id, - refund_tx_amount_sat, - description: description.unwrap_or("Bitcoin transfer".to_string()), - }), - _ => payment_details, - }, + details, } } diff --git a/lib/core/src/persist/migrations.rs b/lib/core/src/persist/migrations.rs index 0f21200..5f99559 100644 --- a/lib/core/src/persist/migrations.rs +++ b/lib/core/src/persist/migrations.rs @@ -75,5 +75,24 @@ pub(crate) fn current_migrations() -> Vec<&'static str> { ALTER TABLE send_swaps ADD COLUMN id_hash TEXT; ALTER TABLE chain_swaps ADD COLUMN id_hash TEXT; ", + " + ALTER TABLE payment_details RENAME TO payment_details_old; + + CREATE TABLE IF NOT EXISTS payment_details ( + tx_id TEXT NOT NULL PRIMARY KEY, + destination TEXT NOT NULL, + description TEXT + ) STRICT; + + INSERT INTO payment_details + (tx_id, destination, description) + SELECT + tx_id, + destination, + description + FROM payment_details_old; + + DROP TABLE payment_details_old; + ", ] } diff --git a/lib/core/src/persist/mod.rs b/lib/core/src/persist/mod.rs index 08b235f..518fa64 100644 --- a/lib/core/src/persist/mod.rs +++ b/lib/core/src/persist/mod.rs @@ -86,7 +86,8 @@ impl Persister { pub(crate) fn insert_or_update_payment( &self, ptx: PaymentTxData, - details: Option, + destination: Option, + description: Option, ) -> Result<()> { let mut con = self.get_connection()?; @@ -111,11 +112,8 @@ impl Persister { ptx.is_confirmed, ), )?; - if let Some(PaymentDetails::Liquid { - destination, - description, - }) = details - { + + if let Some(destination) = destination { tx.execute( "INSERT OR REPLACE INTO payment_details ( tx_id, @@ -349,12 +347,54 @@ impl Persister { }, }; - let payment_details = - maybe_payment_details_destination.map(|destination| PaymentDetails::Liquid { - destination, + let description = swap.as_ref().map(|s| s.description.clone()); + let payment_details = match swap.clone() { + Some( + PaymentSwapData { + swap_type: PaymentSwapType::Receive, + swap_id, + bolt11, + refund_tx_id, + preimage, + refund_tx_amount_sat, + .. + } + | PaymentSwapData { + swap_type: PaymentSwapType::Send, + swap_id, + bolt11, + preimage, + refund_tx_id, + refund_tx_amount_sat, + .. + }, + ) => PaymentDetails::Lightning { + swap_id, + preimage, + bolt11, + refund_tx_id, + refund_tx_amount_sat, + description: description.unwrap_or("Liquid transfer".to_string()), + }, + Some(PaymentSwapData { + swap_type: PaymentSwapType::Chain, + swap_id, + refund_tx_id, + refund_tx_amount_sat, + .. + }) => PaymentDetails::Bitcoin { + swap_id, + refund_tx_id, + refund_tx_amount_sat, + description: description.unwrap_or("Bitcoin transfer".to_string()), + }, + _ => PaymentDetails::Liquid { + destination: maybe_payment_details_destination + .unwrap_or("Destination unknown".to_string()), description: maybe_payment_details_description .unwrap_or("Liquid transfer".to_string()), - }); + }, + }; match (tx, swap.clone()) { (None, None) => Err(maybe_tx_tx_id.err().unwrap()), @@ -455,7 +495,11 @@ mod tests { let (_temp_dir, storage) = new_persister()?; let payment_tx_data = new_payment_tx_data(PaymentType::Send); - storage.insert_or_update_payment(payment_tx_data.clone(), None)?; + storage.insert_or_update_payment( + payment_tx_data.clone(), + Some("mock-address".to_string()), + None, + )?; assert!(storage .get_payments(&ListPaymentsRequest { diff --git a/lib/core/src/receive_swap.rs b/lib/core/src/receive_swap.rs index f32daa7..f6986e8 100644 --- a/lib/core/src/receive_swap.rs +++ b/lib/core/src/receive_swap.rs @@ -266,6 +266,7 @@ impl ReceiveSwapStateHandler { is_confirmed: false, }, None, + None, )?; self.update_swap_info(swap_id, Pending, Some(&claim_tx_id), None) diff --git a/lib/core/src/sdk.rs b/lib/core/src/sdk.rs index 9961cfb..9c1a99e 100644 --- a/lib/core/src/sdk.rs +++ b/lib/core/src/sdk.rs @@ -4,8 +4,8 @@ use std::{fs, path::PathBuf, str::FromStr, sync::Arc, time::Duration}; use anyhow::Result; use async_trait::async_trait; +use boltz_client::LockTime; use boltz_client::{swaps::boltz::*, util::secrets::Preimage}; -use boltz_client::{LockTime, ToHex}; use buy::{BuyBitcoinApi, BuyBitcoinService}; use chain::bitcoin::HybridBitcoinChainService; use chain::liquid::{HybridLiquidChainService, LiquidChainService}; @@ -18,6 +18,7 @@ use lwk_wollet::elements::{AssetId, Txid}; use lwk_wollet::hashes::{sha256, Hash}; use lwk_wollet::secp256k1::ThirtyTwoByteHash; use lwk_wollet::{elements, ElementsNetwork, WalletTx}; +use sdk_common::bitcoin::hashes::hex::ToHex; use sdk_common::bitcoin::secp256k1::Secp256k1; use sdk_common::bitcoin::util::bip32::ChildNumber; use sdk_common::liquid::LiquidAddressData; @@ -449,58 +450,38 @@ impl LiquidSdk { .await? } Pending => { - match &payment.details { - Some(details) => - // The swap state has changed to Pending - { - match details.get_swap_id() { - Some(swap_id) => match self - .persister - .fetch_swap_by_id(&swap_id)? - { - Swap::Chain(ChainSwap { claim_tx_id, .. }) - | Swap::Receive(ReceiveSwap { claim_tx_id, .. }) => { - match claim_tx_id { - Some(_) => { - // The claim tx has now been broadcast - self.notify_event_listeners( - SdkEvent::PaymentWaitingConfirmation { - details: payment, - }, - ) - .await? - } - None => { - // The lockup tx is in the mempool/confirmed - self.notify_event_listeners( - SdkEvent::PaymentPending { - details: payment, - }, - ) - .await? - } - } + match &payment.details.get_swap_id() { + Some(swap_id) => match self.persister.fetch_swap_by_id(swap_id)? { + Swap::Chain(ChainSwap { claim_tx_id, .. }) + | Swap::Receive(ReceiveSwap { claim_tx_id, .. }) => { + match claim_tx_id { + Some(_) => { + // The claim tx has now been broadcast + self.notify_event_listeners( + SdkEvent::PaymentWaitingConfirmation { + details: payment, + }, + ) + .await? } - Swap::Send(_) => { + None => { // The lockup tx is in the mempool/confirmed self.notify_event_listeners( SdkEvent::PaymentPending { details: payment }, ) .await? } - }, - // Here we probably have liquid address payment details so we emit PaymentWaitingConfirmation - None => { - self.notify_event_listeners( - SdkEvent::PaymentWaitingConfirmation { - details: payment, - }, - ) - .await? } } - } - // Here we probably have a transaction without any details so we emit PaymentWaitingConfirmation + Swap::Send(_) => { + // The lockup tx is in the mempool/confirmed + self.notify_event_listeners(SdkEvent::PaymentPending { + details: payment, + }) + .await? + } + }, + // Here we probably have a liquid address payment so we emit PaymentWaitingConfirmation None => { self.notify_event_listeners( SdkEvent::PaymentWaitingConfirmation { details: payment }, @@ -564,12 +545,10 @@ impl LiquidSdk { Complete => confirmed_sent_sat += p.amount_sat, Failed => { confirmed_sent_sat += p.amount_sat; - if let Some(details) = p.details { - confirmed_received_sat += - details.get_refund_tx_amount_sat().unwrap_or_default(); - } + confirmed_received_sat += + p.details.get_refund_tx_amount_sat().unwrap_or_default(); } - Pending => match p.details.and_then(|d| d.get_refund_tx_amount_sat()) { + Pending => match p.details.get_refund_tx_amount_sat() { Some(refund_tx_amount_sat) => { confirmed_sent_sat += p.amount_sat; pending_receive_sat += refund_tx_amount_sat; @@ -991,16 +970,22 @@ impl LiquidSdk { payment_type: PaymentType::Send, is_confirmed: false, }; - let payment_details = Some(PaymentDetails::Liquid { - destination: address_data.to_uri().unwrap_or(address_data.address), - description: address_data - .message - .unwrap_or("Liquid transfer".to_string()), - }); - self.persister - .insert_or_update_payment(tx_data.clone(), payment_details.clone())?; + + let destination = address_data.to_uri().unwrap_or(address_data.address); + let description = address_data.message; + + self.persister.insert_or_update_payment( + tx_data.clone(), + Some(destination.clone()), + description.clone(), + )?; self.emit_payment_updated(Some(tx_id)).await?; // Emit Pending event + let payment_details = PaymentDetails::Liquid { + destination, + description: description.unwrap_or("Liquid transfer".to_string()), + }; + Ok(SendPaymentResponse { payment: Payment::from_tx_data(tx_data, None, payment_details), }) @@ -1342,7 +1327,7 @@ impl LiquidSdk { }, event = events_stream.recv() => match event { Ok(SdkEvent::PaymentPending { details: payment }) => { - let maybe_payment_swap_id = payment.details.as_ref().and_then(|d|d.get_swap_id()); + let maybe_payment_swap_id = payment.details.get_swap_id(); if matches!(maybe_payment_swap_id, Some(swap_id) if swap_id == expected_swap_id) { match accept_zero_conf { true => { @@ -1357,7 +1342,7 @@ impl LiquidSdk { }; }, Ok(SdkEvent::PaymentSucceeded { details: payment }) => { - let maybe_payment_swap_id = payment.details.as_ref().and_then(|d| d.get_swap_id()); + let maybe_payment_swap_id = payment.details.get_swap_id(); if matches!(maybe_payment_swap_id, Some(swap_id) if swap_id == expected_swap_id) { debug!("Received Send Payment succeed event"); return Ok(payment); @@ -1924,6 +1909,10 @@ impl LiquidSdk { }, is_confirmed: is_tx_confirmed, }, + match tx.outputs.iter().find(|output| output.is_some()) { + Some(Some(output)) => Some(output.script_pubkey.to_hex()), + _ => None, + }, None, )?; @@ -2098,8 +2087,7 @@ impl LiquidSdk { let processed_sa = match sa { // For AES, we decrypt the contents on the fly SuccessAction::Aes(data) => { - let Some(PaymentDetails::Lightning { preimage, .. }) = - &payment.details + let PaymentDetails::Lightning { preimage, .. } = &payment.details else { return Err(LnUrlPayError::Generic { err: format!("Invalid payment type: expected type `PaymentDetails::Lightning`, got payment details {:?}.", payment.details), diff --git a/lib/core/src/send_swap.rs b/lib/core/src/send_swap.rs index 2ee9663..15dc6f0 100644 --- a/lib/core/src/send_swap.rs +++ b/lib/core/src/send_swap.rs @@ -96,6 +96,7 @@ impl SendSwapStateHandler { is_confirmed: false, }, None, + None, )?; self.update_swap_info(id, Pending, None, Some(&lockup_tx_id), None) diff --git a/packages/dart/lib/src/frb_generated.dart b/packages/dart/lib/src/frb_generated.dart index f5649fc..772c539 100644 --- a/packages/dart/lib/src/frb_generated.dart +++ b/packages/dart/lib/src/frb_generated.dart @@ -1406,12 +1406,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return dco_decode_payment(raw); } - @protected - PaymentDetails dco_decode_box_autoadd_payment_details(dynamic raw) { - // Codec=Dco (DartCObject based), see doc to use other codecs - return dco_decode_payment_details(raw); - } - @protected PrepareBuyBitcoinRequest dco_decode_box_autoadd_prepare_buy_bitcoin_request(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -2175,12 +2169,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return raw == null ? null : dco_decode_box_autoadd_i_64(raw); } - @protected - PaymentDetails? dco_decode_opt_box_autoadd_payment_details(dynamic raw) { - // Codec=Dco (DartCObject based), see doc to use other codecs - return raw == null ? null : dco_decode_box_autoadd_payment_details(raw); - } - @protected SuccessActionProcessed? dco_decode_opt_box_autoadd_success_action_processed(dynamic raw) { // Codec=Dco (DartCObject based), see doc to use other codecs @@ -2235,7 +2223,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { feesSat: dco_decode_u_64(arr[4]), paymentType: dco_decode_payment_type(arr[5]), status: dco_decode_payment_state(arr[6]), - details: dco_decode_opt_box_autoadd_payment_details(arr[7]), + details: dco_decode_payment_details(arr[7]), ); } @@ -3051,12 +3039,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { return (sse_decode_payment(deserializer)); } - @protected - PaymentDetails sse_decode_box_autoadd_payment_details(SseDeserializer deserializer) { - // Codec=Sse (Serialization based), see doc to use other codecs - return (sse_decode_payment_details(deserializer)); - } - @protected PrepareBuyBitcoinRequest sse_decode_box_autoadd_prepare_buy_bitcoin_request(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -3851,17 +3833,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { } } - @protected - PaymentDetails? sse_decode_opt_box_autoadd_payment_details(SseDeserializer deserializer) { - // Codec=Sse (Serialization based), see doc to use other codecs - - if (sse_decode_bool(deserializer)) { - return (sse_decode_box_autoadd_payment_details(deserializer)); - } else { - return null; - } - } - @protected SuccessActionProcessed? sse_decode_opt_box_autoadd_success_action_processed(SseDeserializer deserializer) { // Codec=Sse (Serialization based), see doc to use other codecs @@ -3935,7 +3906,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { var var_feesSat = sse_decode_u_64(deserializer); var var_paymentType = sse_decode_payment_type(deserializer); var var_status = sse_decode_payment_state(deserializer); - var var_details = sse_decode_opt_box_autoadd_payment_details(deserializer); + var var_details = sse_decode_payment_details(deserializer); return Payment( destination: var_destination, txId: var_txId, @@ -4801,12 +4772,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_payment(self, serializer); } - @protected - void sse_encode_box_autoadd_payment_details(PaymentDetails self, SseSerializer serializer) { - // Codec=Sse (Serialization based), see doc to use other codecs - sse_encode_payment_details(self, serializer); - } - @protected void sse_encode_box_autoadd_prepare_buy_bitcoin_request( PrepareBuyBitcoinRequest self, SseSerializer serializer) { @@ -5471,16 +5436,6 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { } } - @protected - void sse_encode_opt_box_autoadd_payment_details(PaymentDetails? 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_payment_details(self, serializer); - } - } - @protected void sse_encode_opt_box_autoadd_success_action_processed( SuccessActionProcessed? self, SseSerializer serializer) { @@ -5549,7 +5504,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi { sse_encode_u_64(self.feesSat, serializer); sse_encode_payment_type(self.paymentType, serializer); sse_encode_payment_state(self.status, serializer); - sse_encode_opt_box_autoadd_payment_details(self.details, serializer); + sse_encode_payment_details(self.details, serializer); } @protected diff --git a/packages/dart/lib/src/frb_generated.io.dart b/packages/dart/lib/src/frb_generated.io.dart index 6f03837..b94c3e0 100644 --- a/packages/dart/lib/src/frb_generated.io.dart +++ b/packages/dart/lib/src/frb_generated.io.dart @@ -143,9 +143,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected Payment dco_decode_box_autoadd_payment(dynamic raw); - @protected - PaymentDetails dco_decode_box_autoadd_payment_details(dynamic raw); - @protected PrepareBuyBitcoinRequest dco_decode_box_autoadd_prepare_buy_bitcoin_request(dynamic raw); @@ -353,9 +350,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected PlatformInt64? dco_decode_opt_box_autoadd_i_64(dynamic raw); - @protected - PaymentDetails? dco_decode_opt_box_autoadd_payment_details(dynamic raw); - @protected SuccessActionProcessed? dco_decode_opt_box_autoadd_success_action_processed(dynamic raw); @@ -621,9 +615,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected Payment sse_decode_box_autoadd_payment(SseDeserializer deserializer); - @protected - PaymentDetails sse_decode_box_autoadd_payment_details(SseDeserializer deserializer); - @protected PrepareBuyBitcoinRequest sse_decode_box_autoadd_prepare_buy_bitcoin_request(SseDeserializer deserializer); @@ -831,9 +822,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected PlatformInt64? sse_decode_opt_box_autoadd_i_64(SseDeserializer deserializer); - @protected - PaymentDetails? sse_decode_opt_box_autoadd_payment_details(SseDeserializer deserializer); - @protected SuccessActionProcessed? sse_decode_opt_box_autoadd_success_action_processed(SseDeserializer deserializer); @@ -1225,14 +1213,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { return ptr; } - @protected - ffi.Pointer cst_encode_box_autoadd_payment_details(PaymentDetails raw) { - // Codec=Cst (C-struct based), see doc to use other codecs - final ptr = wire.cst_new_box_autoadd_payment_details(); - cst_api_fill_to_wire_payment_details(raw, ptr.ref); - return ptr; - } - @protected ffi.Pointer cst_encode_box_autoadd_prepare_buy_bitcoin_request( PrepareBuyBitcoinRequest raw) { @@ -1489,12 +1469,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { return raw == null ? ffi.nullptr : cst_encode_box_autoadd_i_64(raw); } - @protected - ffi.Pointer cst_encode_opt_box_autoadd_payment_details(PaymentDetails? raw) { - // Codec=Cst (C-struct based), see doc to use other codecs - return raw == null ? ffi.nullptr : cst_encode_box_autoadd_payment_details(raw); - } - @protected ffi.Pointer cst_encode_opt_box_autoadd_success_action_processed( SuccessActionProcessed? raw) { @@ -1720,12 +1694,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { cst_api_fill_to_wire_payment(apiObj, wireObj.ref); } - @protected - void cst_api_fill_to_wire_box_autoadd_payment_details( - PaymentDetails apiObj, ffi.Pointer wireObj) { - cst_api_fill_to_wire_payment_details(apiObj, wireObj.ref); - } - @protected void cst_api_fill_to_wire_box_autoadd_prepare_buy_bitcoin_request( PrepareBuyBitcoinRequest apiObj, ffi.Pointer wireObj) { @@ -2301,7 +2269,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { wireObj.fees_sat = cst_encode_u_64(apiObj.feesSat); wireObj.payment_type = cst_encode_payment_type(apiObj.paymentType); wireObj.status = cst_encode_payment_state(apiObj.status); - wireObj.details = cst_encode_opt_box_autoadd_payment_details(apiObj.details); + cst_api_fill_to_wire_payment_details(apiObj.details, wireObj.details); } @protected @@ -2919,9 +2887,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_encode_box_autoadd_payment(Payment self, SseSerializer serializer); - @protected - void sse_encode_box_autoadd_payment_details(PaymentDetails self, SseSerializer serializer); - @protected void sse_encode_box_autoadd_prepare_buy_bitcoin_request( PrepareBuyBitcoinRequest self, SseSerializer serializer); @@ -3133,9 +3098,6 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl { @protected void sse_encode_opt_box_autoadd_i_64(PlatformInt64? self, SseSerializer serializer); - @protected - void sse_encode_opt_box_autoadd_payment_details(PaymentDetails? self, SseSerializer serializer); - @protected void sse_encode_opt_box_autoadd_success_action_processed( SuccessActionProcessed? self, SseSerializer serializer); @@ -4295,16 +4257,6 @@ class RustLibWire implements BaseWire { late final _cst_new_box_autoadd_payment = _cst_new_box_autoadd_paymentPtr.asFunction Function()>(); - ffi.Pointer cst_new_box_autoadd_payment_details() { - return _cst_new_box_autoadd_payment_details(); - } - - late final _cst_new_box_autoadd_payment_detailsPtr = - _lookup Function()>>( - 'frbgen_breez_liquid_cst_new_box_autoadd_payment_details'); - late final _cst_new_box_autoadd_payment_details = - _cst_new_box_autoadd_payment_detailsPtr.asFunction Function()>(); - ffi.Pointer cst_new_box_autoadd_prepare_buy_bitcoin_request() { return _cst_new_box_autoadd_prepare_buy_bitcoin_request(); } @@ -5030,7 +4982,7 @@ final class wire_cst_payment extends ffi.Struct { @ffi.Int32() external int status; - external ffi.Pointer details; + external wire_cst_payment_details details; } final class wire_cst_SdkEvent_PaymentFailed extends ffi.Struct { diff --git a/packages/dart/lib/src/model.dart b/packages/dart/lib/src/model.dart index a6a300b..17421a2 100644 --- a/packages/dart/lib/src/model.dart +++ b/packages/dart/lib/src/model.dart @@ -475,7 +475,7 @@ class Payment { /// The details of a payment, depending on its [destination](Payment::destination) and /// [type](Payment::payment_type) - final PaymentDetails? details; + final PaymentDetails details; const Payment({ this.destination, @@ -485,7 +485,7 @@ class Payment { required this.feesSat, required this.paymentType, required this.status, - this.details, + required this.details, }); @override diff --git a/packages/flutter/example/lib/routes/home/widgets/payment_list/widgets/payment_item.dart b/packages/flutter/example/lib/routes/home/widgets/payment_list/widgets/payment_item.dart index c73de76..daa49e6 100644 --- a/packages/flutter/example/lib/routes/home/widgets/payment_list/widgets/payment_item.dart +++ b/packages/flutter/example/lib/routes/home/widgets/payment_list/widgets/payment_item.dart @@ -36,8 +36,6 @@ class PaymentItem extends StatelessWidget { void _onLongPress(BuildContext context) { final details = item.details; - if (details == null) return; - if (details is PaymentDetails_Lightning && details.preimage != null) { try { debugPrint("Store payment preimage on clipboard. Preimage: ${details.preimage!}"); diff --git a/packages/flutter/example/lib/routes/home/widgets/receive_payment/receive_payment_dialog.dart b/packages/flutter/example/lib/routes/home/widgets/receive_payment/receive_payment_dialog.dart index d78525d..d06e8ff 100644 --- a/packages/flutter/example/lib/routes/home/widgets/receive_payment/receive_payment_dialog.dart +++ b/packages/flutter/example/lib/routes/home/widgets/receive_payment/receive_payment_dialog.dart @@ -34,7 +34,6 @@ class _ReceivePaymentDialogState extends State { if (paymentList.any( (e) { final details = e.details; - if (details == null) return false; if (details is PaymentDetails_Lightning && details.preimage != null) { return details.preimage! == invoiceDestination!; } diff --git a/packages/flutter/lib/flutter_breez_liquid_bindings_generated.dart b/packages/flutter/lib/flutter_breez_liquid_bindings_generated.dart index 294018d..f04226f 100644 --- a/packages/flutter/lib/flutter_breez_liquid_bindings_generated.dart +++ b/packages/flutter/lib/flutter_breez_liquid_bindings_generated.dart @@ -1061,17 +1061,6 @@ class FlutterBreezLiquidBindings { _frbgen_breez_liquid_cst_new_box_autoadd_paymentPtr .asFunction Function()>(); - ffi.Pointer frbgen_breez_liquid_cst_new_box_autoadd_payment_details() { - return _frbgen_breez_liquid_cst_new_box_autoadd_payment_details(); - } - - late final _frbgen_breez_liquid_cst_new_box_autoadd_payment_detailsPtr = - _lookup Function()>>( - 'frbgen_breez_liquid_cst_new_box_autoadd_payment_details'); - late final _frbgen_breez_liquid_cst_new_box_autoadd_payment_details = - _frbgen_breez_liquid_cst_new_box_autoadd_payment_detailsPtr - .asFunction Function()>(); - ffi.Pointer frbgen_breez_liquid_cst_new_box_autoadd_prepare_buy_bitcoin_request() { return _frbgen_breez_liquid_cst_new_box_autoadd_prepare_buy_bitcoin_request(); @@ -1834,7 +1823,7 @@ final class wire_cst_payment extends ffi.Struct { @ffi.Int32() external int status; - external ffi.Pointer details; + external wire_cst_payment_details details; } final class wire_cst_SdkEvent_PaymentFailed extends ffi.Struct { diff --git a/packages/react-native/android/src/main/java/com/breezsdkliquid/BreezSDKLiquidMapper.kt b/packages/react-native/android/src/main/java/com/breezsdkliquid/BreezSDKLiquidMapper.kt index 05946c4..d6b336d 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 @@ -1217,6 +1217,7 @@ fun asPayment(payment: ReadableMap): Payment? { "feesSat", "paymentType", "status", + "details", ), ) ) { @@ -1227,10 +1228,10 @@ fun asPayment(payment: ReadableMap): Payment? { val feesSat = payment.getDouble("feesSat").toULong() val paymentType = payment.getString("paymentType")?.let { asPaymentType(it) }!! val status = payment.getString("status")?.let { asPaymentState(it) }!! + val details = payment.getMap("details")?.let { asPaymentDetails(it) }!! val destination = if (hasNonNullKey(payment, "destination")) payment.getString("destination") else null val txId = if (hasNonNullKey(payment, "txId")) payment.getString("txId") else null - val details = if (hasNonNullKey(payment, "details")) payment.getMap("details")?.let { asPaymentDetails(it) } else null - return Payment(timestamp, amountSat, feesSat, paymentType, status, destination, txId, details) + return Payment(timestamp, amountSat, feesSat, paymentType, status, details, destination, txId) } fun readableMapOf(payment: Payment): ReadableMap = @@ -1240,9 +1241,9 @@ fun readableMapOf(payment: Payment): ReadableMap = "feesSat" to payment.feesSat, "paymentType" to payment.paymentType.name.lowercase(), "status" to payment.status.name.lowercase(), + "details" to readableMapOf(payment.details), "destination" to payment.destination, "txId" to payment.txId, - "details" to payment.details?.let { readableMapOf(it) }, ) fun asPaymentList(arr: ReadableArray): List { diff --git a/packages/react-native/ios/BreezSDKLiquidMapper.swift b/packages/react-native/ios/BreezSDKLiquidMapper.swift index 5948ef7..9b615db 100644 --- a/packages/react-native/ios/BreezSDKLiquidMapper.swift +++ b/packages/react-native/ios/BreezSDKLiquidMapper.swift @@ -1439,6 +1439,11 @@ enum BreezSDKLiquidMapper { } let status = try asPaymentState(paymentState: statusTmp) + guard let detailsTmp = payment["details"] as? [String: Any?] else { + throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "details", typeName: "Payment")) + } + let details = try asPaymentDetails(paymentDetails: detailsTmp) + var destination: String? if hasNonNilKey(data: payment, key: "destination") { guard let destinationTmp = payment["destination"] as? String else { @@ -1453,12 +1458,8 @@ enum BreezSDKLiquidMapper { } txId = txIdTmp } - var details: PaymentDetails? - if let detailsTmp = payment["details"] as? [String: Any?] { - details = try asPaymentDetails(paymentDetails: detailsTmp) - } - return Payment(timestamp: timestamp, amountSat: amountSat, feesSat: feesSat, paymentType: paymentType, status: status, destination: destination, txId: txId, details: details) + return Payment(timestamp: timestamp, amountSat: amountSat, feesSat: feesSat, paymentType: paymentType, status: status, details: details, destination: destination, txId: txId) } static func dictionaryOf(payment: Payment) -> [String: Any?] { @@ -1468,9 +1469,9 @@ enum BreezSDKLiquidMapper { "feesSat": payment.feesSat, "paymentType": valueOf(paymentType: payment.paymentType), "status": valueOf(paymentState: payment.status), + "details": dictionaryOf(paymentDetails: payment.details), "destination": payment.destination == nil ? nil : payment.destination, "txId": payment.txId == nil ? nil : payment.txId, - "details": payment.details == nil ? nil : dictionaryOf(paymentDetails: payment.details!), ] } diff --git a/packages/react-native/src/index.ts b/packages/react-native/src/index.ts index bfc3eec..02550bc 100644 --- a/packages/react-native/src/index.ts +++ b/packages/react-native/src/index.ts @@ -227,9 +227,9 @@ export interface Payment { feesSat: number paymentType: PaymentType status: PaymentState + details: PaymentDetails destination?: string txId?: string - details?: PaymentDetails } export interface PrepareBuyBitcoinRequest {