From 7bdcf769adeed4a2060bf9cb9504762d9e584094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Granh=C3=A3o?= Date: Tue, 9 Sep 2025 00:52:58 +0100 Subject: [PATCH 01/11] Use u128 for payment amounts --- Cargo.lock | 16 +----- Cargo.toml | 2 +- .../bindings/langs/swift/Package.resolved | 16 ++++++ .../bindings/langs/swift/Package.swift | 5 +- crates/breez-sdk/cli/src/commands.rs | 13 ++--- crates/breez-sdk/common/src/input/models.rs | 26 ++++++++- crates/breez-sdk/common/uniffi.toml | 6 ++ crates/breez-sdk/core/src/models/adaptors.rs | 14 ++--- crates/breez-sdk/core/src/models/mod.rs | 32 +++++++++-- crates/breez-sdk/core/src/persist/mod.rs | 2 +- crates/breez-sdk/core/src/persist/sqlite.rs | 48 ++++++++++++++-- crates/breez-sdk/core/src/sdk.rs | 30 ++++++---- crates/breez-sdk/core/src/utils/token.rs | 2 +- crates/breez-sdk/core/uniffi.toml | 6 ++ crates/breez-sdk/wasm/Cargo.toml | 2 +- .../breez-sdk/wasm/js/node-storage/index.cjs | 8 +-- .../wasm/js/node-storage/migrations.cjs | 23 ++++++++ .../wasm/js/node-storage/package-lock.json | 7 +-- crates/breez-sdk/wasm/src/models.rs | 41 ++++++++++---- crates/spark/src/address/mod.rs | 9 ++- .../Sources/SendPayment.swift | 56 +++++++++++-------- 21 files changed, 262 insertions(+), 102 deletions(-) create mode 100644 crates/breez-sdk/bindings/langs/swift/Package.resolved diff --git a/Cargo.lock b/Cargo.lock index fb2e0dbb..33b57ada 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1737,19 +1737,6 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" -[[package]] -name = "gloo-utils" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" -dependencies = [ - "js-sys", - "serde", - "serde_json", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "goblin" version = "0.8.2" @@ -5203,9 +5190,8 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7d0f2208feeb5f7a6edb15a2389c14cd42480ef6417318316bb866da5806a61d" dependencies = [ - "gloo-utils", "serde", - "serde_json", + "serde-wasm-bindgen", "tsify-next-macros", "wasm-bindgen", ] diff --git a/Cargo.toml b/Cargo.toml index 37cc5f9c..4280a022 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -127,7 +127,7 @@ tower-http = "0.6.6" tower-service = "0.3.3" tracing = "0.1.41" tracing-subscriber = "0.3.19" -tsify-next = "0.5.5" +tsify-next = {version = "0.5.5", default-features = false} uniffi = "0.28.3" uuid = { version = "1.17.0", features = ["v7", "v4"] } wasm-bindgen = "0.2.100" diff --git a/crates/breez-sdk/bindings/langs/swift/Package.resolved b/crates/breez-sdk/bindings/langs/swift/Package.resolved new file mode 100644 index 00000000..619b60f6 --- /dev/null +++ b/crates/breez-sdk/bindings/langs/swift/Package.resolved @@ -0,0 +1,16 @@ +{ + "object": { + "pins": [ + { + "package": "BigInt", + "repositoryURL": "https://github.com/attaswift/BigInt.git", + "state": { + "branch": null, + "revision": "e07e00fa1fd435143a2dcf8b7eec9a7710b2fdfe", + "version": "5.7.0" + } + } + ] + }, + "version": 1 +} diff --git a/crates/breez-sdk/bindings/langs/swift/Package.swift b/crates/breez-sdk/bindings/langs/swift/Package.swift index a1b16a4e..ca2bc1a8 100644 --- a/crates/breez-sdk/bindings/langs/swift/Package.swift +++ b/crates/breez-sdk/bindings/langs/swift/Package.swift @@ -12,8 +12,11 @@ let package = Package( products: [ .library(name: "BreezSdkSpark", targets: ["breez_sdk_sparkFFI", "BreezSdkSpark"]), ], + dependencies: [ + .package(url: "https://github.com/attaswift/BigInt.git", from: "5.4.0") + ], targets: [ .binaryTarget(name: "breez_sdk_sparkFFI", path: "./breez_sdk_sparkFFI.xcframework"), - .target(name: "BreezSdkSpark", dependencies: ["breez_sdk_sparkFFI"]), + .target(name: "BreezSdkSpark", dependencies: ["breez_sdk_sparkFFI", "BigInt"]), ] ) diff --git a/crates/breez-sdk/cli/src/commands.rs b/crates/breez-sdk/cli/src/commands.rs index 58d67b66..e399374d 100644 --- a/crates/breez-sdk/cli/src/commands.rs +++ b/crates/breez-sdk/cli/src/commands.rs @@ -66,7 +66,7 @@ pub enum Command { /// Optional amount to pay. By default is denominated in sats. /// If a token identifier is provided, the amount will be denominated in the token base units. #[arg(short = 'a', long)] - amount: Option, + amount: Option, /// Optional token identifier. May only be provided if the payment request is a spark address. #[arg(short = 't', long)] @@ -310,12 +310,11 @@ pub(crate) async fn execute_command( let payment_options = read_payment_options(prepare_response.payment_method.clone(), rl)?; - let send_payment_response = sdk - .send_payment(SendPaymentRequest { - prepare_response, - options: payment_options, - }) - .await?; + let send_payment_response = Box::pin(sdk.send_payment(SendPaymentRequest { + prepare_response, + options: payment_options, + })) + .await?; print_value(&send_payment_response)?; Ok(true) diff --git a/crates/breez-sdk/common/src/input/models.rs b/crates/breez-sdk/common/src/input/models.rs index 6427f584..c0f53f5e 100644 --- a/crates/breez-sdk/common/src/input/models.rs +++ b/crates/breez-sdk/common/src/input/models.rs @@ -264,7 +264,7 @@ pub enum SparkAddressPaymentType { #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] pub struct TokensPaymentDetails { pub token_identifier: Option, - pub amount: Option, + pub amount: Option, } #[derive(Clone, Debug, Deserialize, Serialize)] @@ -307,3 +307,27 @@ pub struct SilentPaymentAddressDetails { pub network: BitcoinNetwork, pub source: PaymentRequestSource, } + +// Uniffi bindings have issues if multiple crates define the same custom type. This is a workaround. +#[allow(unused_imports)] +use u128 as common_u128; + +#[cfg(feature = "uniffi")] +uniffi::custom_type!(common_u128, String); + +#[cfg(feature = "uniffi")] +impl crate::UniffiCustomTypeConverter for u128 { + type Builtin = String; + + fn into_custom(val: Self::Builtin) -> ::uniffi::Result + where + Self: ::std::marker::Sized, + { + val.parse::() + .map_err(uniffi::deps::anyhow::Error::msg) + } + + fn from_custom(obj: Self) -> Self::Builtin { + obj.to_string() + } +} diff --git a/crates/breez-sdk/common/uniffi.toml b/crates/breez-sdk/common/uniffi.toml index 4cf3a9de..4a49290f 100644 --- a/crates/breez-sdk/common/uniffi.toml +++ b/crates/breez-sdk/common/uniffi.toml @@ -11,3 +11,9 @@ disable_java_cleaner = true ffi_module_name = "breez_sdk_sparkFFI" ffi_module_filename = "breez_sdk_commonFFI" cdylib_name = "breez_sdk_spark_bindings" + +[bindings.swift.custom_types.common_u128] +type_name = "BigUInt" +imports = [ "BigInt" ] +into_custom = "BigUInt(stringLiteral: {})" +from_custom = "{}.description" \ No newline at end of file diff --git a/crates/breez-sdk/core/src/models/adaptors.rs b/crates/breez-sdk/core/src/models/adaptors.rs index 8327c634..92b8e340 100644 --- a/crates/breez-sdk/core/src/models/adaptors.rs +++ b/crates/breez-sdk/core/src/models/adaptors.rs @@ -86,7 +86,7 @@ impl TryFrom for Payment { TransferStatus::Expired | TransferStatus::Returned => PaymentStatus::Failed, _ => PaymentStatus::Pending, }; - let (fees_sat, mut amount_sat): (u64, u64) = match transfer.clone().user_request { + let (fees_sat, mut amount_sat) = match transfer.clone().user_request { Some(user_request) => match user_request { SspUserRequest::LightningSendRequest(r) => { // TODO: if we have the preimage it is not pending. This is a workaround @@ -137,8 +137,8 @@ impl TryFrom for Payment { id: transfer.id.to_string(), payment_type, status, - amount: amount_sat, - fees: fees_sat, + amount: amount_sat.into(), + fees: fees_sat.into(), timestamp: match transfer.created_at.map(|t| t.duration_since(UNIX_EPOCH)) { Some(Ok(duration)) => duration.as_secs(), _ => 0, @@ -152,7 +152,7 @@ impl TryFrom for Payment { impl Payment { pub fn from_lightning( payment: LightningSendPayment, - amount_sat: u64, + amount_sat: u128, transfer_id: String, ) -> Result { let mut status = match payment.status { @@ -185,7 +185,7 @@ impl Payment { payment_type: PaymentType::Send, status, amount: amount_sat, - fees: payment.fee_sat, + fees: payment.fee_sat.into(), timestamp: payment.created_at.cast_unsigned(), method: PaymentMethod::Lightning, details: Some(details), @@ -214,7 +214,7 @@ impl From for spark_wallet::Fee { impl From for TokenBalance { fn from(value: spark_wallet::TokenBalance) -> Self { Self { - balance: value.balance.try_into().unwrap_or_default(), // balance will be changed to u128 or similar + balance: value.balance, token_metadata: value.token_metadata.into(), } } @@ -228,7 +228,7 @@ impl From for TokenMetadata { name: value.name, ticker: value.ticker, decimals: value.decimals, - max_supply: value.max_supply.try_into().unwrap_or_default(), // max_supply will be changed to u128 or similar + max_supply: value.max_supply, is_freezable: value.is_freezable, } } diff --git a/crates/breez-sdk/core/src/models/mod.rs b/crates/breez-sdk/core/src/models/mod.rs index beb2f69c..fae8637b 100644 --- a/crates/breez-sdk/core/src/models/mod.rs +++ b/crates/breez-sdk/core/src/models/mod.rs @@ -146,9 +146,9 @@ pub struct Payment { /// Status of the payment pub status: PaymentStatus, /// Amount in satoshis - pub amount: u64, + pub amount: u128, /// Fee paid in satoshis - pub fees: u64, + pub fees: u128, /// Timestamp of when the payment was created pub timestamp: u64, /// Method of payment. Sometimes the payment details is empty so this field @@ -158,6 +158,26 @@ pub struct Payment { pub details: Option, } +#[cfg(feature = "uniffi")] +uniffi::custom_type!(u128, String); + +#[cfg(feature = "uniffi")] +impl crate::UniffiCustomTypeConverter for u128 { + type Builtin = String; + + fn into_custom(val: Self::Builtin) -> ::uniffi::Result + where + Self: ::std::marker::Sized, + { + val.parse::() + .map_err(uniffi::deps::anyhow::Error::msg) + } + + fn from_custom(obj: Self) -> Self::Builtin { + obj.to_string() + } +} + // TODO: fix large enum variant lint - may be done by boxing lnurl_pay_info but that requires // some changes to the wasm bindgen macro #[allow(clippy::large_enum_variant)] @@ -358,7 +378,7 @@ pub struct GetInfoResponse { #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "uniffi", derive(uniffi::Record))] pub struct TokenBalance { - pub balance: u64, + pub balance: u128, pub token_metadata: TokenMetadata, } @@ -372,7 +392,7 @@ pub struct TokenMetadata { pub ticker: String, /// Number of decimals the token uses pub decimals: u32, - pub max_supply: u64, + pub max_supply: u128, pub is_freezable: bool, } @@ -539,7 +559,7 @@ pub struct PrepareSendPaymentRequest { /// Amount to send. By default is denominated in sats. /// If a token identifier is provided, the amount will be denominated in the token base units. #[cfg_attr(feature = "uniffi", uniffi(default=None))] - pub amount: Option, + pub amount: Option, /// If provided, the payment will be for a token /// May only be provided if the payment request is a spark address #[cfg_attr(feature = "uniffi", uniffi(default=None))] @@ -552,7 +572,7 @@ pub struct PrepareSendPaymentResponse { pub payment_method: SendPaymentMethod, /// Amount to send. By default is denominated in sats. /// If a token identifier is provided, the amount will be denominated in the token base units. - pub amount: u64, + pub amount: u128, /// The presence of this field indicates that the payment is for a token /// If empty, it is a Bitcoin payment pub token_identifier: Option, diff --git a/crates/breez-sdk/core/src/persist/mod.rs b/crates/breez-sdk/core/src/persist/mod.rs index 8df24c28..9ddd8e7d 100644 --- a/crates/breez-sdk/core/src/persist/mod.rs +++ b/crates/breez-sdk/core/src/persist/mod.rs @@ -382,7 +382,7 @@ pub mod tests { id: "spark_pmt123".to_string(), payment_type: PaymentType::Send, status: PaymentStatus::Completed, - amount: 100_000, + amount: u128::from(u64::MAX).checked_add(100_000).unwrap(), fees: 1000, timestamp: 5000, method: PaymentMethod::Spark, diff --git a/crates/breez-sdk/core/src/persist/sqlite.rs b/crates/breez-sdk/core/src/persist/sqlite.rs index 00282361..44822524 100644 --- a/crates/breez-sdk/core/src/persist/sqlite.rs +++ b/crates/breez-sdk/core/src/persist/sqlite.rs @@ -169,6 +169,24 @@ impl SqliteStorage { tx_hash TEXT NOT NULL, FOREIGN KEY (payment_id) REFERENCES payments(id) ON DELETE CASCADE );", + // Migration to change payments amount and fees from INTEGER to TEXT + "CREATE TABLE payments_new ( + id TEXT PRIMARY KEY, + payment_type TEXT NOT NULL, + status TEXT NOT NULL, + amount TEXT NOT NULL, + fees TEXT NOT NULL, + timestamp INTEGER NOT NULL, + method TEXT, + withdraw_tx_id TEXT, + deposit_tx_id TEXT, + spark INTEGER + );", + "INSERT INTO payments_new (id, payment_type, status, amount, fees, timestamp, method, withdraw_tx_id, deposit_tx_id, spark) + SELECT id, payment_type, status, CAST(amount AS TEXT), CAST(fees AS TEXT), timestamp, method, withdraw_tx_id, deposit_tx_id, spark + FROM payments;", + "DROP TABLE payments;", + "ALTER TABLE payments_new RENAME TO payments;", ] } } @@ -240,8 +258,8 @@ impl Storage for SqliteStorage { payment.id, payment.payment_type.to_string(), payment.status.to_string(), - payment.amount, - payment.fees, + U128SqlWrapper(payment.amount), + U128SqlWrapper(payment.fees), payment.timestamp, payment.method, ], @@ -545,8 +563,8 @@ fn map_payment(row: &Row<'_>) -> Result { status: row.get::<_, String>(2)?.parse().map_err(|e: String| { rusqlite::Error::FromSqlConversionFailure(2, rusqlite::types::Type::Text, e.into()) })?, - amount: row.get(3)?, - fees: row.get(4)?, + amount: row.get::<_, U128SqlWrapper>(3)?.0, + fees: row.get::<_, U128SqlWrapper>(4)?.0, timestamp: row.get(5)?, details, method: row.get(6)?, @@ -643,6 +661,28 @@ impl FromSql for LnurlPayInfo { } } +struct U128SqlWrapper(u128); + +impl ToSql for U128SqlWrapper { + fn to_sql(&self) -> rusqlite::Result> { + let string = self.0.to_string(); + Ok(rusqlite::types::ToSqlOutput::from(string)) + } +} + +impl FromSql for U128SqlWrapper { + fn column_result(value: ValueRef<'_>) -> FromSqlResult { + match value { + ValueRef::Text(i) => { + let s = std::str::from_utf8(i).map_err(|e| FromSqlError::Other(Box::new(e)))?; + let integer = s.parse::().map_err(|_| FromSqlError::InvalidType)?; + Ok(U128SqlWrapper(integer)) + } + _ => Err(FromSqlError::InvalidType), + } + } +} + #[cfg(test)] mod tests { use crate::SqliteStorage; diff --git a/crates/breez-sdk/core/src/sdk.rs b/crates/breez-sdk/core/src/sdk.rs index 742991b0..dc96906a 100644 --- a/crates/breez-sdk/core/src/sdk.rs +++ b/crates/breez-sdk/core/src/sdk.rs @@ -684,7 +684,7 @@ impl BreezSdk { let prepare_response = self .prepare_send_payment(PrepareSendPaymentRequest { payment_request: success_data.pr, - amount: Some(request.amount_sats), + amount: Some(request.amount_sats.into()), token_identifier: None, }) .await?; @@ -720,7 +720,7 @@ impl BreezSdk { spark_transfer_fee_sats: None, lightning_fee_sats: request.prepare_response.fee_sats, }, - amount: request.prepare_response.amount_sats, + amount: request.prepare_response.amount_sats.into(), token_identifier: None, }, options: None, @@ -796,7 +796,7 @@ impl BreezSdk { "Amount can't be provided for this payment request: spark invoice defines amount".to_string(), )); } - sats_payment_details.amount + sats_payment_details.amount.map(Into::into) } spark_wallet::SparkAddressPaymentType::TokensPayment( tokens_payment_details, @@ -856,7 +856,12 @@ impl BreezSdk { let lightning_fee_sats = self .spark_wallet - .fetch_lightning_send_fee_estimate(&request.payment_request, amount_sats) + .fetch_lightning_send_fee_estimate( + &request.payment_request, + amount_sats + .map(|a| Ok::(a.try_into()?)) + .transpose()?, + ) .await?; Ok(PrepareSendPaymentResponse { @@ -866,7 +871,9 @@ impl BreezSdk { lightning_fee_sats, }, amount: amount_sats - .or(detailed_bolt11_invoice.amount_msat.map(|msat| msat / 1000)) + .or(detailed_bolt11_invoice + .amount_msat + .map(|msat| u128::from(msat) / 1000)) .ok_or(SdkError::InvalidInput("Amount is required".to_string()))?, token_identifier: None, }) @@ -878,7 +885,8 @@ impl BreezSdk { &withdrawal_address.address, Some( amount_sats - .ok_or(SdkError::InvalidInput("Amount is required".to_string()))?, + .ok_or(SdkError::InvalidInput("Amount is required".to_string()))? + .try_into()?, ), ) .await?; @@ -1231,14 +1239,14 @@ impl BreezSdk { let payment = if let Some(identifier) = token_identifier { self.send_spark_token_payment( identifier, - request.prepare_response.amount.into(), + request.prepare_response.amount, spark_address, ) .await? } else { let transfer = self .spark_wallet - .transfer(request.prepare_response.amount, &spark_address) + .transfer(request.prepare_response.amount.try_into()?, &spark_address) .await?; transfer.try_into()? }; @@ -1275,7 +1283,9 @@ impl BreezSdk { .spark_wallet .pay_lightning_invoice( &invoice_details.invoice.bolt11, - amount_to_send, + amount_to_send + .map(|a| Ok::(a.try_into()?)) + .transpose()?, Some(fee_sats), prefer_spark, ) @@ -1334,7 +1344,7 @@ impl BreezSdk { .spark_wallet .withdraw( &address.address, - Some(request.prepare_response.amount), + Some(request.prepare_response.amount.try_into()?), exit_speed, fee_quote.clone().into(), ) diff --git a/crates/breez-sdk/core/src/utils/token.rs b/crates/breez-sdk/core/src/utils/token.rs index 93c1a179..1b7db07b 100644 --- a/crates/breez-sdk/core/src/utils/token.rs +++ b/crates/breez-sdk/core/src/utils/token.rs @@ -86,7 +86,7 @@ pub async fn token_transaction_to_payments( transaction.status, is_transfer_transaction, ), - amount: output.token_amount.try_into().unwrap_or_default(), + amount: output.token_amount, fees: 0, // TODO: calculate actual fees when they start being charged timestamp, method: PaymentMethod::Token, diff --git a/crates/breez-sdk/core/uniffi.toml b/crates/breez-sdk/core/uniffi.toml index b6b30cef..1811a0ba 100644 --- a/crates/breez-sdk/core/uniffi.toml +++ b/crates/breez-sdk/core/uniffi.toml @@ -11,3 +11,9 @@ disable_java_cleaner = true ffi_module_name = "breez_sdk_sparkFFI" ffi_module_filename = "breez_sdk_sparkFFI" cdylib_name = "breez_sdk_spark_bindings" + +[bindings.swift.custom_types.u128] +type_name = "BigUInt" +imports = [ "BigInt" ] +into_custom = "BigUInt(stringLiteral: {})" +from_custom = "{}.description" diff --git a/crates/breez-sdk/wasm/Cargo.toml b/crates/breez-sdk/wasm/Cargo.toml index c0ff4aa5..db32bb92 100644 --- a/crates/breez-sdk/wasm/Cargo.toml +++ b/crates/breez-sdk/wasm/Cargo.toml @@ -19,7 +19,7 @@ serde.workspace = true serde-wasm-bindgen.workspace = true tracing.workspace = true tracing-subscriber.workspace = true -tsify-next.workspace = true +tsify-next = {workspace = true, default-features = false, features = ["js"]} wasm-bindgen.workspace = true wasm-bindgen-futures.workspace = true bitcoin.workspace = true diff --git a/crates/breez-sdk/wasm/js/node-storage/index.cjs b/crates/breez-sdk/wasm/js/node-storage/index.cjs index 377511d9..321df6a7 100644 --- a/crates/breez-sdk/wasm/js/node-storage/index.cjs +++ b/crates/breez-sdk/wasm/js/node-storage/index.cjs @@ -191,8 +191,8 @@ class SqliteStorage { id: payment.id, paymentType: payment.paymentType, status: payment.status, - amount: payment.amount, - fees: payment.fees, + amount: payment.amount.toString(), + fees: payment.fees.toString(), timestamp: payment.timestamp, method: payment.method ? JSON.stringify(payment.method) : null, withdrawTxId: @@ -525,8 +525,8 @@ class SqliteStorage { id: row.id, paymentType: row.payment_type, status: row.status, - amount: row.amount, - fees: row.fees, + amount: BigInt(row.amount), + fees: BigInt(row.fees), timestamp: row.timestamp, method, details, diff --git a/crates/breez-sdk/wasm/js/node-storage/migrations.cjs b/crates/breez-sdk/wasm/js/node-storage/migrations.cjs index f05463d5..137d0348 100644 --- a/crates/breez-sdk/wasm/js/node-storage/migrations.cjs +++ b/crates/breez-sdk/wasm/js/node-storage/migrations.cjs @@ -188,6 +188,29 @@ class MigrationManager { )`, ], }, + { + name: "Change payments amount and fees from INTEGER to TEXT", + sql: [ + `CREATE TABLE payments_new ( + id TEXT PRIMARY KEY, + payment_type TEXT NOT NULL, + status TEXT NOT NULL, + amount TEXT NOT NULL, + fees TEXT NOT NULL, + timestamp INTEGER NOT NULL, + method TEXT, + withdraw_tx_id TEXT, + deposit_tx_id TEXT, + spark INTEGER + method TEXT + )`, + `INSERT INTO payments_new (id, payment_type, status, amount, fees, timestamp, method, withdraw_tx_id, deposit_tx_id, spark) + SELECT id, payment_type, status, CAST(amount AS TEXT), CAST(fees AS TEXT), timestamp, method, withdraw_tx_id, deposit_tx_id, spark + FROM payments`, + `DROP TABLE payments`, + `ALTER TABLE payments_new RENAME TO payments`, + ], + }, ]; } } diff --git a/crates/breez-sdk/wasm/js/node-storage/package-lock.json b/crates/breez-sdk/wasm/js/node-storage/package-lock.json index c5002838..5eff346a 100644 --- a/crates/breez-sdk/wasm/js/node-storage/package-lock.json +++ b/crates/breez-sdk/wasm/js/node-storage/package-lock.json @@ -1536,10 +1536,9 @@ } }, "node_modules/tar-fs": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.3.tgz", - "integrity": "sha512-090nwYJDmlhwFwEW3QQl+vaNnxsO2yVsd45eTKRBzSzu+hlb1w2K9inVq5b0ngXuLVqQ4ApvsUHHnu/zQNkWAg==", - "license": "MIT", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", diff --git a/crates/breez-sdk/wasm/src/models.rs b/crates/breez-sdk/wasm/src/models.rs index 697e355d..e4d4290d 100644 --- a/crates/breez-sdk/wasm/src/models.rs +++ b/crates/breez-sdk/wasm/src/models.rs @@ -2,6 +2,26 @@ use std::collections::HashMap; use wasm_bindgen::prelude::wasm_bindgen; +// Helper module for serializing u128 as string +mod serde_u128_as_string { + use serde::{Deserialize, Deserializer, Serializer}; + + pub fn serialize(value: &u128, serializer: S) -> Result + where + S: Serializer, + { + serializer.serialize_str(&value.to_string()) + } + + pub fn deserialize<'de, D>(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + s.parse().map_err(serde::de::Error::custom) + } +} + #[allow(clippy::large_enum_variant)] #[macros::extern_wasm_bindgen(breez_sdk_spark::SdkEvent)] pub enum SdkEvent { @@ -161,7 +181,7 @@ pub enum SparkAddressPaymentType { #[macros::extern_wasm_bindgen(breez_sdk_common::input::TokensPaymentDetails)] pub struct TokensPaymentDetails { pub token_identifier: Option, - pub amount: Option, + pub amount: Option, } #[macros::extern_wasm_bindgen(breez_sdk_common::input::SatsPaymentDetails)] @@ -361,8 +381,8 @@ pub struct Payment { pub id: String, pub payment_type: PaymentType, pub status: PaymentStatus, - pub amount: u64, - pub fees: u64, + pub amount: u128, + pub fees: u128, pub timestamp: u64, pub method: PaymentMethod, pub details: Option, @@ -506,21 +526,22 @@ pub struct GetInfoResponse { #[macros::extern_wasm_bindgen(breez_sdk_spark::TokenBalance)] pub struct TokenBalance { - pub balance: u64, + pub balance: u128, pub token_metadata: TokenMetadata, } #[macros::extern_wasm_bindgen(breez_sdk_spark::TokenMetadata)] pub struct TokenMetadata { pub identifier: String, - /// Hex representation of the issuer public key pub issuer_public_key: String, pub name: String, pub ticker: String, - /// Number of decimals the token uses pub decimals: u32, - /// Decimal representation of the token max supply (unsigned 128-bit integer) - pub max_supply: u64, + // Serde doesn't support deserializing u128 types whenever they are user with flatten: https://github.com/serde-rs/json/issues/625 + // This occurs in the storage implementation when parsing `PaymentDetails` due to the use of flatten in LnurlRequestDetails + // Serializing as string is a workaround to avoid the issue. + #[serde(with = "serde_u128_as_string")] + pub max_supply: u128, pub is_freezable: bool, } @@ -616,14 +637,14 @@ pub struct LnurlPayResponse { #[macros::extern_wasm_bindgen(breez_sdk_spark::PrepareSendPaymentRequest)] pub struct PrepareSendPaymentRequest { pub payment_request: String, - pub amount: Option, + pub amount: Option, pub token_identifier: Option, } #[macros::extern_wasm_bindgen(breez_sdk_spark::PrepareSendPaymentResponse)] pub struct PrepareSendPaymentResponse { pub payment_method: SendPaymentMethod, - pub amount: u64, + pub amount: u128, pub token_identifier: Option, } diff --git a/crates/spark/src/address/mod.rs b/crates/spark/src/address/mod.rs index c8e3e350..509bcb3b 100644 --- a/crates/spark/src/address/mod.rs +++ b/crates/spark/src/address/mod.rs @@ -69,7 +69,7 @@ pub struct SatsPayment { #[derive(Clone, PartialEq, Eq, Hash)] pub struct TokensPayment { pub token_identifier: Option, - pub amount: Option, + pub amount: Option, } impl From for ProtoPaymentType { @@ -77,9 +77,7 @@ impl From for ProtoPaymentType { match value { SparkAddressPaymentType::TokensPayment(tp) => { ProtoPaymentType::TokensPayment(ProtoTokensPayment { - amount: tp - .amount - .map(|amount| u128::to_be_bytes(amount as u128).to_vec()), + amount: tp.amount.map(|amount| amount.to_be_bytes().to_vec()), token_identifier: tp.token_identifier.map(|id| id.0.to_vec()), }) } @@ -100,7 +98,7 @@ impl TryFrom for SparkAddressPaymentType { let amount_bytes: [u8; 16] = amount.try_into().map_err(|_| { AddressError::InvalidPaymentIntent("Invalid amount".to_string()) })?; - Some(u128::from_be_bytes(amount_bytes) as u64) + Some(u128::from_be_bytes(amount_bytes)) } None => None, }; @@ -121,6 +119,7 @@ impl TryFrom for SparkAddressPaymentType { #[derive(Clone, Debug, PartialEq, Eq, Hash)] pub struct AssetIdentifier(Vec); + impl std::fmt::Display for AssetIdentifier { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "{}", hex::encode(&self.0)) diff --git a/docs/breez-sdk/snippets/swift/BreezSdkSnippets/Sources/SendPayment.swift b/docs/breez-sdk/snippets/swift/BreezSdkSnippets/Sources/SendPayment.swift index eeb7ec82..190ac218 100644 --- a/docs/breez-sdk/snippets/swift/BreezSdkSnippets/Sources/SendPayment.swift +++ b/docs/breez-sdk/snippets/swift/BreezSdkSnippets/Sources/SendPayment.swift @@ -1,18 +1,21 @@ +import BigInt import BreezSdkSpark func prepareSendPaymentLightningBolt11(sdk: BreezSdk) async throws { // ANCHOR: prepare-send-payment-lightning-bolt11 let paymentRequest = "" // Optionally set the amount you wish the pay the receiver - let optionalAmountSats: UInt64 = 5_000 + let optionalAmountSats: BigUInt = 5_000 let prepareResponse = try await sdk.prepareSendPayment( - request: PrepareSendPaymentRequest ( + request: PrepareSendPaymentRequest( paymentRequest: paymentRequest, - amountSats: optionalAmountSats + amount: optionalAmountSats, )) - if case let .bolt11Invoice(_, sparkTransferFeeSats, lightningFeeSats) = prepareResponse.paymentMethod { + if case let .bolt11Invoice(_, sparkTransferFeeSats, lightningFeeSats) = prepareResponse + .paymentMethod + { // Fees to pay via Lightning print("Lightning Fee: \(lightningFeeSats) sats") // Or fees to pay (if available) via a Spark transfer @@ -27,12 +30,12 @@ func prepareSendPaymentOnchain(sdk: BreezSdk) async throws { // ANCHOR: prepare-send-payment-onchain let paymentRequest = "" // Set the amount you wish the pay the receiver - let amountSats: UInt64 = 50_000 + let amountSats: BigUInt = 50_000 let prepareResponse = try await sdk.prepareSendPayment( - request: PrepareSendPaymentRequest ( + request: PrepareSendPaymentRequest( paymentRequest: paymentRequest, - amountSats: amountSats + amount: amountSats )) if case let .bitcoinAddress(_, feeQuote) = prepareResponse.paymentMethod { @@ -50,27 +53,30 @@ func prepareSendPaymentSpark(sdk: BreezSdk) async throws { // ANCHOR: prepare-send-payment-spark let paymentRequest = "" // Set the amount you wish the pay the receiver - let amountSats: UInt64 = 50_000 + let amountSats: BigUInt = 50_000 let prepareResponse = try await sdk.prepareSendPayment( - request: PrepareSendPaymentRequest ( + request: PrepareSendPaymentRequest( paymentRequest: paymentRequest, - amountSats: amountSats + amount: amountSats )) - if case let .sparkAddress(_, feeSats) = prepareResponse.paymentMethod { + if case let .sparkAddress(_, feeSats, _) = prepareResponse.paymentMethod { print("Fees: \(feeSats) sats") } // ANCHOR_END: prepare-send-payment-spark } -func sendPaymentLightningBolt11(sdk: BreezSdk, prepareResponse: PrepareSendPaymentResponse) async throws { +func sendPaymentLightningBolt11(sdk: BreezSdk, prepareResponse: PrepareSendPaymentResponse) + async throws +{ // ANCHOR: send-payment-lightning-bolt11 let options = SendPaymentOptions.bolt11Invoice(preferSpark: true, completionTimeoutSecs: 10) - let sendResponse = try await sdk.sendPayment(request: SendPaymentRequest ( - prepareResponse: prepareResponse, - options: options - )) + let sendResponse = try await sdk.sendPayment( + request: SendPaymentRequest( + prepareResponse: prepareResponse, + options: options + )) let payment = sendResponse.payment // ANCHOR_END: send-payment-lightning-bolt11 print(payment) @@ -79,10 +85,11 @@ func sendPaymentLightningBolt11(sdk: BreezSdk, prepareResponse: PrepareSendPayme func sendPaymentOnchain(sdk: BreezSdk, prepareResponse: PrepareSendPaymentResponse) async throws { // ANCHOR: send-payment-onchain let options = SendPaymentOptions.bitcoinAddress(confirmationSpeed: .medium) - let sendResponse = try await sdk.sendPayment(request: SendPaymentRequest ( - prepareResponse: prepareResponse, - options: options - )) + let sendResponse = try await sdk.sendPayment( + request: SendPaymentRequest( + prepareResponse: prepareResponse, + options: options + )) let payment = sendResponse.payment // ANCHOR_END: send-payment-onchain print(payment) @@ -90,10 +97,11 @@ func sendPaymentOnchain(sdk: BreezSdk, prepareResponse: PrepareSendPaymentRespon func sendPaymentSpark(sdk: BreezSdk, prepareResponse: PrepareSendPaymentResponse) async throws { // ANCHOR: send-payment-spark - let sendResponse = try await sdk.sendPayment(request: SendPaymentRequest ( - prepareResponse: prepareResponse, - options: nil - )) + let sendResponse = try await sdk.sendPayment( + request: SendPaymentRequest( + prepareResponse: prepareResponse, + options: nil + )) let payment = sendResponse.payment // ANCHOR_END: send-payment-spark print(payment) From 20949ff33feab037dd50d0588d6143e1f5290cf8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Granh=C3=A3o?= Date: Tue, 9 Sep 2025 11:11:09 +0100 Subject: [PATCH 02/11] Kotlin support for custom u128 type --- .../breez-sdk-spark-kmp/build.gradle.kts | 1 + crates/breez-sdk/common/uniffi.kotlin-multiplatform.toml | 6 ++++++ crates/breez-sdk/common/uniffi.toml | 7 +++++++ crates/breez-sdk/core/uniffi.kotlin-multiplatform.toml | 6 ++++++ crates/breez-sdk/core/uniffi.toml | 7 +++++++ 5 files changed, 27 insertions(+) diff --git a/crates/breez-sdk/bindings/langs/kotlin-multiplatform/breez-sdk-spark-kmp/build.gradle.kts b/crates/breez-sdk/bindings/langs/kotlin-multiplatform/breez-sdk-spark-kmp/build.gradle.kts index ad45ef8f..99c9ee46 100644 --- a/crates/breez-sdk/bindings/langs/kotlin-multiplatform/breez-sdk-spark-kmp/build.gradle.kts +++ b/crates/breez-sdk/bindings/langs/kotlin-multiplatform/breez-sdk-spark-kmp/build.gradle.kts @@ -66,6 +66,7 @@ kotlin { implementation("com.squareup.okio:okio:3.6.0") implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.5.0") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0") + implementation("com.ionspin.kotlin:bignum:0.3.10") } } diff --git a/crates/breez-sdk/common/uniffi.kotlin-multiplatform.toml b/crates/breez-sdk/common/uniffi.kotlin-multiplatform.toml index e87cd791..482e650f 100644 --- a/crates/breez-sdk/common/uniffi.kotlin-multiplatform.toml +++ b/crates/breez-sdk/common/uniffi.kotlin-multiplatform.toml @@ -5,3 +5,9 @@ kotlin_multiplatform = true kotlin_targets = ["jvm", "android", "native"] kotlin_target_version = "1.9.21" disable_java_cleaner = true + +[custom_types.common_u128] +type_name = "BigInteger" +imports = [ "com.ionspin.kotlin.bignum.integer.BigInteger" ] +into_custom = "BigInteger.parseString({}, 10)" +from_custom = "{}.toString(10)" \ No newline at end of file diff --git a/crates/breez-sdk/common/uniffi.toml b/crates/breez-sdk/common/uniffi.toml index 4a49290f..652dc515 100644 --- a/crates/breez-sdk/common/uniffi.toml +++ b/crates/breez-sdk/common/uniffi.toml @@ -6,6 +6,13 @@ kotlin_targets = ["jvm"] kotlin_target_version = "1.9.21" disable_java_cleaner = true +# Kotlin custom types +[custom_types.common_u128] +type_name = "BigInteger" +imports = [ "java.math.BigInteger" ] +into_custom = "BigInteger({})" +from_custom = "{}.toString()" + # https://mozilla.github.io/uniffi-rs/swift/configuration.html [bindings.swift] ffi_module_name = "breez_sdk_sparkFFI" diff --git a/crates/breez-sdk/core/uniffi.kotlin-multiplatform.toml b/crates/breez-sdk/core/uniffi.kotlin-multiplatform.toml index 0b93032d..d102b62b 100644 --- a/crates/breez-sdk/core/uniffi.kotlin-multiplatform.toml +++ b/crates/breez-sdk/core/uniffi.kotlin-multiplatform.toml @@ -5,3 +5,9 @@ kotlin_multiplatform = true kotlin_targets = ["jvm", "android", "native"] kotlin_target_version = "1.9.21" disable_java_cleaner = true + +[custom_types.u128] +type_name = "BigInteger" +imports = [ "com.ionspin.kotlin.bignum.integer.BigInteger" ] +into_custom = "BigInteger.parseString({}, 10)" +from_custom = "{}.toString(10)" \ No newline at end of file diff --git a/crates/breez-sdk/core/uniffi.toml b/crates/breez-sdk/core/uniffi.toml index 1811a0ba..57dc47d4 100644 --- a/crates/breez-sdk/core/uniffi.toml +++ b/crates/breez-sdk/core/uniffi.toml @@ -6,6 +6,13 @@ kotlin_targets = ["jvm"] kotlin_target_version = "1.9.21" disable_java_cleaner = true +# Kotlin custom types +[custom_types.u128] +type_name = "BigInteger" +imports = [ "java.math.BigInteger" ] +into_custom = "BigInteger({})" +from_custom = "{}.toString()" + # https://mozilla.github.io/uniffi-rs/swift/configuration.html [bindings.swift] ffi_module_name = "breez_sdk_sparkFFI" From 40f24161b88ddca0b444cf8a369b3ff8d5ca7d88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Granh=C3=A3o?= Date: Tue, 9 Sep 2025 14:25:40 +0100 Subject: [PATCH 03/11] Update flutter --- crates/breez-sdk/core/src/models/mod.rs | 2 +- crates/breez-sdk/wasm/src/models.rs | 2 +- packages/flutter/rust/src/models.rs | 16 ++++++++-------- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/crates/breez-sdk/core/src/models/mod.rs b/crates/breez-sdk/core/src/models/mod.rs index fae8637b..d96b9ec6 100644 --- a/crates/breez-sdk/core/src/models/mod.rs +++ b/crates/breez-sdk/core/src/models/mod.rs @@ -433,7 +433,7 @@ pub enum SendPaymentMethod { address: String, /// Fee to pay for the transaction /// Denominated in sats if token identifier is empty, otherwise in the token base units - fee: u64, + fee: u128, /// The presence of this field indicates that the payment is for a token /// If empty, it is a Bitcoin payment token_identifier: Option, diff --git a/crates/breez-sdk/wasm/src/models.rs b/crates/breez-sdk/wasm/src/models.rs index e4d4290d..e8dd8a41 100644 --- a/crates/breez-sdk/wasm/src/models.rs +++ b/crates/breez-sdk/wasm/src/models.rs @@ -589,7 +589,7 @@ pub enum SendPaymentMethod { }, // should be replaced with the parsed invoice SparkAddress { address: String, - fee: u64, + fee: u128, token_identifier: Option, }, } diff --git a/packages/flutter/rust/src/models.rs b/packages/flutter/rust/src/models.rs index 53f6d8ad..16af391c 100644 --- a/packages/flutter/rust/src/models.rs +++ b/packages/flutter/rust/src/models.rs @@ -96,7 +96,7 @@ pub struct _GetInfoResponse { #[frb(mirror(TokenBalance))] pub struct _TokenBalance { - pub balance: u64, + pub balance: u128, pub token_metadata: TokenMetadata, } @@ -107,7 +107,7 @@ pub struct _TokenMetadata { pub name: String, pub ticker: String, pub decimals: u32, - pub max_supply: u64, + pub max_supply: u128, pub is_freezable: bool, } @@ -206,14 +206,14 @@ pub struct _PrepareLnurlPayResponse { #[frb(mirror(PrepareSendPaymentRequest))] pub struct _PrepareSendPaymentRequest { pub payment_request: String, - pub amount: Option, + pub amount: Option, pub token_identifier: Option, } #[frb(mirror(PrepareSendPaymentResponse))] pub struct _PrepareSendPaymentResponse { pub payment_method: SendPaymentMethod, - pub amount: u64, + pub amount: u128, pub token_identifier: Option, } @@ -280,7 +280,7 @@ pub enum _SendPaymentMethod { }, SparkAddress { address: String, - fee: u64, + fee: u128, token_identifier: Option, }, } @@ -369,8 +369,8 @@ pub struct _Payment { pub id: String, pub payment_type: PaymentType, pub status: PaymentStatus, - pub amount: u64, - pub fees: u64, + pub amount: u128, + pub fees: u128, pub timestamp: u64, pub method: PaymentMethod, pub details: Option, @@ -585,7 +585,7 @@ pub enum _SparkAddressPaymentType { #[frb(mirror(TokensPaymentDetails))] pub struct _TokensPaymentDetails { pub token_identifier: Option, - pub amount: Option, + pub amount: Option, } #[frb(mirror(SatsPaymentDetails))] From 32ce6753bd250f79b81b74a0284b02b333007156 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Granh=C3=A3o?= Date: Tue, 9 Sep 2025 16:09:13 +0100 Subject: [PATCH 04/11] Python support for custom u128 type --- crates/breez-sdk/common/uniffi.toml | 7 ++++++- crates/breez-sdk/core/uniffi.toml | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/crates/breez-sdk/common/uniffi.toml b/crates/breez-sdk/common/uniffi.toml index 652dc515..7f3cf40c 100644 --- a/crates/breez-sdk/common/uniffi.toml +++ b/crates/breez-sdk/common/uniffi.toml @@ -23,4 +23,9 @@ cdylib_name = "breez_sdk_spark_bindings" type_name = "BigUInt" imports = [ "BigInt" ] into_custom = "BigUInt(stringLiteral: {})" -from_custom = "{}.description" \ No newline at end of file +from_custom = "{}.description" + +[bindings.python.custom_types.CommonU128] +type_name = "int" +into_custom = "int({})" +from_custom = "str({})" \ No newline at end of file diff --git a/crates/breez-sdk/core/uniffi.toml b/crates/breez-sdk/core/uniffi.toml index 57dc47d4..fa5c14dd 100644 --- a/crates/breez-sdk/core/uniffi.toml +++ b/crates/breez-sdk/core/uniffi.toml @@ -24,3 +24,8 @@ type_name = "BigUInt" imports = [ "BigInt" ] into_custom = "BigUInt(stringLiteral: {})" from_custom = "{}.description" + +[bindings.python.custom_types.U128] +type_name = "int" +into_custom = "int({})" +from_custom = "str({})" From efba9f2bdfbc3a2815bf09e09fbdd49503c20fad Mon Sep 17 00:00:00 2001 From: Ross Savage Date: Wed, 24 Sep 2025 16:05:09 +0200 Subject: [PATCH 05/11] React Native support for custom u128 type --- crates/breez-sdk/common/uniffi.toml | 7 ++++++- crates/breez-sdk/core/uniffi.toml | 5 +++++ docs/breez-sdk/snippets/react-native/send_payment.ts | 11 +++++++---- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/crates/breez-sdk/common/uniffi.toml b/crates/breez-sdk/common/uniffi.toml index 7f3cf40c..d883d91c 100644 --- a/crates/breez-sdk/common/uniffi.toml +++ b/crates/breez-sdk/common/uniffi.toml @@ -28,4 +28,9 @@ from_custom = "{}.description" [bindings.python.custom_types.CommonU128] type_name = "int" into_custom = "int({})" -from_custom = "str({})" \ No newline at end of file +from_custom = "str({})" + +[bindings.typescript.customTypes.common_u128] +typeName = "bigint" +intoCustom = "BigInt({})" +fromCustom = "{}.toString()" diff --git a/crates/breez-sdk/core/uniffi.toml b/crates/breez-sdk/core/uniffi.toml index fa5c14dd..23b0cf9e 100644 --- a/crates/breez-sdk/core/uniffi.toml +++ b/crates/breez-sdk/core/uniffi.toml @@ -29,3 +29,8 @@ from_custom = "{}.description" type_name = "int" into_custom = "int({})" from_custom = "str({})" + +[bindings.typescript.customTypes.u128] +typeName = "bigint" +intoCustom = "BigInt({})" +fromCustom = "{}.toString()" diff --git a/docs/breez-sdk/snippets/react-native/send_payment.ts b/docs/breez-sdk/snippets/react-native/send_payment.ts index b3376925..39eae1a9 100644 --- a/docs/breez-sdk/snippets/react-native/send_payment.ts +++ b/docs/breez-sdk/snippets/react-native/send_payment.ts @@ -14,7 +14,8 @@ const examplePrepareSendPaymentLightningBolt11 = async (sdk: BreezSdk) => { const prepareResponse = await sdk.prepareSendPayment({ paymentRequest, - amountSats: optionalAmountSats + amount: optionalAmountSats, + tokenIdentifier: undefined }) // If the fees are acceptable, continue to create the Send Payment @@ -37,7 +38,8 @@ const examplePrepareSendPaymentOnchain = async (sdk: BreezSdk) => { const prepareResponse = await sdk.prepareSendPayment({ paymentRequest, - amountSats + amount: amountSats, + tokenIdentifier: undefined }) // If the fees are acceptable, continue to create the Send Payment @@ -61,12 +63,13 @@ const examplePrepareSendPaymentSpark = async (sdk: BreezSdk) => { const prepareResponse = await sdk.prepareSendPayment({ paymentRequest, - amountSats + amount: amountSats, + tokenIdentifier: undefined }) // If the fees are acceptable, continue to create the Send Payment if (prepareResponse.paymentMethod instanceof SendPaymentMethod.SparkAddress) { - const feeSats = prepareResponse.paymentMethod.inner.feeSats + const feeSats = prepareResponse.paymentMethod.inner.fee console.debug(`Fees: ${feeSats} sats`) } // ANCHOR_END: prepare-send-payment-spark From e1a8ab0b6723d7daf8dc6270c2f869415e83f3d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Granh=C3=A3o?= Date: Tue, 7 Oct 2025 15:30:08 +0100 Subject: [PATCH 06/11] Golang support for custom u128 types --- crates/breez-sdk/common/uniffi.toml | 9 +++++++++ crates/breez-sdk/core/uniffi.toml | 9 +++++++++ docs/breez-sdk/snippets/go/send_payment.go | 15 ++++++++------- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/crates/breez-sdk/common/uniffi.toml b/crates/breez-sdk/common/uniffi.toml index d883d91c..674dedc4 100644 --- a/crates/breez-sdk/common/uniffi.toml +++ b/crates/breez-sdk/common/uniffi.toml @@ -34,3 +34,12 @@ from_custom = "str({})" typeName = "bigint" intoCustom = "BigInt({})" fromCustom = "{}.toString()" + +[bindings.go.custom_types.common_u128] +type_name = "*big.Int" +imports = [ "math/big" ] +into_custom = """ +result, _ := new(big.Int).SetString({}, 10) +return result +""" +from_custom = "{}.String()" \ No newline at end of file diff --git a/crates/breez-sdk/core/uniffi.toml b/crates/breez-sdk/core/uniffi.toml index 23b0cf9e..88c36237 100644 --- a/crates/breez-sdk/core/uniffi.toml +++ b/crates/breez-sdk/core/uniffi.toml @@ -34,3 +34,12 @@ from_custom = "str({})" typeName = "bigint" intoCustom = "BigInt({})" fromCustom = "{}.toString()" + +[bindings.go.custom_types.u128] +type_name = "*big.Int" +imports = [ "math/big" ] +into_custom = """ +result, _ := new(big.Int).SetString({}, 10) +return result +""" +from_custom = "{}.String()" diff --git a/docs/breez-sdk/snippets/go/send_payment.go b/docs/breez-sdk/snippets/go/send_payment.go index 6576cb8b..3a87b6ed 100644 --- a/docs/breez-sdk/snippets/go/send_payment.go +++ b/docs/breez-sdk/snippets/go/send_payment.go @@ -2,6 +2,7 @@ package example import ( "log" + "math/big" "github.com/breez/breez-sdk-spark-go/breez_sdk_spark" ) @@ -10,11 +11,11 @@ func PrepareSendPaymentLightningBolt11(sdk *breez_sdk_spark.BreezSdk) (*breez_sd // ANCHOR: prepare-send-payment-lightning-bolt11 paymentRequest := "" // Optionally set the amount you wish the pay the receiver - optionalAmountSats := uint64(5_000) + optionalAmountSats := new(big.Int).SetInt64(5_000) request := breez_sdk_spark.PrepareSendPaymentRequest{ PaymentRequest: paymentRequest, - AmountSats: &optionalAmountSats, + Amount: &optionalAmountSats, } response, err := sdk.PrepareSendPayment(request) @@ -40,11 +41,11 @@ func PrepareSendPaymentOnchain(sdk *breez_sdk_spark.BreezSdk) (*breez_sdk_spark. // ANCHOR: prepare-send-payment-onchain paymentRequest := "" // Set the amount you wish the pay the receiver - amountSats := uint64(50_000) + amountSats := new(big.Int).SetInt64(50_000) request := breez_sdk_spark.PrepareSendPaymentRequest{ PaymentRequest: paymentRequest, - AmountSats: &amountSats, + Amount: &amountSats, } response, err := sdk.PrepareSendPayment(request) @@ -71,11 +72,11 @@ func PrepareSendPaymentSpark(sdk *breez_sdk_spark.BreezSdk) (*breez_sdk_spark.Pr // ANCHOR: prepare-send-payment-spark paymentRequest := "" // Set the amount you wish the pay the receiver - amountSats := uint64(50_000) + amountSats := new(big.Int).SetInt64(50_000) request := breez_sdk_spark.PrepareSendPaymentRequest{ PaymentRequest: paymentRequest, - AmountSats: &amountSats, + Amount: &amountSats, } response, err := sdk.PrepareSendPayment(request) @@ -86,7 +87,7 @@ func PrepareSendPaymentSpark(sdk *breez_sdk_spark.BreezSdk) (*breez_sdk_spark.Pr // If the fees are acceptable, continue to create the Send Payment switch paymentMethod := response.PaymentMethod.(type) { case breez_sdk_spark.SendPaymentMethodSparkAddress: - feeSats := paymentMethod.FeeSats + feeSats := paymentMethod.Fee log.Printf("Fees: %v sats", feeSats) } // ANCHOR_END: prepare-send-payment-spark From 892b73aadeab8623031a7a551d35429cb17be43c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Granh=C3=A3o?= Date: Wed, 8 Oct 2025 14:34:32 +0100 Subject: [PATCH 07/11] Fix python snippet lints --- .../snippets/python/src/fiat_currencies.py | 28 +++++++++---------- .../snippets/python/src/getting_started.py | 2 +- .../snippets/python/src/lightning_address.py | 1 - .../snippets/python/src/receive_payment.py | 10 +++++-- .../snippets/python/src/send_payment.py | 6 ++-- 5 files changed, 26 insertions(+), 21 deletions(-) diff --git a/docs/breez-sdk/snippets/python/src/fiat_currencies.py b/docs/breez-sdk/snippets/python/src/fiat_currencies.py index 11a3ed0e..8650f019 100644 --- a/docs/breez-sdk/snippets/python/src/fiat_currencies.py +++ b/docs/breez-sdk/snippets/python/src/fiat_currencies.py @@ -1,19 +1,19 @@ from breez_sdk_spark import BreezSdk async def list_fiat_currencies(sdk: BreezSdk): - # ANCHOR: list-fiat-currencies - try: - response = await sdk.list_fiat_currencies() - except Exception as error: - print(error) - raise - # ANCHOR_END: list-fiat-currencies + # ANCHOR: list-fiat-currencies + try: + response = await sdk.list_fiat_currencies() + except Exception as error: + print(error) + raise + # ANCHOR_END: list-fiat-currencies async def list_fiat_rates(sdk: BreezSdk): - # ANCHOR: list-fiat-rates - try: - response = await sdk.list_fiat_rates() - except Exception as error: - print(error) - raise - # ANCHOR_END: list-fiat-rates + # ANCHOR: list-fiat-rates + try: + response = await sdk.list_fiat_rates() + except Exception as error: + print(error) + raise + # ANCHOR_END: list-fiat-rates diff --git a/docs/breez-sdk/snippets/python/src/getting_started.py b/docs/breez-sdk/snippets/python/src/getting_started.py index 93c60f96..019ab6d3 100644 --- a/docs/breez-sdk/snippets/python/src/getting_started.py +++ b/docs/breez-sdk/snippets/python/src/getting_started.py @@ -94,7 +94,7 @@ def set_logger(logger: SdkLogger): # ANCHOR: add-event-listener class SdkListener(EventListener): - async def on_event(self, event: SdkEvent): + def on_event(self, event: SdkEvent): logging.debug(f"Received event {event}") diff --git a/docs/breez-sdk/snippets/python/src/lightning_address.py b/docs/breez-sdk/snippets/python/src/lightning_address.py index da8c8f00..22577383 100644 --- a/docs/breez-sdk/snippets/python/src/lightning_address.py +++ b/docs/breez-sdk/snippets/python/src/lightning_address.py @@ -1,4 +1,3 @@ -import logging from breez_sdk_spark import ( BreezSdk, CheckLightningAddressRequest, diff --git a/docs/breez-sdk/snippets/python/src/receive_payment.py b/docs/breez-sdk/snippets/python/src/receive_payment.py index a425b9ad..d4715a01 100644 --- a/docs/breez-sdk/snippets/python/src/receive_payment.py +++ b/docs/breez-sdk/snippets/python/src/receive_payment.py @@ -1,5 +1,11 @@ import logging -from breez_sdk_spark import BreezSdk, ReceivePaymentMethod, ReceivePaymentRequest, WaitForPaymentRequest, WaitForPaymentIdentifier +from breez_sdk_spark import ( + BreezSdk, + ReceivePaymentMethod, + ReceivePaymentRequest, + WaitForPaymentRequest, + WaitForPaymentIdentifier, +) async def receive_lightning(sdk: BreezSdk): @@ -72,7 +78,7 @@ async def wait_for_payment(sdk: BreezSdk, payment_request: str): identifier=WaitForPaymentIdentifier.PAYMENT_REQUEST(payment_request) ) ) - + logging.debug(f"Payment received with ID: {response.payment.id}") return response.payment except Exception as error: diff --git a/docs/breez-sdk/snippets/python/src/send_payment.py b/docs/breez-sdk/snippets/python/src/send_payment.py index dd6d083f..c8fbf523 100644 --- a/docs/breez-sdk/snippets/python/src/send_payment.py +++ b/docs/breez-sdk/snippets/python/src/send_payment.py @@ -17,7 +17,7 @@ async def prepare_send_payment_lightning_bolt11(sdk: BreezSdk): optional_amount_sats = 5_000 try: request = PrepareSendPaymentRequest( - payment_request=payment_request, amount_sats=optional_amount_sats + payment_request=payment_request, amount=optional_amount_sats ) prepare_response = await sdk.prepare_send_payment(request=request) @@ -46,7 +46,7 @@ async def prepare_send_payment_onchain(sdk: BreezSdk): amount_sats = 50_000 try: request = PrepareSendPaymentRequest( - payment_request=payment_request, amount_sats=amount_sats + payment_request=payment_request, amount=amount_sats ) prepare_response = await sdk.prepare_send_payment(request=request) @@ -83,7 +83,7 @@ async def prepare_send_payment_spark(sdk: BreezSdk): amount_sats = 50_000 try: request = PrepareSendPaymentRequest( - payment_request=payment_request, amount_sats=amount_sats + payment_request=payment_request, amount=amount_sats ) prepare_response = await sdk.prepare_send_payment(request=request) From d4d9d260274397d1faf9a97bb8264343054c32c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Granh=C3=A3o?= Date: Wed, 8 Oct 2025 15:06:37 +0100 Subject: [PATCH 08/11] Fix flutter snippets --- docs/breez-sdk/snippets/flutter/lib/send_payment.dart | 8 ++++---- docs/breez-sdk/snippets/flutter/pubspec.lock | 10 ---------- docs/breez-sdk/snippets/flutter/pubspec.yaml | 2 -- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/docs/breez-sdk/snippets/flutter/lib/send_payment.dart b/docs/breez-sdk/snippets/flutter/lib/send_payment.dart index 455ad0a3..08dd78d3 100644 --- a/docs/breez-sdk/snippets/flutter/lib/send_payment.dart +++ b/docs/breez-sdk/snippets/flutter/lib/send_payment.dart @@ -8,7 +8,7 @@ Future prepareSendPaymentLightningBolt11( BigInt optionalAmountSats = BigInt.from(5000); final request = PrepareSendPaymentRequest( - paymentRequest: paymentRequest, amountSats: optionalAmountSats); + paymentRequest: paymentRequest, amount: optionalAmountSats); final response = await sdk.prepareSendPayment(request: request); // If the fees are acceptable, continue to create the Send Payment @@ -33,7 +33,7 @@ Future prepareSendPaymentOnchain( BigInt amountSats = BigInt.from(50000); final request = PrepareSendPaymentRequest( - paymentRequest: paymentRequest, amountSats: amountSats); + paymentRequest: paymentRequest, amount: amountSats); final response = await sdk.prepareSendPayment(request: request); // If the fees are acceptable, continue to create the Send Payment @@ -61,13 +61,13 @@ Future prepareSendPaymentSpark(BreezSdk sdk) async { BigInt amountSats = BigInt.from(50000); final request = PrepareSendPaymentRequest( - paymentRequest: paymentRequest, amountSats: amountSats); + paymentRequest: paymentRequest, amount: amountSats); final response = await sdk.prepareSendPayment(request: request); // If the fees are acceptable, continue to create the Send Payment final paymentMethod = response.paymentMethod; if (paymentMethod is SendPaymentMethod_SparkAddress) { - final feeSats = paymentMethod.feeSats; + final feeSats = paymentMethod.fee; print("Fees: $feeSats sats"); } // ANCHOR_END: prepare-send-payment-spark diff --git a/docs/breez-sdk/snippets/flutter/pubspec.lock b/docs/breez-sdk/snippets/flutter/pubspec.lock index 8a97b169..551065a9 100644 --- a/docs/breez-sdk/snippets/flutter/pubspec.lock +++ b/docs/breez-sdk/snippets/flutter/pubspec.lock @@ -128,11 +128,6 @@ packages: url: "https://pub.dev" source: hosted version: "7.0.1" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" flutter_rust_bridge: dependency: transitive description: @@ -450,11 +445,6 @@ packages: url: "https://pub.dev" source: hosted version: "3.0.0" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" source_map_stack_trace: dependency: transitive description: diff --git a/docs/breez-sdk/snippets/flutter/pubspec.yaml b/docs/breez-sdk/snippets/flutter/pubspec.yaml index e0e77bbf..0a1a5a88 100644 --- a/docs/breez-sdk/snippets/flutter/pubspec.yaml +++ b/docs/breez-sdk/snippets/flutter/pubspec.yaml @@ -8,8 +8,6 @@ environment: flutter: ">=3.27.0" dependencies: - flutter: - sdk: flutter flutter_secure_storage: ^6.0.0 app_group_directory: ^2.0.0 path_provider: ^2.0.0 From 13ce9ebfa405cac95e40f51d6ffd20f6b419ead9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Granh=C3=A3o?= Date: Wed, 8 Oct 2025 16:11:13 +0100 Subject: [PATCH 09/11] Fix kmp snippets and expose bignum depenency --- .../breez-sdk-spark-kmp/build.gradle.kts | 2 +- docs/breez-sdk/snippets/kotlin_mpp_lib/README.md | 14 +++++++++++++- .../kotlin_mpp_lib/gradle/libs.versions.toml | 2 +- .../snippets/kotlin_mpp_lib/settings.gradle.kts | 1 + .../com/example/kotlinmpplib/GettingStarted.kt | 8 ++++---- .../kotlin/com/example/kotlinmpplib/SendPayment.kt | 9 +++++---- 6 files changed, 25 insertions(+), 11 deletions(-) diff --git a/crates/breez-sdk/bindings/langs/kotlin-multiplatform/breez-sdk-spark-kmp/build.gradle.kts b/crates/breez-sdk/bindings/langs/kotlin-multiplatform/breez-sdk-spark-kmp/build.gradle.kts index 99c9ee46..8a9e4de8 100644 --- a/crates/breez-sdk/bindings/langs/kotlin-multiplatform/breez-sdk-spark-kmp/build.gradle.kts +++ b/crates/breez-sdk/bindings/langs/kotlin-multiplatform/breez-sdk-spark-kmp/build.gradle.kts @@ -66,7 +66,7 @@ kotlin { implementation("com.squareup.okio:okio:3.6.0") implementation("org.jetbrains.kotlinx:kotlinx-datetime:0.5.0") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0") - implementation("com.ionspin.kotlin:bignum:0.3.10") + api("com.ionspin.kotlin:bignum:0.3.10") } } diff --git a/docs/breez-sdk/snippets/kotlin_mpp_lib/README.md b/docs/breez-sdk/snippets/kotlin_mpp_lib/README.md index 705d7028..0619cec9 100644 --- a/docs/breez-sdk/snippets/kotlin_mpp_lib/README.md +++ b/docs/breez-sdk/snippets/kotlin_mpp_lib/README.md @@ -1,3 +1,14 @@ +## Steps to use a local version of the SDK + +```bash +cd ../../../../crates/breez-sdk/bindings +make package-kotlin-multiplatform +cd langs/kotlin-multiplatform +./gradlew publishToMavenLocal -PlibraryVersion= +``` + +Then set the version of the SDK in `gradle/libs.versions.toml` to the defined local version. + ## Steps to compile the snippets locally ```bash @@ -6,4 +17,5 @@ cd snippets/kotlin_mpp_lib/ ``` ## Nix -Use the command `nix develop` \ No newline at end of file + +Use the command `nix develop` diff --git a/docs/breez-sdk/snippets/kotlin_mpp_lib/gradle/libs.versions.toml b/docs/breez-sdk/snippets/kotlin_mpp_lib/gradle/libs.versions.toml index 385911e3..bf20bdc5 100644 --- a/docs/breez-sdk/snippets/kotlin_mpp_lib/gradle/libs.versions.toml +++ b/docs/breez-sdk/snippets/kotlin_mpp_lib/gradle/libs.versions.toml @@ -1,6 +1,6 @@ [versions] agp = "8.1.2" -breez = "0.1.3" +breez = "0.2.6" kotlin = "1.9.20" coroutines = "1.7.3" compose = "1.5.4" diff --git a/docs/breez-sdk/snippets/kotlin_mpp_lib/settings.gradle.kts b/docs/breez-sdk/snippets/kotlin_mpp_lib/settings.gradle.kts index d938ac38..9edc1da7 100644 --- a/docs/breez-sdk/snippets/kotlin_mpp_lib/settings.gradle.kts +++ b/docs/breez-sdk/snippets/kotlin_mpp_lib/settings.gradle.kts @@ -10,6 +10,7 @@ pluginManagement { dependencyResolutionManagement { // repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { + mavenLocal() // Allows to use local builds google() mavenCentral() maven("https://mvn.breez.technology/releases") diff --git a/docs/breez-sdk/snippets/kotlin_mpp_lib/shared/src/commonMain/kotlin/com/example/kotlinmpplib/GettingStarted.kt b/docs/breez-sdk/snippets/kotlin_mpp_lib/shared/src/commonMain/kotlin/com/example/kotlinmpplib/GettingStarted.kt index 6c66dd0f..dfb64605 100644 --- a/docs/breez-sdk/snippets/kotlin_mpp_lib/shared/src/commonMain/kotlin/com/example/kotlinmpplib/GettingStarted.kt +++ b/docs/breez-sdk/snippets/kotlin_mpp_lib/shared/src/commonMain/kotlin/com/example/kotlinmpplib/GettingStarted.kt @@ -82,12 +82,12 @@ class GettingStarted { // ANCHOR: add-event-listener class SdkListener : EventListener { - override fun onEvent(e: SdkEvent) { + override suspend fun onEvent(e: SdkEvent) { // Log.v("SDKListener", "Received event $e") } } - fun addEventListener(sdk: BreezSdk, listener: SdkListener): String? { + suspend fun addEventListener(sdk: BreezSdk, listener: SdkListener): String? { try { val listenerId = sdk.addEventListener(listener) return listenerId @@ -99,7 +99,7 @@ class GettingStarted { // ANCHOR_END: add-event-listener // ANCHOR: remove-event-listener - fun removeEventListener(sdk: BreezSdk, listenerId: String) { + suspend fun removeEventListener(sdk: BreezSdk, listenerId: String) { try { sdk.removeEventListener(listenerId) } catch (e: Exception) { @@ -109,7 +109,7 @@ class GettingStarted { // ANCHOR_END: remove-event-listener // ANCHOR: disconnect - fun disconnect(sdk: BreezSdk) { + suspend fun disconnect(sdk: BreezSdk) { try { sdk.disconnect() } catch (e: Exception) { diff --git a/docs/breez-sdk/snippets/kotlin_mpp_lib/shared/src/commonMain/kotlin/com/example/kotlinmpplib/SendPayment.kt b/docs/breez-sdk/snippets/kotlin_mpp_lib/shared/src/commonMain/kotlin/com/example/kotlinmpplib/SendPayment.kt index 25e3834f..16b06e69 100644 --- a/docs/breez-sdk/snippets/kotlin_mpp_lib/shared/src/commonMain/kotlin/com/example/kotlinmpplib/SendPayment.kt +++ b/docs/breez-sdk/snippets/kotlin_mpp_lib/shared/src/commonMain/kotlin/com/example/kotlinmpplib/SendPayment.kt @@ -1,13 +1,14 @@ package com.example.kotlinmpplib import breez_sdk_spark.* +import com.ionspin.kotlin.bignum.integer.BigInteger class SendPayment { suspend fun prepareSendPaymentLightningBolt11(sdk: BreezSdk) { // ANCHOR: prepare-send-payment-lightning-bolt11 val paymentRequest = "" // Optionally set the amount you wish the pay the receiver - val optionalAmountSats = 5_000UL + val optionalAmountSats = BigInteger.fromLong(5_000L) try { val req = PrepareSendPaymentRequest(paymentRequest, optionalAmountSats) val prepareResponse = sdk.prepareSendPayment(req) @@ -32,7 +33,7 @@ class SendPayment { // ANCHOR: prepare-send-payment-onchain val paymentRequest = "" // Set the amount you wish the pay the receiver - val amountSats = 50_000UL + val amountSats = BigInteger.fromLong(50_000L) try { val req = PrepareSendPaymentRequest(paymentRequest, amountSats) val prepareResponse = sdk.prepareSendPayment(req) @@ -58,7 +59,7 @@ class SendPayment { // ANCHOR: prepare-send-payment-spark val paymentRequest = "" // Set the amount you wish the pay the receiver - val amountSats = 50_000UL + val amountSats = BigInteger.fromLong(50_000L) try { val req = PrepareSendPaymentRequest(paymentRequest, amountSats) val prepareResponse = sdk.prepareSendPayment(req) @@ -66,7 +67,7 @@ class SendPayment { // If the fees are acceptable, continue to create the Send Payment val paymentMethod = prepareResponse.paymentMethod if (paymentMethod is SendPaymentMethod.SparkAddress) { - val feeSats = paymentMethod.feeSats + val feeSats = paymentMethod.fee // Log.v("Breez", "Fees: ${feeSats} sats") } } catch (e: Exception) { From d3266098f3652c961569a49b9f368c3f8684888e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Granh=C3=A3o?= Date: Wed, 8 Oct 2025 16:26:40 +0100 Subject: [PATCH 10/11] Fix wasm snippets --- .../breez-sdk/snippets/wasm/receive_payment.ts | 5 +---- docs/breez-sdk/snippets/wasm/send_payment.ts | 18 +++++++++--------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/docs/breez-sdk/snippets/wasm/receive_payment.ts b/docs/breez-sdk/snippets/wasm/receive_payment.ts index f52062a0..5c498f52 100644 --- a/docs/breez-sdk/snippets/wasm/receive_payment.ts +++ b/docs/breez-sdk/snippets/wasm/receive_payment.ts @@ -51,10 +51,7 @@ const exampleWaitForPayment = async (sdk: BreezSdk, paymentRequest: string) => { // ANCHOR: wait-for-payment // Wait for a payment to be completed using a payment request const response = await sdk.waitForPayment({ - identifier: { - type: 'paymentRequest', - paymentRequest: paymentRequest - } + identifier: paymentRequest as { type: 'paymentRequest' } & string }) console.log(`Payment received with ID: ${response.payment.id}`) diff --git a/docs/breez-sdk/snippets/wasm/send_payment.ts b/docs/breez-sdk/snippets/wasm/send_payment.ts index 5d803e6c..a8384af0 100644 --- a/docs/breez-sdk/snippets/wasm/send_payment.ts +++ b/docs/breez-sdk/snippets/wasm/send_payment.ts @@ -8,11 +8,11 @@ const examplePrepareSendPaymentLightningBolt11 = async (sdk: BreezSdk) => { // ANCHOR: prepare-send-payment-lightning-bolt11 const paymentRequest = '' // Optionally set the amount you wish the pay the receiver - const optionalAmountSats = 5_000 + const optionalAmountSats = BigInt(5_000) const prepareResponse = await sdk.prepareSendPayment({ paymentRequest, - amountSats: optionalAmountSats + amount: optionalAmountSats }) // If the fees are acceptable, continue to create the Send Payment @@ -31,11 +31,11 @@ const examplePrepareSendPaymentOnchain = async (sdk: BreezSdk) => { // ANCHOR: prepare-send-payment-onchain const paymentRequest = '' // Set the amount you wish the pay the receiver - const amountSats = 50_000 + const amountSats = BigInt(50_000) const prepareResponse = await sdk.prepareSendPayment({ paymentRequest, - amountSats + amount: amountSats }) // If the fees are acceptable, continue to create the Send Payment @@ -55,16 +55,16 @@ const examplePrepareSendPaymentSpark = async (sdk: BreezSdk) => { // ANCHOR: prepare-send-payment-spark const paymentRequest = '' // Set the amount you wish the pay the receiver - const amountSats = 50_000 + const amountSats = BigInt(50_000) const prepareResponse = await sdk.prepareSendPayment({ paymentRequest, - amountSats + amount: amountSats }) // If the fees are acceptable, continue to create the Send Payment if (prepareResponse.paymentMethod.type === 'sparkAddress') { - const feeSats = prepareResponse.paymentMethod.feeSats + const feeSats = prepareResponse.paymentMethod.fee console.debug(`Fees: ${feeSats} sats`) } // ANCHOR_END: prepare-send-payment-spark @@ -75,8 +75,8 @@ const exampleSendPaymentLightningBolt11 = async ( prepareResponse: PrepareSendPaymentResponse ) => { // ANCHOR: send-payment-lightning-bolt11 - const options: SendPaymentOptions = { - type: 'bolt11Invoice', + const options: SendPaymentOptions = { + type: 'bolt11Invoice', preferSpark: true, completionTimeoutSecs: 10 } From adc7ce60e5cec906458347804f8a8aa514d73cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Granh=C3=A3o?= <32176319+danielgranhao@users.noreply.github.com> Date: Wed, 8 Oct 2025 18:33:41 +0100 Subject: [PATCH 11/11] Fix typo Co-authored-by: Ross Savage <551697+dangeross@users.noreply.github.com> --- crates/breez-sdk/wasm/src/models.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/breez-sdk/wasm/src/models.rs b/crates/breez-sdk/wasm/src/models.rs index e8dd8a41..eac0703a 100644 --- a/crates/breez-sdk/wasm/src/models.rs +++ b/crates/breez-sdk/wasm/src/models.rs @@ -537,7 +537,7 @@ pub struct TokenMetadata { pub name: String, pub ticker: String, pub decimals: u32, - // Serde doesn't support deserializing u128 types whenever they are user with flatten: https://github.com/serde-rs/json/issues/625 + // Serde doesn't support deserializing u128 types whenever they are used with flatten: https://github.com/serde-rs/json/issues/625 // This occurs in the storage implementation when parsing `PaymentDetails` due to the use of flatten in LnurlRequestDetails // Serializing as string is a workaround to avoid the issue. #[serde(with = "serde_u128_as_string")]