From 4608d78972f6b8b0c51d03b22415ed9965719edb Mon Sep 17 00:00:00 2001 From: Daniel <111755602+cnixbtc@users.noreply.github.com> Date: Thu, 31 Aug 2023 22:30:46 +0200 Subject: [PATCH 01/48] Update publish-android.yml --- .github/workflows/publish-android.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-android.yml b/.github/workflows/publish-android.yml index ef95e3b5f..e7a4b2b36 100644 --- a/.github/workflows/publish-android.yml +++ b/.github/workflows/publish-android.yml @@ -74,5 +74,5 @@ jobs: # We're sleeping for 30s before triggering the Jitpack build to give our Maven repo # some time to process the just uploaded files (the Jitpack build is dependent upon them being available). # If anything fails here, we'll still finish sucessfully as this is an optional optimization. - sleep 30s + sleep 60s curl -s -m 30 https://jitpack.io/api/builds/com.github.breez/breez-sdk/${{ inputs.package-version }} || true From 21b5526db18ed6f9ce03351d2b0986acedb4a6e3 Mon Sep 17 00:00:00 2001 From: Dominic Leutenegger Date: Fri, 13 Oct 2023 09:44:05 +0200 Subject: [PATCH 02/48] Extend payment type filter to include `ClosedChannels` type --- libs/sdk-bindings/src/breez_sdk.udl | 3 +- libs/sdk-core/src/breez_services.rs | 6 +- libs/sdk-core/src/bridge_generated.io.rs | 31 +++++++++- libs/sdk-core/src/bridge_generated.rs | 3 +- libs/sdk-core/src/models.rs | 6 +- libs/sdk-core/src/persist/transactions.rs | 58 ++++++++++++------- .../ios/Classes/bridge_generated.h | 10 +++- libs/sdk-flutter/lib/bridge_generated.dart | 40 +++++++++++-- .../main/java/com/breezsdk/BreezSDKMapper.kt | 9 +-- .../sdk-react-native/ios/BreezSDKMapper.swift | 14 +++-- libs/sdk-react-native/src/index.ts | 3 +- tools/sdk-cli/src/command_handlers.rs | 2 +- 12 files changed, 137 insertions(+), 48 deletions(-) diff --git a/libs/sdk-bindings/src/breez_sdk.udl b/libs/sdk-bindings/src/breez_sdk.udl index 3ddf7afbf..3b4e601f6 100644 --- a/libs/sdk-bindings/src/breez_sdk.udl +++ b/libs/sdk-bindings/src/breez_sdk.udl @@ -121,6 +121,7 @@ dictionary CheckMessageResponse { enum PaymentTypeFilter { "Sent", "Received", + "ClosedChannels", "All", }; @@ -148,7 +149,7 @@ dictionary Payment { }; dictionary ListPaymentsRequest { - PaymentTypeFilter filter; + sequence filters; i64? from_timestamp = null; i64? to_timestamp = null; boolean? include_failures = null; diff --git a/libs/sdk-core/src/breez_services.rs b/libs/sdk-core/src/breez_services.rs index eea1ce4e1..cddd622fa 100644 --- a/libs/sdk-core/src/breez_services.rs +++ b/libs/sdk-core/src/breez_services.rs @@ -2032,7 +2032,7 @@ pub(crate) mod tests { let all = breez_services .list_payments(ListPaymentsRequest { - filter: PaymentTypeFilter::All, + filters: vec![PaymentTypeFilter::All], from_timestamp: None, to_timestamp: None, include_failures: None, @@ -2048,7 +2048,7 @@ pub(crate) mod tests { let received = breez_services .list_payments(ListPaymentsRequest { - filter: PaymentTypeFilter::Received, + filters: vec![PaymentTypeFilter::Received], from_timestamp: None, to_timestamp: None, include_failures: None, @@ -2060,7 +2060,7 @@ pub(crate) mod tests { let sent = breez_services .list_payments(ListPaymentsRequest { - filter: PaymentTypeFilter::Sent, + filters: vec![PaymentTypeFilter::Sent, PaymentTypeFilter::ClosedChannels], from_timestamp: None, to_timestamp: None, include_failures: None, diff --git a/libs/sdk-core/src/bridge_generated.io.rs b/libs/sdk-core/src/bridge_generated.io.rs index 6cb589ad4..b92ed3e0c 100644 --- a/libs/sdk-core/src/bridge_generated.io.rs +++ b/libs/sdk-core/src/bridge_generated.io.rs @@ -363,6 +363,15 @@ pub extern "C" fn new_box_autoadd_u64_0(value: u64) -> *mut u64 { support::new_leak_box_ptr(value) } +#[no_mangle] +pub extern "C" fn new_list_payment_type_filter_0(len: i32) -> *mut wire_list_payment_type_filter { + let wrap = wire_list_payment_type_filter { + ptr: support::new_leak_vec_ptr(Default::default(), len), + len, + }; + support::new_leak_box_ptr(wrap) +} + #[no_mangle] pub extern "C" fn new_uint_8_list_0(len: i32) -> *mut wire_uint_8_list { let ans = wire_uint_8_list { @@ -587,10 +596,19 @@ impl Wire2Api for wire_GreenlightNodeConfig { } } +impl Wire2Api> for *mut wire_list_payment_type_filter { + fn wire2api(self) -> Vec { + let vec = unsafe { + let wrap = support::box_from_leak_ptr(self); + support::vec_from_leak_ptr(wrap.ptr, wrap.len) + }; + vec.into_iter().map(Wire2Api::wire2api).collect() + } +} impl Wire2Api for wire_ListPaymentsRequest { fn wire2api(self) -> ListPaymentsRequest { ListPaymentsRequest { - filter: self.filter.wire2api(), + filters: self.filters.wire2api(), from_timestamp: self.from_timestamp.wire2api(), to_timestamp: self.to_timestamp.wire2api(), include_failures: self.include_failures.wire2api(), @@ -826,10 +844,17 @@ pub struct wire_GreenlightNodeConfig { invite_code: *mut wire_uint_8_list, } +#[repr(C)] +#[derive(Clone)] +pub struct wire_list_payment_type_filter { + ptr: *mut i32, + len: i32, +} + #[repr(C)] #[derive(Clone)] pub struct wire_ListPaymentsRequest { - filter: i32, + filters: *mut wire_list_payment_type_filter, from_timestamp: *mut i64, to_timestamp: *mut i64, include_failures: *mut bool, @@ -1100,7 +1125,7 @@ impl Default for wire_GreenlightNodeConfig { impl NewWithNullPtr for wire_ListPaymentsRequest { fn new_with_null_ptr() -> Self { Self { - filter: Default::default(), + filters: core::ptr::null_mut(), from_timestamp: core::ptr::null_mut(), to_timestamp: core::ptr::null_mut(), include_failures: core::ptr::null_mut(), diff --git a/libs/sdk-core/src/bridge_generated.rs b/libs/sdk-core/src/bridge_generated.rs index 4668af7bc..3c2a7fe4a 100644 --- a/libs/sdk-core/src/bridge_generated.rs +++ b/libs/sdk-core/src/bridge_generated.rs @@ -744,7 +744,8 @@ impl Wire2Api for i32 { match self { 0 => PaymentTypeFilter::Sent, 1 => PaymentTypeFilter::Received, - 2 => PaymentTypeFilter::All, + 2 => PaymentTypeFilter::ClosedChannels, + 3 => PaymentTypeFilter::All, _ => unreachable!("Invalid variant for PaymentTypeFilter: {}", self), } } diff --git a/libs/sdk-core/src/models.rs b/libs/sdk-core/src/models.rs index ec55ffd58..7864b2a32 100644 --- a/libs/sdk-core/src/models.rs +++ b/libs/sdk-core/src/models.rs @@ -38,7 +38,7 @@ pub const SWAP_PAYMENT_FEE_EXPIRY_SECONDS: u32 = 60 * 60 * 24 * 2; // 2 days pub const INVOICE_PAYMENT_FEE_EXPIRY_SECONDS: u32 = 60 * 60; // 60 minutes /// Different types of supported payments -#[derive(Clone, PartialEq, Eq, Debug, EnumString, Display, Deserialize, Serialize)] +#[derive(Clone, PartialEq, Eq, Debug, EnumString, Display, Deserialize, Serialize, Hash)] pub enum PaymentType { Sent, Received, @@ -576,9 +576,11 @@ impl From for bitcoin::network::constants::Network { } /// Different types of supported filters which can be applied when retrieving the transaction list +#[derive(PartialEq)] pub enum PaymentTypeFilter { Sent, Received, + ClosedChannels, All, } @@ -656,7 +658,7 @@ pub struct Payment { /// Represents a list payments request. pub struct ListPaymentsRequest { - pub filter: PaymentTypeFilter, + pub filters: Vec, pub from_timestamp: Option, pub to_timestamp: Option, pub include_failures: Option, diff --git a/libs/sdk-core/src/persist/transactions.rs b/libs/sdk-core/src/persist/transactions.rs index a24140756..99132b4c0 100644 --- a/libs/sdk-core/src/persist/transactions.rs +++ b/libs/sdk-core/src/persist/transactions.rs @@ -6,6 +6,7 @@ use anyhow::{anyhow, Result}; use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ToSql, ToSqlOutput, ValueRef}; use rusqlite::Row; use rusqlite::{params, OptionalExtension}; +use std::collections::HashSet; use std::str::FromStr; @@ -133,7 +134,7 @@ impl SqliteStorage { /// or [Self::get_completed_payment_by_hash] pub fn list_payments(&self, req: ListPaymentsRequest) -> SdkResult> { let where_clause = filter_to_where_clause( - req.filter, + req.filters, req.from_timestamp, req.to_timestamp, req.include_failures, @@ -262,7 +263,7 @@ impl SqliteStorage { } fn filter_to_where_clause( - type_filter: PaymentTypeFilter, + type_filters: Vec, from_timestamp: Option, to_timestamp: Option, include_failures: Option, @@ -280,18 +281,31 @@ fn filter_to_where_clause( where_clause.push(format!("status != {}", PaymentStatus::Failed as i64)); }; - match type_filter { - PaymentTypeFilter::Sent => { - where_clause.push(format!( - "payment_type in ('{}','{}') ", - PaymentType::Sent, - PaymentType::ClosedChannel - )); + if !type_filters.contains(&PaymentTypeFilter::All) { + let mut type_filter_clause: HashSet = HashSet::new(); + for type_filter in type_filters { + match type_filter { + PaymentTypeFilter::Sent => { + type_filter_clause.insert(PaymentType::Sent); + } + PaymentTypeFilter::Received => { + type_filter_clause.insert(PaymentType::Received); + } + PaymentTypeFilter::ClosedChannels => { + type_filter_clause.insert(PaymentType::ClosedChannel); + } + _ => {} + } } - PaymentTypeFilter::Received => { - where_clause.push(format!("payment_type = '{}' ", PaymentType::Received)); - } - PaymentTypeFilter::All => (), + + where_clause.push(format!( + "payment_type in ({})", + type_filter_clause + .iter() + .map(|t| format!("'{}'", t)) + .collect::>() + .join(", ") + )); } let mut where_clause_str = String::new(); @@ -460,7 +474,7 @@ fn test_ln_transactions() -> Result<(), Box> { // retrieve all let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filter: PaymentTypeFilter::All, + filters: vec![PaymentTypeFilter::All], from_timestamp: None, to_timestamp: None, include_failures: None, @@ -472,7 +486,7 @@ fn test_ln_transactions() -> Result<(), Box> { //test only sent let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filter: PaymentTypeFilter::Sent, + filters: vec![PaymentTypeFilter::Sent, PaymentTypeFilter::ClosedChannels], from_timestamp: None, to_timestamp: None, include_failures: None, @@ -490,7 +504,7 @@ fn test_ln_transactions() -> Result<(), Box> { //test only received let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filter: PaymentTypeFilter::Received, + filters: vec![PaymentTypeFilter::Received], from_timestamp: None, to_timestamp: None, include_failures: None, @@ -505,7 +519,7 @@ fn test_ln_transactions() -> Result<(), Box> { storage.insert_or_update_payments(&txs)?; let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filter: PaymentTypeFilter::All, + filters: vec![PaymentTypeFilter::All], from_timestamp: None, to_timestamp: None, include_failures: None, @@ -517,7 +531,7 @@ fn test_ln_transactions() -> Result<(), Box> { storage.insert_open_channel_payment_info("123", 150)?; let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filter: PaymentTypeFilter::All, + filters: vec![PaymentTypeFilter::All], from_timestamp: None, to_timestamp: None, include_failures: None, @@ -528,7 +542,7 @@ fn test_ln_transactions() -> Result<(), Box> { // test all with failures let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filter: PaymentTypeFilter::All, + filters: vec![PaymentTypeFilter::All], from_timestamp: None, to_timestamp: None, include_failures: Some(true), @@ -539,7 +553,7 @@ fn test_ln_transactions() -> Result<(), Box> { // test sent with failures let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filter: PaymentTypeFilter::Sent, + filters: vec![PaymentTypeFilter::Sent, PaymentTypeFilter::ClosedChannels], from_timestamp: None, to_timestamp: None, include_failures: Some(true), @@ -550,7 +564,7 @@ fn test_ln_transactions() -> Result<(), Box> { // test limit let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filter: PaymentTypeFilter::All, + filters: vec![PaymentTypeFilter::All], from_timestamp: None, to_timestamp: None, include_failures: Some(false), @@ -561,7 +575,7 @@ fn test_ln_transactions() -> Result<(), Box> { // test offset let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filter: PaymentTypeFilter::All, + filters: vec![PaymentTypeFilter::All], from_timestamp: None, to_timestamp: None, include_failures: Some(false), diff --git a/libs/sdk-flutter/ios/Classes/bridge_generated.h b/libs/sdk-flutter/ios/Classes/bridge_generated.h index 228c80c17..8903ad31a 100644 --- a/libs/sdk-flutter/ios/Classes/bridge_generated.h +++ b/libs/sdk-flutter/ios/Classes/bridge_generated.h @@ -72,8 +72,13 @@ typedef struct wire_StaticBackupRequest { struct wire_uint_8_list *working_dir; } wire_StaticBackupRequest; +typedef struct wire_list_payment_type_filter { + int32_t *ptr; + int32_t len; +} wire_list_payment_type_filter; + typedef struct wire_ListPaymentsRequest { - int32_t filter; + struct wire_list_payment_type_filter *filters; int64_t *from_timestamp; int64_t *to_timestamp; bool *include_failures; @@ -338,6 +343,8 @@ uint32_t *new_box_autoadd_u32_0(uint32_t value); uint64_t *new_box_autoadd_u64_0(uint64_t value); +struct wire_list_payment_type_filter *new_list_payment_type_filter_0(int32_t len); + struct wire_uint_8_list *new_uint_8_list_0(int32_t len); union NodeConfigKind *inflate_NodeConfig_Greenlight(void); @@ -416,6 +423,7 @@ static int64_t dummy_method_to_enforce_bundling(void) { dummy_var ^= ((int64_t) (void*) new_box_autoadd_sweep_request_0); dummy_var ^= ((int64_t) (void*) new_box_autoadd_u32_0); dummy_var ^= ((int64_t) (void*) new_box_autoadd_u64_0); + dummy_var ^= ((int64_t) (void*) new_list_payment_type_filter_0); dummy_var ^= ((int64_t) (void*) new_uint_8_list_0); dummy_var ^= ((int64_t) (void*) inflate_NodeConfig_Greenlight); dummy_var ^= ((int64_t) (void*) free_WireSyncReturn); diff --git a/libs/sdk-flutter/lib/bridge_generated.dart b/libs/sdk-flutter/lib/bridge_generated.dart index 4ff4b2037..926aefc89 100644 --- a/libs/sdk-flutter/lib/bridge_generated.dart +++ b/libs/sdk-flutter/lib/bridge_generated.dart @@ -571,7 +571,7 @@ class InvoicePaidDetails { /// Represents a list payments request. class ListPaymentsRequest { - final PaymentTypeFilter filter; + final List filters; final int? fromTimestamp; final int? toTimestamp; final bool? includeFailures; @@ -579,7 +579,7 @@ class ListPaymentsRequest { final int? limit; const ListPaymentsRequest({ - required this.filter, + required this.filters, this.fromTimestamp, this.toTimestamp, this.includeFailures, @@ -1096,6 +1096,7 @@ enum PaymentType { enum PaymentTypeFilter { Sent, Received, + ClosedChannels, All, } @@ -3523,6 +3524,15 @@ class BreezSdkCorePlatform extends FlutterRustBridgeBase { return raw; } + @protected + ffi.Pointer api2wire_list_payment_type_filter(List raw) { + final ans = inner.new_list_payment_type_filter_0(raw.length); + for (var i = 0; i < raw.length; ++i) { + ans.ref.ptr[i] = api2wire_payment_type_filter(raw[i]); + } + return ans; + } + @protected ffi.Pointer api2wire_opt_String(String? raw) { return raw == null ? ffi.nullptr : api2wire_String(raw); @@ -3724,7 +3734,7 @@ class BreezSdkCorePlatform extends FlutterRustBridgeBase { } void _api_fill_to_wire_list_payments_request(ListPaymentsRequest apiObj, wire_ListPaymentsRequest wireObj) { - wireObj.filter = api2wire_payment_type_filter(apiObj.filter); + wireObj.filters = api2wire_list_payment_type_filter(apiObj.filters); wireObj.from_timestamp = api2wire_opt_box_autoadd_i64(apiObj.fromTimestamp); wireObj.to_timestamp = api2wire_opt_box_autoadd_i64(apiObj.toTimestamp); wireObj.include_failures = api2wire_opt_box_autoadd_bool(apiObj.includeFailures); @@ -4854,6 +4864,20 @@ class BreezSdkCoreWire implements FlutterRustBridgeWireBase { late final _new_box_autoadd_u64_0 = _new_box_autoadd_u64_0Ptr.asFunction Function(int)>(); + ffi.Pointer new_list_payment_type_filter_0( + int len, + ) { + return _new_list_payment_type_filter_0( + len, + ); + } + + late final _new_list_payment_type_filter_0Ptr = + _lookup Function(ffi.Int32)>>( + 'new_list_payment_type_filter_0'); + late final _new_list_payment_type_filter_0 = _new_list_payment_type_filter_0Ptr + .asFunction Function(int)>(); + ffi.Pointer new_uint_8_list_0( int len, ) { @@ -4967,9 +4991,15 @@ class wire_StaticBackupRequest extends ffi.Struct { external ffi.Pointer working_dir; } -class wire_ListPaymentsRequest extends ffi.Struct { +class wire_list_payment_type_filter extends ffi.Struct { + external ffi.Pointer ptr; + @ffi.Int32() - external int filter; + external int len; +} + +class wire_ListPaymentsRequest extends ffi.Struct { + external ffi.Pointer filters; external ffi.Pointer from_timestamp; diff --git a/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt b/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt index a576ee312..5735dad4f 100644 --- a/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt +++ b/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt @@ -727,13 +727,13 @@ fun asListPaymentsRequest(listPaymentsRequest: ReadableMap): ListPaymentsRequest if (!validateMandatoryFields( listPaymentsRequest, arrayOf( - "filter", + "filters", ), ) ) { return null } - val filter = listPaymentsRequest.getString("filter")?.let { asPaymentTypeFilter(it) }!! + val filters = listPaymentsRequest.getArray("filters")?.let { asPaymentTypeFilterList(it) }!! val fromTimestamp = if (hasNonNullKey( listPaymentsRequest, @@ -758,7 +758,7 @@ fun asListPaymentsRequest(listPaymentsRequest: ReadableMap): ListPaymentsRequest val offset = if (hasNonNullKey(listPaymentsRequest, "offset")) listPaymentsRequest.getInt("offset").toUInt() else null val limit = if (hasNonNullKey(listPaymentsRequest, "limit")) listPaymentsRequest.getInt("limit").toUInt() else null return ListPaymentsRequest( - filter, + filters, fromTimestamp, toTimestamp, includeFailures, @@ -769,7 +769,7 @@ fun asListPaymentsRequest(listPaymentsRequest: ReadableMap): ListPaymentsRequest fun readableMapOf(listPaymentsRequest: ListPaymentsRequest): ReadableMap { return readableMapOf( - "filter" to listPaymentsRequest.filter.name.lowercase(), + "filters" to readableArrayOf(listPaymentsRequest.filters), "fromTimestamp" to listPaymentsRequest.fromTimestamp, "toTimestamp" to listPaymentsRequest.toTimestamp, "includeFailures" to listPaymentsRequest.includeFailures, @@ -3370,6 +3370,7 @@ fun pushToArray( is LspInformation -> array.pushMap(readableMapOf(value)) is OpeningFeeParams -> array.pushMap(readableMapOf(value)) is Payment -> array.pushMap(readableMapOf(value)) + is PaymentTypeFilter -> array.pushMap(readableMapOf(value)) is Rate -> array.pushMap(readableMapOf(value)) is ReverseSwapInfo -> array.pushMap(readableMapOf(value)) is RouteHint -> array.pushMap(readableMapOf(value)) diff --git a/libs/sdk-react-native/ios/BreezSDKMapper.swift b/libs/sdk-react-native/ios/BreezSDKMapper.swift index f2c9f4ecd..2001dba16 100644 --- a/libs/sdk-react-native/ios/BreezSDKMapper.swift +++ b/libs/sdk-react-native/ios/BreezSDKMapper.swift @@ -657,8 +657,8 @@ class BreezSDKMapper { } static func asListPaymentsRequest(listPaymentsRequest: [String: Any?]) throws -> ListPaymentsRequest { - guard let filterTmp = listPaymentsRequest["filter"] as? String else { throw SdkError.Generic(message: "Missing mandatory field filter for type ListPaymentsRequest") } - let filter = try asPaymentTypeFilter(paymentTypeFilter: filterTmp) + guard let filtersTmp = listPaymentsRequest["filters"] as? [String] else { throw SdkError.Generic(message: "Missing mandatory field filters for type ListPaymentsRequest") } + let filters = filtersTmp let fromTimestamp = listPaymentsRequest["fromTimestamp"] as? Int64 let toTimestamp = listPaymentsRequest["toTimestamp"] as? Int64 @@ -667,7 +667,7 @@ class BreezSDKMapper { let limit = listPaymentsRequest["limit"] as? UInt32 return ListPaymentsRequest( - filter: filter, + filters: filters, fromTimestamp: fromTimestamp, toTimestamp: toTimestamp, includeFailures: includeFailures, @@ -678,7 +678,7 @@ class BreezSDKMapper { static func dictionaryOf(listPaymentsRequest: ListPaymentsRequest) -> [String: Any?] { return [ - "filter": valueOf(paymentTypeFilter: listPaymentsRequest.filter), + "filters": arrayOf(paymentTypeFilterList: listPaymentsRequest.filters), "fromTimestamp": listPaymentsRequest.fromTimestamp == nil ? nil : listPaymentsRequest.fromTimestamp, "toTimestamp": listPaymentsRequest.toTimestamp == nil ? nil : listPaymentsRequest.toTimestamp, "includeFailures": listPaymentsRequest.includeFailures == nil ? nil : listPaymentsRequest.includeFailures, @@ -3219,6 +3219,9 @@ class BreezSDKMapper { case "received": return PaymentTypeFilter.received + case "closedChannels": + return PaymentTypeFilter.closedChannels + case "all": return PaymentTypeFilter.all @@ -3234,6 +3237,9 @@ class BreezSDKMapper { case .received: return "received" + case .closedChannels: + return "closedChannels" + case .all: return "all" } diff --git a/libs/sdk-react-native/src/index.ts b/libs/sdk-react-native/src/index.ts index ecd3b4fdb..9dd1501d0 100644 --- a/libs/sdk-react-native/src/index.ts +++ b/libs/sdk-react-native/src/index.ts @@ -125,7 +125,7 @@ export type LnInvoice = { } export type ListPaymentsRequest = { - filter: PaymentTypeFilter + filters: PaymentTypeFilter[] fromTimestamp?: number toTimestamp?: number includeFailures?: boolean @@ -635,6 +635,7 @@ export enum PaymentType { export enum PaymentTypeFilter { SENT = "sent", RECEIVED = "received", + CLOSED_CHANNELS = "closedChannels", ALL = "all" } diff --git a/tools/sdk-cli/src/command_handlers.rs b/tools/sdk-cli/src/command_handlers.rs index c64a33d27..30e448e5c 100644 --- a/tools/sdk-cli/src/command_handlers.rs +++ b/tools/sdk-cli/src/command_handlers.rs @@ -216,7 +216,7 @@ pub(crate) async fn handle_command( } => { let payments = sdk()? .list_payments(ListPaymentsRequest { - filter: PaymentTypeFilter::All, + filters: vec![PaymentTypeFilter::All], from_timestamp, to_timestamp, include_failures: Some(include_failures), From bc9462fe2374f5a4ba8f39d9a4221ef31ec311d1 Mon Sep 17 00:00:00 2001 From: Dominic Leutenegger Date: Mon, 23 Oct 2023 09:30:32 +0200 Subject: [PATCH 03/48] Remove payment type filter `All` --- libs/sdk-bindings/src/breez_sdk.udl | 1 - libs/sdk-core/src/breez_services.rs | 2 +- libs/sdk-core/src/bridge_generated.rs | 1 - libs/sdk-core/src/models.rs | 1 - libs/sdk-core/src/persist/transactions.rs | 15 +++++++-------- libs/sdk-flutter/lib/bridge_generated.dart | 1 - libs/sdk-react-native/ios/BreezSDKMapper.swift | 6 ------ libs/sdk-react-native/src/index.ts | 3 +-- tools/sdk-cli/src/command_handlers.rs | 8 ++++---- 9 files changed, 13 insertions(+), 25 deletions(-) diff --git a/libs/sdk-bindings/src/breez_sdk.udl b/libs/sdk-bindings/src/breez_sdk.udl index 3b4e601f6..40b890143 100644 --- a/libs/sdk-bindings/src/breez_sdk.udl +++ b/libs/sdk-bindings/src/breez_sdk.udl @@ -122,7 +122,6 @@ enum PaymentTypeFilter { "Sent", "Received", "ClosedChannels", - "All", }; enum PaymentStatus { diff --git a/libs/sdk-core/src/breez_services.rs b/libs/sdk-core/src/breez_services.rs index cddd622fa..5833082f0 100644 --- a/libs/sdk-core/src/breez_services.rs +++ b/libs/sdk-core/src/breez_services.rs @@ -2032,7 +2032,7 @@ pub(crate) mod tests { let all = breez_services .list_payments(ListPaymentsRequest { - filters: vec![PaymentTypeFilter::All], + filters: vec![], from_timestamp: None, to_timestamp: None, include_failures: None, diff --git a/libs/sdk-core/src/bridge_generated.rs b/libs/sdk-core/src/bridge_generated.rs index 3c2a7fe4a..3c572e806 100644 --- a/libs/sdk-core/src/bridge_generated.rs +++ b/libs/sdk-core/src/bridge_generated.rs @@ -745,7 +745,6 @@ impl Wire2Api for i32 { 0 => PaymentTypeFilter::Sent, 1 => PaymentTypeFilter::Received, 2 => PaymentTypeFilter::ClosedChannels, - 3 => PaymentTypeFilter::All, _ => unreachable!("Invalid variant for PaymentTypeFilter: {}", self), } } diff --git a/libs/sdk-core/src/models.rs b/libs/sdk-core/src/models.rs index 7864b2a32..3cf238828 100644 --- a/libs/sdk-core/src/models.rs +++ b/libs/sdk-core/src/models.rs @@ -581,7 +581,6 @@ pub enum PaymentTypeFilter { Sent, Received, ClosedChannels, - All, } /// Different types of supported feerates diff --git a/libs/sdk-core/src/persist/transactions.rs b/libs/sdk-core/src/persist/transactions.rs index 99132b4c0..ad1b3ba0f 100644 --- a/libs/sdk-core/src/persist/transactions.rs +++ b/libs/sdk-core/src/persist/transactions.rs @@ -281,7 +281,7 @@ fn filter_to_where_clause( where_clause.push(format!("status != {}", PaymentStatus::Failed as i64)); }; - if !type_filters.contains(&PaymentTypeFilter::All) { + if !type_filters.is_empty() { let mut type_filter_clause: HashSet = HashSet::new(); for type_filter in type_filters { match type_filter { @@ -294,7 +294,6 @@ fn filter_to_where_clause( PaymentTypeFilter::ClosedChannels => { type_filter_clause.insert(PaymentType::ClosedChannel); } - _ => {} } } @@ -474,7 +473,7 @@ fn test_ln_transactions() -> Result<(), Box> { // retrieve all let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: vec![PaymentTypeFilter::All], + filters: vec![], from_timestamp: None, to_timestamp: None, include_failures: None, @@ -519,7 +518,7 @@ fn test_ln_transactions() -> Result<(), Box> { storage.insert_or_update_payments(&txs)?; let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: vec![PaymentTypeFilter::All], + filters: vec![], from_timestamp: None, to_timestamp: None, include_failures: None, @@ -531,7 +530,7 @@ fn test_ln_transactions() -> Result<(), Box> { storage.insert_open_channel_payment_info("123", 150)?; let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: vec![PaymentTypeFilter::All], + filters: vec![], from_timestamp: None, to_timestamp: None, include_failures: None, @@ -542,7 +541,7 @@ fn test_ln_transactions() -> Result<(), Box> { // test all with failures let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: vec![PaymentTypeFilter::All], + filters: vec![], from_timestamp: None, to_timestamp: None, include_failures: Some(true), @@ -564,7 +563,7 @@ fn test_ln_transactions() -> Result<(), Box> { // test limit let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: vec![PaymentTypeFilter::All], + filters: vec![], from_timestamp: None, to_timestamp: None, include_failures: Some(false), @@ -575,7 +574,7 @@ fn test_ln_transactions() -> Result<(), Box> { // test offset let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: vec![PaymentTypeFilter::All], + filters: vec![], from_timestamp: None, to_timestamp: None, include_failures: Some(false), diff --git a/libs/sdk-flutter/lib/bridge_generated.dart b/libs/sdk-flutter/lib/bridge_generated.dart index 926aefc89..bcb0b76e4 100644 --- a/libs/sdk-flutter/lib/bridge_generated.dart +++ b/libs/sdk-flutter/lib/bridge_generated.dart @@ -1097,7 +1097,6 @@ enum PaymentTypeFilter { Sent, Received, ClosedChannels, - All, } /// Denominator in an exchange rate diff --git a/libs/sdk-react-native/ios/BreezSDKMapper.swift b/libs/sdk-react-native/ios/BreezSDKMapper.swift index 2001dba16..5eb236e6d 100644 --- a/libs/sdk-react-native/ios/BreezSDKMapper.swift +++ b/libs/sdk-react-native/ios/BreezSDKMapper.swift @@ -3222,9 +3222,6 @@ class BreezSDKMapper { case "closedChannels": return PaymentTypeFilter.closedChannels - case "all": - return PaymentTypeFilter.all - default: throw SdkError.Generic(message: "Invalid variant \(paymentTypeFilter) for enum PaymentTypeFilter") } } @@ -3239,9 +3236,6 @@ class BreezSDKMapper { case .closedChannels: return "closedChannels" - - case .all: - return "all" } } diff --git a/libs/sdk-react-native/src/index.ts b/libs/sdk-react-native/src/index.ts index 9dd1501d0..ed9083c7b 100644 --- a/libs/sdk-react-native/src/index.ts +++ b/libs/sdk-react-native/src/index.ts @@ -635,8 +635,7 @@ export enum PaymentType { export enum PaymentTypeFilter { SENT = "sent", RECEIVED = "received", - CLOSED_CHANNELS = "closedChannels", - ALL = "all" + CLOSED_CHANNELS = "closedChannels" } export enum ReverseSwapStatus { diff --git a/tools/sdk-cli/src/command_handlers.rs b/tools/sdk-cli/src/command_handlers.rs index 30e448e5c..f596d6e88 100644 --- a/tools/sdk-cli/src/command_handlers.rs +++ b/tools/sdk-cli/src/command_handlers.rs @@ -6,9 +6,9 @@ use breez_sdk_core::InputType::{LnUrlAuth, LnUrlPay, LnUrlWithdraw}; use breez_sdk_core::{ parse, BreezEvent, BreezServices, BuyBitcoinRequest, CheckMessageRequest, EventListener, GreenlightCredentials, ListPaymentsRequest, LnUrlPayRequest, LnUrlWithdrawRequest, - PaymentTypeFilter, ReceiveOnchainRequest, ReceivePaymentRequest, RefundRequest, - ReverseSwapFeesRequest, SendOnchainRequest, SendPaymentRequest, SendSpontaneousPaymentRequest, - SignMessageRequest, StaticBackupRequest, SweepRequest, + ReceiveOnchainRequest, ReceivePaymentRequest, RefundRequest, ReverseSwapFeesRequest, + SendOnchainRequest, SendPaymentRequest, SendSpontaneousPaymentRequest, SignMessageRequest, + StaticBackupRequest, SweepRequest, }; use breez_sdk_core::{Config, GreenlightNodeConfig, NodeConfig}; use once_cell::sync::OnceCell; @@ -216,7 +216,7 @@ pub(crate) async fn handle_command( } => { let payments = sdk()? .list_payments(ListPaymentsRequest { - filters: vec![PaymentTypeFilter::All], + filters: vec![], from_timestamp, to_timestamp, include_failures: Some(include_failures), From 7e46f0067407d9e98440429b23b61e37a54c800e Mon Sep 17 00:00:00 2001 From: ok300 <106775972+ok300@users.noreply.github.com> Date: Tue, 24 Oct 2023 15:23:35 +0200 Subject: [PATCH 04/48] Bump Greenlight dependency --- libs/Cargo.lock | 2 +- libs/sdk-core/Cargo.toml | 2 +- tools/sdk-cli/Cargo.lock | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libs/Cargo.lock b/libs/Cargo.lock index b03053b94..e189bb08e 100644 --- a/libs/Cargo.lock +++ b/libs/Cargo.lock @@ -1299,7 +1299,7 @@ checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" [[package]] name = "gl-client" version = "0.1.9" -source = "git+https://github.com/Blockstream/greenlight.git?rev=f91390734fc8a3044812f05ff8d0e102660189bb#f91390734fc8a3044812f05ff8d0e102660189bb" +source = "git+https://github.com/Blockstream/greenlight.git?rev=28f41bb835659cb3d2e60cd612548f5b22027bb1#28f41bb835659cb3d2e60cd612548f5b22027bb1" dependencies = [ "anyhow", "async-trait", diff --git a/libs/sdk-core/Cargo.toml b/libs/sdk-core/Cargo.toml index 657a512af..92a220efc 100644 --- a/libs/sdk-core/Cargo.toml +++ b/libs/sdk-core/Cargo.toml @@ -18,7 +18,7 @@ bip21 = "0.2" bitcoin = "0.29.2" gl-client = { git = "https://github.com/Blockstream/greenlight.git", features = [ "permissive", -], rev = "f91390734fc8a3044812f05ff8d0e102660189bb" } +], rev = "28f41bb835659cb3d2e60cd612548f5b22027bb1" } zbase32 = "0.1.2" base64 = "0.13.0" chrono = "0.4" diff --git a/tools/sdk-cli/Cargo.lock b/tools/sdk-cli/Cargo.lock index 6f4d172d0..c1d50a05a 100644 --- a/tools/sdk-cli/Cargo.lock +++ b/tools/sdk-cli/Cargo.lock @@ -1215,7 +1215,7 @@ checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" [[package]] name = "gl-client" version = "0.1.9" -source = "git+https://github.com/Blockstream/greenlight.git?rev=f91390734fc8a3044812f05ff8d0e102660189bb#f91390734fc8a3044812f05ff8d0e102660189bb" +source = "git+https://github.com/Blockstream/greenlight.git?rev=28f41bb835659cb3d2e60cd612548f5b22027bb1#28f41bb835659cb3d2e60cd612548f5b22027bb1" dependencies = [ "anyhow", "async-trait", From 970a13baa04c58bf7ce538e4a946b407a3227ac8 Mon Sep 17 00:00:00 2001 From: Dominic Leutenegger Date: Tue, 24 Oct 2023 16:19:47 +0200 Subject: [PATCH 05/48] Define list payments request filters as optional --- libs/sdk-bindings/src/breez_sdk.udl | 2 +- libs/sdk-core/src/breez_services.rs | 9 ++- libs/sdk-core/src/models.rs | 2 +- libs/sdk-core/src/persist/transactions.rs | 70 +++++++++++-------- libs/sdk-flutter/lib/bridge_generated.dart | 12 +++- .../main/java/com/breezsdk/BreezSDKMapper.kt | 15 ++-- .../sdk-react-native/ios/BreezSDKMapper.swift | 8 ++- libs/sdk-react-native/src/index.ts | 2 +- tools/sdk-cli/src/command_handlers.rs | 2 +- 9 files changed, 73 insertions(+), 49 deletions(-) diff --git a/libs/sdk-bindings/src/breez_sdk.udl b/libs/sdk-bindings/src/breez_sdk.udl index 40b890143..81e7b2537 100644 --- a/libs/sdk-bindings/src/breez_sdk.udl +++ b/libs/sdk-bindings/src/breez_sdk.udl @@ -148,7 +148,7 @@ dictionary Payment { }; dictionary ListPaymentsRequest { - sequence filters; + sequence? filters = null; i64? from_timestamp = null; i64? to_timestamp = null; boolean? include_failures = null; diff --git a/libs/sdk-core/src/breez_services.rs b/libs/sdk-core/src/breez_services.rs index 5833082f0..0c44aac1f 100644 --- a/libs/sdk-core/src/breez_services.rs +++ b/libs/sdk-core/src/breez_services.rs @@ -2032,7 +2032,7 @@ pub(crate) mod tests { let all = breez_services .list_payments(ListPaymentsRequest { - filters: vec![], + filters: None, from_timestamp: None, to_timestamp: None, include_failures: None, @@ -2048,7 +2048,7 @@ pub(crate) mod tests { let received = breez_services .list_payments(ListPaymentsRequest { - filters: vec![PaymentTypeFilter::Received], + filters: Some(vec![PaymentTypeFilter::Received]), from_timestamp: None, to_timestamp: None, include_failures: None, @@ -2060,7 +2060,10 @@ pub(crate) mod tests { let sent = breez_services .list_payments(ListPaymentsRequest { - filters: vec![PaymentTypeFilter::Sent, PaymentTypeFilter::ClosedChannels], + filters: Some(vec![ + PaymentTypeFilter::Sent, + PaymentTypeFilter::ClosedChannels, + ]), from_timestamp: None, to_timestamp: None, include_failures: None, diff --git a/libs/sdk-core/src/models.rs b/libs/sdk-core/src/models.rs index 3cf238828..279e57b89 100644 --- a/libs/sdk-core/src/models.rs +++ b/libs/sdk-core/src/models.rs @@ -657,7 +657,7 @@ pub struct Payment { /// Represents a list payments request. pub struct ListPaymentsRequest { - pub filters: Vec, + pub filters: Option>, pub from_timestamp: Option, pub to_timestamp: Option, pub include_failures: Option, diff --git a/libs/sdk-core/src/persist/transactions.rs b/libs/sdk-core/src/persist/transactions.rs index ad1b3ba0f..69ed24077 100644 --- a/libs/sdk-core/src/persist/transactions.rs +++ b/libs/sdk-core/src/persist/transactions.rs @@ -263,7 +263,7 @@ impl SqliteStorage { } fn filter_to_where_clause( - type_filters: Vec, + type_filters: Option>, from_timestamp: Option, to_timestamp: Option, include_failures: Option, @@ -281,30 +281,32 @@ fn filter_to_where_clause( where_clause.push(format!("status != {}", PaymentStatus::Failed as i64)); }; - if !type_filters.is_empty() { - let mut type_filter_clause: HashSet = HashSet::new(); - for type_filter in type_filters { - match type_filter { - PaymentTypeFilter::Sent => { - type_filter_clause.insert(PaymentType::Sent); - } - PaymentTypeFilter::Received => { - type_filter_clause.insert(PaymentType::Received); - } - PaymentTypeFilter::ClosedChannels => { - type_filter_clause.insert(PaymentType::ClosedChannel); + if let Some(filters) = type_filters { + if !filters.is_empty() { + let mut type_filter_clause: HashSet = HashSet::new(); + for type_filter in filters { + match type_filter { + PaymentTypeFilter::Sent => { + type_filter_clause.insert(PaymentType::Sent); + } + PaymentTypeFilter::Received => { + type_filter_clause.insert(PaymentType::Received); + } + PaymentTypeFilter::ClosedChannels => { + type_filter_clause.insert(PaymentType::ClosedChannel); + } } } - } - where_clause.push(format!( - "payment_type in ({})", - type_filter_clause - .iter() - .map(|t| format!("'{}'", t)) - .collect::>() - .join(", ") - )); + where_clause.push(format!( + "payment_type in ({})", + type_filter_clause + .iter() + .map(|t| format!("'{}'", t)) + .collect::>() + .join(", ") + )); + } } let mut where_clause_str = String::new(); @@ -473,7 +475,7 @@ fn test_ln_transactions() -> Result<(), Box> { // retrieve all let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: vec![], + filters: None, from_timestamp: None, to_timestamp: None, include_failures: None, @@ -485,7 +487,10 @@ fn test_ln_transactions() -> Result<(), Box> { //test only sent let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: vec![PaymentTypeFilter::Sent, PaymentTypeFilter::ClosedChannels], + filters: Some(vec![ + PaymentTypeFilter::Sent, + PaymentTypeFilter::ClosedChannels, + ]), from_timestamp: None, to_timestamp: None, include_failures: None, @@ -503,7 +508,7 @@ fn test_ln_transactions() -> Result<(), Box> { //test only received let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: vec![PaymentTypeFilter::Received], + filters: Some(vec![PaymentTypeFilter::Received]), from_timestamp: None, to_timestamp: None, include_failures: None, @@ -518,7 +523,7 @@ fn test_ln_transactions() -> Result<(), Box> { storage.insert_or_update_payments(&txs)?; let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: vec![], + filters: None, from_timestamp: None, to_timestamp: None, include_failures: None, @@ -530,7 +535,7 @@ fn test_ln_transactions() -> Result<(), Box> { storage.insert_open_channel_payment_info("123", 150)?; let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: vec![], + filters: None, from_timestamp: None, to_timestamp: None, include_failures: None, @@ -541,7 +546,7 @@ fn test_ln_transactions() -> Result<(), Box> { // test all with failures let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: vec![], + filters: None, from_timestamp: None, to_timestamp: None, include_failures: Some(true), @@ -552,7 +557,10 @@ fn test_ln_transactions() -> Result<(), Box> { // test sent with failures let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: vec![PaymentTypeFilter::Sent, PaymentTypeFilter::ClosedChannels], + filters: Some(vec![ + PaymentTypeFilter::Sent, + PaymentTypeFilter::ClosedChannels, + ]), from_timestamp: None, to_timestamp: None, include_failures: Some(true), @@ -563,7 +571,7 @@ fn test_ln_transactions() -> Result<(), Box> { // test limit let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: vec![], + filters: None, from_timestamp: None, to_timestamp: None, include_failures: Some(false), @@ -574,7 +582,7 @@ fn test_ln_transactions() -> Result<(), Box> { // test offset let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: vec![], + filters: None, from_timestamp: None, to_timestamp: None, include_failures: Some(false), diff --git a/libs/sdk-flutter/lib/bridge_generated.dart b/libs/sdk-flutter/lib/bridge_generated.dart index bcb0b76e4..c3fd8ae9d 100644 --- a/libs/sdk-flutter/lib/bridge_generated.dart +++ b/libs/sdk-flutter/lib/bridge_generated.dart @@ -571,7 +571,7 @@ class InvoicePaidDetails { /// Represents a list payments request. class ListPaymentsRequest { - final List filters; + final List? filters; final int? fromTimestamp; final int? toTimestamp; final bool? includeFailures; @@ -579,7 +579,7 @@ class ListPaymentsRequest { final int? limit; const ListPaymentsRequest({ - required this.filters, + this.filters, this.fromTimestamp, this.toTimestamp, this.includeFailures, @@ -3568,6 +3568,12 @@ class BreezSdkCorePlatform extends FlutterRustBridgeBase { return raw == null ? ffi.nullptr : api2wire_box_autoadd_u64(raw); } + @protected + ffi.Pointer api2wire_opt_list_payment_type_filter( + List? raw) { + return raw == null ? ffi.nullptr : api2wire_list_payment_type_filter(raw); + } + @protected ffi.Pointer api2wire_opt_uint_8_list(Uint8List? raw) { return raw == null ? ffi.nullptr : api2wire_uint_8_list(raw); @@ -3733,7 +3739,7 @@ class BreezSdkCorePlatform extends FlutterRustBridgeBase { } void _api_fill_to_wire_list_payments_request(ListPaymentsRequest apiObj, wire_ListPaymentsRequest wireObj) { - wireObj.filters = api2wire_list_payment_type_filter(apiObj.filters); + wireObj.filters = api2wire_opt_list_payment_type_filter(apiObj.filters); wireObj.from_timestamp = api2wire_opt_box_autoadd_i64(apiObj.fromTimestamp); wireObj.to_timestamp = api2wire_opt_box_autoadd_i64(apiObj.toTimestamp); wireObj.include_failures = api2wire_opt_box_autoadd_bool(apiObj.includeFailures); diff --git a/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt b/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt index 5735dad4f..634fa0d5d 100644 --- a/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt +++ b/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt @@ -726,14 +726,19 @@ fun asLnInvoiceList(arr: ReadableArray): List { fun asListPaymentsRequest(listPaymentsRequest: ReadableMap): ListPaymentsRequest? { if (!validateMandatoryFields( listPaymentsRequest, - arrayOf( - "filters", - ), + arrayOf(), ) ) { return null } - val filters = listPaymentsRequest.getArray("filters")?.let { asPaymentTypeFilterList(it) }!! + val filters = + if (hasNonNullKey(listPaymentsRequest, "filters")) { + listPaymentsRequest.getArray("filters")?.let { + asPaymentTypeFilterList(it) + } + } else { + null + } val fromTimestamp = if (hasNonNullKey( listPaymentsRequest, @@ -769,7 +774,7 @@ fun asListPaymentsRequest(listPaymentsRequest: ReadableMap): ListPaymentsRequest fun readableMapOf(listPaymentsRequest: ListPaymentsRequest): ReadableMap { return readableMapOf( - "filters" to readableArrayOf(listPaymentsRequest.filters), + "filters" to listPaymentsRequest.filters?.let { readableArrayOf(it) }, "fromTimestamp" to listPaymentsRequest.fromTimestamp, "toTimestamp" to listPaymentsRequest.toTimestamp, "includeFailures" to listPaymentsRequest.includeFailures, diff --git a/libs/sdk-react-native/ios/BreezSDKMapper.swift b/libs/sdk-react-native/ios/BreezSDKMapper.swift index 5eb236e6d..ebe5eaa5a 100644 --- a/libs/sdk-react-native/ios/BreezSDKMapper.swift +++ b/libs/sdk-react-native/ios/BreezSDKMapper.swift @@ -657,8 +657,10 @@ class BreezSDKMapper { } static func asListPaymentsRequest(listPaymentsRequest: [String: Any?]) throws -> ListPaymentsRequest { - guard let filtersTmp = listPaymentsRequest["filters"] as? [String] else { throw SdkError.Generic(message: "Missing mandatory field filters for type ListPaymentsRequest") } - let filters = filtersTmp + var filters: [PaymentTypeFilter]? + if let filtersTmp = listPaymentsRequest["filters"] as? [String] { + filters = filtersTmp + } let fromTimestamp = listPaymentsRequest["fromTimestamp"] as? Int64 let toTimestamp = listPaymentsRequest["toTimestamp"] as? Int64 @@ -678,7 +680,7 @@ class BreezSDKMapper { static func dictionaryOf(listPaymentsRequest: ListPaymentsRequest) -> [String: Any?] { return [ - "filters": arrayOf(paymentTypeFilterList: listPaymentsRequest.filters), + "filters": listPaymentsRequest.filters == nil ? nil : arrayOf(paymentTypeFilterList: listPaymentsRequest.filters!), "fromTimestamp": listPaymentsRequest.fromTimestamp == nil ? nil : listPaymentsRequest.fromTimestamp, "toTimestamp": listPaymentsRequest.toTimestamp == nil ? nil : listPaymentsRequest.toTimestamp, "includeFailures": listPaymentsRequest.includeFailures == nil ? nil : listPaymentsRequest.includeFailures, diff --git a/libs/sdk-react-native/src/index.ts b/libs/sdk-react-native/src/index.ts index ed9083c7b..9a63b0fea 100644 --- a/libs/sdk-react-native/src/index.ts +++ b/libs/sdk-react-native/src/index.ts @@ -125,7 +125,7 @@ export type LnInvoice = { } export type ListPaymentsRequest = { - filters: PaymentTypeFilter[] + filters?: PaymentTypeFilter[] fromTimestamp?: number toTimestamp?: number includeFailures?: boolean diff --git a/tools/sdk-cli/src/command_handlers.rs b/tools/sdk-cli/src/command_handlers.rs index f596d6e88..27c4937bc 100644 --- a/tools/sdk-cli/src/command_handlers.rs +++ b/tools/sdk-cli/src/command_handlers.rs @@ -216,7 +216,7 @@ pub(crate) async fn handle_command( } => { let payments = sdk()? .list_payments(ListPaymentsRequest { - filters: vec![], + filters: None, from_timestamp, to_timestamp, include_failures: Some(include_failures), From a51d8147c12c3a22cd664b1c883528d8de87a11f Mon Sep 17 00:00:00 2001 From: Ademar Date: Wed, 25 Oct 2023 10:58:51 -0300 Subject: [PATCH 06/48] Allow multiple logs listeners (#553) --- libs/sdk-flutter/lib/breez_sdk.dart | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libs/sdk-flutter/lib/breez_sdk.dart b/libs/sdk-flutter/lib/breez_sdk.dart index 8fe92f31a..6a833db2a 100644 --- a/libs/sdk-flutter/lib/breez_sdk.dart +++ b/libs/sdk-flutter/lib/breez_sdk.dart @@ -47,9 +47,17 @@ class BreezSDK { _backupStreamController.addError(Exception(event.details.error)); } }); + _lnToolkit.breezLogStream().listen((logEntry) { + _logStreamController.add(logEntry); + }, onError: (e) { + _logStreamController.addError(e); + }); } - Stream get logStream => _lnToolkit.breezLogStream(); + final _logStreamController = StreamController.broadcast(); + + /// Listen to log events + Stream get logStream => _logStreamController.stream; /* Breez Services API's & Streams*/ From 89dd16a38c77bf13cc7b3a7da7077b193c86c1ee Mon Sep 17 00:00:00 2001 From: Ademar Date: Wed, 25 Oct 2023 11:15:05 -0300 Subject: [PATCH 07/48] Add prepare withdraw method (#294) --- libs/Cargo.lock | 21 ++- libs/sdk-bindings/src/breez_sdk.udl | 19 ++- libs/sdk-bindings/src/uniffi_binding.rs | 32 +++-- libs/sdk-core/Cargo.toml | 1 + libs/sdk-core/src/binding.rs | 16 ++- libs/sdk-core/src/breez_services.rs | 16 ++- libs/sdk-core/src/bridge_generated.io.rs | 46 ++++++ libs/sdk-core/src/bridge_generated.rs | 29 ++++ libs/sdk-core/src/greenlight/node_api.rs | 135 ++++++++++++++---- libs/sdk-core/src/models.rs | 29 +++- libs/sdk-core/src/test_utils.rs | 9 +- .../ios/Classes/bridge_generated.h | 11 ++ libs/sdk-flutter/lib/breez_sdk.dart | 11 ++ libs/sdk-flutter/lib/bridge_generated.dart | 105 ++++++++++++++ .../main/java/com/breezsdk/BreezSDKMapper.kt | 74 ++++++++++ .../main/java/com/breezsdk/BreezSDKModule.kt | 19 +++ .../sdk-react-native/ios/BreezSDKMapper.swift | 68 +++++++++ libs/sdk-react-native/ios/RNBreezSDK.m | 6 + libs/sdk-react-native/ios/RNBreezSDK.swift | 11 ++ libs/sdk-react-native/src/index.ts | 15 ++ tools/sdk-cli/Cargo.lock | 21 ++- tools/sdk-cli/src/command_handlers.rs | 20 ++- tools/sdk-cli/src/commands.rs | 11 +- 23 files changed, 650 insertions(+), 75 deletions(-) diff --git a/libs/Cargo.lock b/libs/Cargo.lock index 172b04002..b918d6804 100644 --- a/libs/Cargo.lock +++ b/libs/Cargo.lock @@ -531,6 +531,7 @@ dependencies = [ "ecies", "env_logger 0.10.0", "flutter_rust_bridge", + "futures", "gl-client", "hex", "lazy_static", @@ -2514,9 +2515,21 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.4" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" dependencies = [ "aho-corasick", "memchr", @@ -2525,9 +2538,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "reqwest" diff --git a/libs/sdk-bindings/src/breez_sdk.udl b/libs/sdk-bindings/src/breez_sdk.udl index 81e7b2537..8d6d07b33 100644 --- a/libs/sdk-bindings/src/breez_sdk.udl +++ b/libs/sdk-bindings/src/breez_sdk.udl @@ -83,7 +83,7 @@ dictionary UnspentTransactionOutput { u32 outnum; u64 amount_millisatoshi; string address; - boolean reserved; + boolean reserved; }; dictionary NodeState { @@ -536,6 +536,16 @@ enum BuyBitcoinProvider { "Moonpay", }; +dictionary PrepareSweepRequest { + string to_address; + u64 sats_per_vbyte; +}; + +dictionary PrepareSweepResponse { + u64 sweep_tx_weight; + u64 sweep_tx_fee_sat; +}; + dictionary SweepRequest { string to_address; u32 fee_rate_sats_per_vbyte; @@ -580,7 +590,7 @@ dictionary RefundResponse { string refund_tx_id; }; -interface BlockingBreezServices { +interface BlockingBreezServices { [Throws=SdkError] void disconnect(); @@ -686,6 +696,9 @@ interface BlockingBreezServices { [Throws=SdkError] BuyBitcoinResponse buy_bitcoin(BuyBitcoinRequest req); + + [Throws=SdkError] + PrepareSweepResponse prepare_sweep(PrepareSweepRequest req); }; namespace breez_sdk { @@ -709,4 +722,4 @@ namespace breez_sdk { [Throws=SdkError] StaticBackupResponse static_backup(StaticBackupRequest req); -}; \ No newline at end of file +}; diff --git a/libs/sdk-bindings/src/uniffi_binding.rs b/libs/sdk-bindings/src/uniffi_binding.rs index f3f86a581..0ad41147f 100644 --- a/libs/sdk-bindings/src/uniffi_binding.rs +++ b/libs/sdk-bindings/src/uniffi_binding.rs @@ -1,9 +1,4 @@ -use std::sync::Arc; - use anyhow::{anyhow, Result}; -use log::{Level, LevelFilter, Metadata, Record}; -use once_cell::sync::{Lazy, OnceCell}; - use breez_sdk_core::{ error::*, mnemonic_to_seed as sdk_mnemonic_to_seed, parse as sdk_parse_input, parse_invoice as sdk_parse_invoice, AesSuccessActionDataDecrypted, BackupFailedData, @@ -17,14 +12,19 @@ use breez_sdk_core::{ LocaleOverrides, LocalizedName, LogEntry, LogStream, LspInformation, MessageSuccessActionData, MetadataItem, Network, NodeConfig, NodeState, OpenChannelFeeRequest, OpenChannelFeeResponse, OpeningFeeParams, OpeningFeeParamsMenu, Payment, PaymentDetails, PaymentFailedData, - PaymentStatus, PaymentType, PaymentTypeFilter, Rate, ReceiveOnchainRequest, - ReceivePaymentRequest, ReceivePaymentResponse, RecommendedFees, RefundRequest, RefundResponse, - ReverseSwapFeesRequest, ReverseSwapInfo, ReverseSwapPairInfo, ReverseSwapStatus, RouteHint, - RouteHintHop, SendOnchainRequest, SendOnchainResponse, SendPaymentRequest, SendPaymentResponse, - SendSpontaneousPaymentRequest, SignMessageRequest, SignMessageResponse, StaticBackupRequest, - StaticBackupResponse, SuccessActionProcessed, SwapInfo, SwapStatus, SweepRequest, - SweepResponse, Symbol, UnspentTransactionOutput, UrlSuccessActionData, + PaymentStatus, PaymentType, PaymentTypeFilter, PrepareSweepRequest, PrepareSweepResponse, Rate, + ReceiveOnchainRequest, ReceivePaymentRequest, ReceivePaymentResponse, RecommendedFees, + RefundRequest, RefundResponse, ReverseSwapFeesRequest, ReverseSwapInfo, ReverseSwapPairInfo, + ReverseSwapStatus, RouteHint, RouteHintHop, SendOnchainRequest, SendOnchainResponse, + SendPaymentRequest, SendPaymentResponse, SendSpontaneousPaymentRequest, SignMessageRequest, + SignMessageResponse, StaticBackupRequest, StaticBackupResponse, SuccessActionProcessed, + SwapInfo, SwapStatus, SweepRequest, SweepResponse, Symbol, UnspentTransactionOutput, + UrlSuccessActionData, }; +use log::{Level, LevelFilter, Metadata, Record}; +use once_cell::sync::{Lazy, OnceCell}; +use std::sync::Arc; + static RT: Lazy = Lazy::new(|| tokio::runtime::Runtime::new().unwrap()); static LOG_INIT: OnceCell = OnceCell::new(); @@ -286,6 +286,14 @@ impl BlockingBreezServices { pub fn buy_bitcoin(&self, req: BuyBitcoinRequest) -> SdkResult { rt().block_on(self.breez_services.buy_bitcoin(req)) } + + pub fn prepare_sweep( + &self, + req: PrepareSweepRequest, + ) -> Result { + rt().block_on(self.breez_services.prepare_sweep(req)) + .map_err(|e| e.into()) + } } pub fn parse_invoice(invoice: String) -> SdkResult { diff --git a/libs/sdk-core/Cargo.toml b/libs/sdk-core/Cargo.toml index 92a220efc..ff6dea08f 100644 --- a/libs/sdk-core/Cargo.toml +++ b/libs/sdk-core/Cargo.toml @@ -24,6 +24,7 @@ base64 = "0.13.0" chrono = "0.4" ecies = { version = "0.2", default-features = false, features = ["pure"] } env_logger = "0.10" +futures = "0.3.28" ripemd = "0.1" rand = "0.8" tiny-bip39 = "1" diff --git a/libs/sdk-core/src/binding.rs b/libs/sdk-core/src/binding.rs index 099800d4f..9608a5441 100644 --- a/libs/sdk-core/src/binding.rs +++ b/libs/sdk-core/src/binding.rs @@ -32,11 +32,12 @@ use crate::{ BackupStatus, BuyBitcoinRequest, BuyBitcoinResponse, CheckMessageRequest, CheckMessageResponse, EnvironmentType, ListPaymentsRequest, LnUrlCallbackStatus, LnUrlPayRequest, LnUrlWithdrawRequest, LnUrlWithdrawResult, NodeConfig, OpenChannelFeeRequest, - OpenChannelFeeResponse, ReceiveOnchainRequest, ReceivePaymentRequest, ReceivePaymentResponse, - RefundRequest, RefundResponse, ReverseSwapFeesRequest, ReverseSwapInfo, ReverseSwapPairInfo, - SendOnchainRequest, SendOnchainResponse, SendPaymentRequest, SendPaymentResponse, - SendSpontaneousPaymentRequest, SignMessageRequest, SignMessageResponse, StaticBackupRequest, - StaticBackupResponse, SweepRequest, SweepResponse, + OpenChannelFeeResponse, PrepareSweepRequest, PrepareSweepResponse, ReceiveOnchainRequest, + ReceivePaymentRequest, ReceivePaymentResponse, RefundRequest, RefundResponse, + ReverseSwapFeesRequest, ReverseSwapInfo, ReverseSwapPairInfo, SendOnchainRequest, + SendOnchainResponse, SendPaymentRequest, SendPaymentResponse, SendSpontaneousPaymentRequest, + SignMessageRequest, SignMessageResponse, StaticBackupRequest, StaticBackupResponse, + SweepRequest, SweepResponse, }; /* @@ -301,6 +302,11 @@ pub fn sweep(req: SweepRequest) -> Result { block_on(async { get_breez_services().await?.sweep(req).await }) } +/// See [BreezServices::prepare_sweep] +pub fn prepare_sweep(req: PrepareSweepRequest) -> Result { + block_on(async { get_breez_services().await?.prepare_sweep(req).await }) +} + /* Refundables API's */ /// See [BreezServices::list_refundables] diff --git a/libs/sdk-core/src/breez_services.rs b/libs/sdk-core/src/breez_services.rs index 6775d86aa..b956d4eba 100644 --- a/libs/sdk-core/src/breez_services.rs +++ b/libs/sdk-core/src/breez_services.rs @@ -476,6 +476,12 @@ impl BreezServices { Ok(SweepResponse { txid }) } + pub async fn prepare_sweep(&self, req: PrepareSweepRequest) -> Result { + self.start_node().await?; + let response = self.node_api.prepare_sweep(req).await?; + Ok(response) + } + /// Fetch live rates of fiat currencies pub async fn fetch_fiat_rates(&self) -> Result> { self.fiat_api.fetch_fiat_rates().await @@ -1430,6 +1436,11 @@ impl BreezServicesBuilder { .unwrap_or_else(|| Arc::new(SqliteStorage::new(self.config.working_dir.clone()))); persister.init()?; + // mempool space is used to monitor the chain + let chain_service = Arc::new(MempoolSpace::from_base_url( + self.config.mempoolspace_url.clone(), + )); + let mut node_api = self.node_api.clone(); let mut backup_transport = self.backup_transport.clone(); if node_api.is_none() { @@ -1500,11 +1511,6 @@ impl BreezServicesBuilder { self.config.api_key.clone(), )); - // mempool space is used to monitor the chain - let chain_service = Arc::new(MempoolSpace::from_base_url( - self.config.mempoolspace_url.clone(), - )); - let current_lsp_id = persister.get_lsp_id()?; if current_lsp_id.is_none() && self.config.default_lsp_id.is_some() { persister.set_lsp_id(self.config.default_lsp_id.clone().unwrap())?; diff --git a/libs/sdk-core/src/bridge_generated.io.rs b/libs/sdk-core/src/bridge_generated.io.rs index b92ed3e0c..546393469 100644 --- a/libs/sdk-core/src/bridge_generated.io.rs +++ b/libs/sdk-core/src/bridge_generated.io.rs @@ -189,6 +189,11 @@ pub extern "C" fn wire_sweep(port_: i64, req: *mut wire_SweepRequest) { wire_sweep_impl(port_, req) } +#[no_mangle] +pub extern "C" fn wire_prepare_sweep(port_: i64, req: *mut wire_PrepareSweepRequest) { + wire_prepare_sweep_impl(port_, req) +} + #[no_mangle] pub extern "C" fn wire_list_refundables(port_: i64) { wire_list_refundables_impl(port_) @@ -301,6 +306,11 @@ pub extern "C" fn new_box_autoadd_opening_fee_params_0() -> *mut wire_OpeningFee support::new_leak_box_ptr(wire_OpeningFeeParams::new_with_null_ptr()) } +#[no_mangle] +pub extern "C" fn new_box_autoadd_prepare_sweep_request_0() -> *mut wire_PrepareSweepRequest { + support::new_leak_box_ptr(wire_PrepareSweepRequest::new_with_null_ptr()) +} + #[no_mangle] pub extern "C" fn new_box_autoadd_receive_onchain_request_0() -> *mut wire_ReceiveOnchainRequest { support::new_leak_box_ptr(wire_ReceiveOnchainRequest::new_with_null_ptr()) @@ -474,6 +484,12 @@ impl Wire2Api for *mut wire_OpeningFeeParams { Wire2Api::::wire2api(*wrap).into() } } +impl Wire2Api for *mut wire_PrepareSweepRequest { + fn wire2api(self) -> PrepareSweepRequest { + let wrap = unsafe { support::box_from_leak_ptr(self) }; + Wire2Api::::wire2api(*wrap).into() + } +} impl Wire2Api for *mut wire_ReceiveOnchainRequest { fn wire2api(self) -> ReceiveOnchainRequest { let wrap = unsafe { support::box_from_leak_ptr(self) }; @@ -705,6 +721,14 @@ impl Wire2Api for wire_OpeningFeeParams { } } +impl Wire2Api for wire_PrepareSweepRequest { + fn wire2api(self) -> PrepareSweepRequest { + PrepareSweepRequest { + to_address: self.to_address.wire2api(), + sats_per_vbyte: self.sats_per_vbyte.wire2api(), + } + } +} impl Wire2Api for wire_ReceiveOnchainRequest { fn wire2api(self) -> ReceiveOnchainRequest { ReceiveOnchainRequest { @@ -927,6 +951,13 @@ pub struct wire_OpeningFeeParams { promise: *mut wire_uint_8_list, } +#[repr(C)] +#[derive(Clone)] +pub struct wire_PrepareSweepRequest { + to_address: *mut wire_uint_8_list, + sats_per_vbyte: u64, +} + #[repr(C)] #[derive(Clone)] pub struct wire_ReceiveOnchainRequest { @@ -1286,6 +1317,21 @@ impl Default for wire_OpeningFeeParams { } } +impl NewWithNullPtr for wire_PrepareSweepRequest { + fn new_with_null_ptr() -> Self { + Self { + to_address: core::ptr::null_mut(), + sats_per_vbyte: Default::default(), + } + } +} + +impl Default for wire_PrepareSweepRequest { + fn default() -> Self { + Self::new_with_null_ptr() + } +} + impl NewWithNullPtr for wire_ReceiveOnchainRequest { fn new_with_null_ptr() -> Self { Self { diff --git a/libs/sdk-core/src/bridge_generated.rs b/libs/sdk-core/src/bridge_generated.rs index 3c572e806..39fe66edd 100644 --- a/libs/sdk-core/src/bridge_generated.rs +++ b/libs/sdk-core/src/bridge_generated.rs @@ -79,6 +79,8 @@ use crate::models::PaymentDetails; use crate::models::PaymentStatus; use crate::models::PaymentType; use crate::models::PaymentTypeFilter; +use crate::models::PrepareSweepRequest; +use crate::models::PrepareSweepResponse; use crate::models::ReceiveOnchainRequest; use crate::models::ReceivePaymentRequest; use crate::models::ReceivePaymentResponse; @@ -565,6 +567,22 @@ fn wire_sweep_impl(port_: MessagePort, req: impl Wire2Api + Unwind }, ) } +fn wire_prepare_sweep_impl( + port_: MessagePort, + req: impl Wire2Api + UnwindSafe, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap( + WrapInfo { + debug_name: "prepare_sweep", + port: Some(port_), + mode: FfiCallMode::Normal, + }, + move || { + let api_req = req.wire2api(); + move |task_callback| prepare_sweep(api_req) + }, + ) +} fn wire_list_refundables_impl(port_: MessagePort) { FLUTTER_RUST_BRIDGE_HANDLER.wrap( WrapInfo { @@ -1261,6 +1279,17 @@ impl support::IntoDart for PaymentType { } } impl support::IntoDartExceptPrimitive for PaymentType {} +impl support::IntoDart for PrepareSweepResponse { + fn into_dart(self) -> support::DartAbi { + vec![ + self.sweep_tx_weight.into_dart(), + self.sweep_tx_fee_sat.into_dart(), + ] + .into_dart() + } +} +impl support::IntoDartExceptPrimitive for PrepareSweepResponse {} + impl support::IntoDart for Rate { fn into_dart(self) -> support::DartAbi { vec![self.coin.into_dart(), self.value.into_dart()].into_dart() diff --git a/libs/sdk-core/src/greenlight/node_api.rs b/libs/sdk-core/src/greenlight/node_api.rs index ed81afac9..f86d415d9 100644 --- a/libs/sdk-core/src/greenlight/node_api.rs +++ b/libs/sdk-core/src/greenlight/node_api.rs @@ -6,18 +6,21 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH}; use anyhow::{anyhow, Result}; use bitcoin::bech32::{u5, ToBase32}; +use bitcoin::blockdata::constants::WITNESS_SCALE_FACTOR; +use bitcoin::hashes::Hash; use bitcoin::secp256k1::ecdsa::{RecoverableSignature, RecoveryId}; use bitcoin::secp256k1::PublicKey; use bitcoin::secp256k1::Secp256k1; use bitcoin::util::bip32::{ChildNumber, ExtendedPrivKey}; +use bitcoin::{Address, OutPoint, Script, Sequence, Transaction, TxIn, TxOut, Txid, Witness}; use ecies::utils::{aes_decrypt, aes_encrypt}; use gl_client::node::ClnClient; use gl_client::pb::cln::listinvoices_invoices::ListinvoicesInvoicesStatus; use gl_client::pb::cln::listpays_pays::ListpaysPaysStatus; use gl_client::pb::cln::{ self, CloseRequest, ListclosedchannelsClosedchannels, ListclosedchannelsRequest, - ListinvoicesInvoices, ListpaysPays, ListpeerchannelsRequest, SendcustommsgRequest, - StaticbackupRequest, + ListfundsRequest, ListfundsResponse, ListinvoicesInvoices, ListpaysPays, + ListpeerchannelsRequest, SendcustommsgRequest, StaticbackupRequest, }; use gl_client::pb::cln::{AmountOrAny, InvoiceRequest}; use gl_client::pb::{OffChainPayment, PayStatus}; @@ -39,7 +42,7 @@ use tonic::Streaming; use crate::invoice::parse_invoice; use crate::models::*; use crate::persist::db::SqliteStorage; -use crate::{Channel, ChannelState, NodeConfig}; +use crate::{Channel, ChannelState, NodeConfig, PrepareSweepRequest, PrepareSweepResponse}; use std::iter::Iterator; const MAX_PAYMENT_AMOUNT_MSAT: u64 = 4294967000; @@ -60,7 +63,7 @@ impl Greenlight { /// If the node is not created, it will register it using the provided partner credentials /// or invite code /// If the node is already registered and an existing credentials were found, it will try to - /// connect to the node using these credentials. + /// connect to the node using these credentials. pub async fn connect( config: Config, seed: Vec, @@ -352,6 +355,45 @@ impl Greenlight { channels_balance, )) } + + async fn list_funds(&self) -> Result { + let mut client = self.get_node_client().await?; + let funds: ListfundsResponse = client + .list_funds(ListfundsRequest::default()) + .await? + .into_inner(); + Ok(funds) + } + + async fn on_chain_balance(&self, funds: ListfundsResponse) -> Result { + let on_chain_balance = funds.outputs.iter().fold(0, |a, b| { + if b.reserved { + return a; + } + a + b.amount_msat.clone().unwrap_or_default().msat + }); + Ok(on_chain_balance) + } + + // Collect utxos from onchain funds + async fn utxos(&self, funds: ListfundsResponse) -> Result> { + let utxos: Vec = funds + .outputs + .iter() + .map(|output| UnspentTransactionOutput { + txid: output.txid.clone(), + outnum: output.output, + amount_millisatoshi: output + .amount_msat + .as_ref() + .map(|a| a.msat) + .unwrap_or_default(), + address: output.address.clone().unwrap_or_default(), + reserved: output.reserved, + }) + .collect(); + Ok(utxos) + } } #[tonic::async_trait] @@ -388,7 +430,7 @@ impl NodeAPI for Greenlight { Ok(res.bolt11) } - // implemenet pull changes from greenlight + // implement pull changes from greenlight async fn pull_changed( &self, since_timestamp: u64, @@ -402,8 +444,7 @@ impl NodeAPI for Greenlight { let node_info_future = node_info_client.getinfo(pb::cln::GetinfoRequest::default()); // list both off chain funds and on chain fudns - let mut funds_client = node_client.clone(); - let funds_future = funds_client.list_funds(pb::cln::ListfundsRequest::default()); + let funds_future = self.list_funds(); // Fetch closed channels from greenlight let mut closed_channels_client = node_client.clone(); @@ -426,7 +467,7 @@ impl NodeAPI for Greenlight { ); let node_info = node_info_res?.into_inner(); - let onchain_funds = funds_res?.into_inner().outputs; + let funds = funds_res?; let closed_channels = closed_channels_res?.into_inner().closedchannels; let (all_channels, opened_channels, connected_peers, channels_balance) = balance_res?; @@ -447,28 +488,8 @@ impl NodeAPI for Greenlight { all_channel_models.extend(forgotten_closed_channels?); // calculate onchain balance - let onchain_balance = onchain_funds.iter().fold(0, |a, b| { - if b.reserved { - return a; - } - a + b.amount_msat.clone().unwrap_or_default().msat - }); - - // Collect utxos from onchain funds - let utxos = onchain_funds - .iter() - .map(|output| UnspentTransactionOutput { - txid: output.txid.clone(), - outnum: output.output, - amount_millisatoshi: output - .amount_msat - .as_ref() - .map(|a| a.msat) - .unwrap_or_default(), - address: output.address.clone().unwrap_or_default(), - reserved: output.reserved, - }) - .collect(); + let onchain_balance = self.on_chain_balance(funds.clone()).await?; + let utxos = self.utxos(funds).await?; // calculate payment limits and inbound liquidity let mut max_payable: u64 = 0; @@ -596,6 +617,58 @@ impl NodeAPI for Greenlight { Ok(client.withdraw(request).await?.into_inner().txid) } + async fn prepare_sweep(&self, req: PrepareSweepRequest) -> Result { + let funds = self.list_funds().await?; + let utxos = self.utxos(funds).await?; + + let mut amount: u64 = 0; + let txins: Vec = utxos + .iter() + .map(|utxo| { + amount += utxo.amount_millisatoshi; + TxIn { + previous_output: OutPoint { + txid: Txid::from_slice(&utxo.txid).unwrap(), + vout: 0, + }, + script_sig: Script::new(), + sequence: Sequence(0), + witness: Witness::default(), + } + }) + .collect(); + + // remove millisats lower than 1 satoshi (1-999 msat) + amount /= 1000; + amount *= 1000; + + let btc_address = Address::from_str(&req.to_address)?; + let tx_out: Vec = vec![TxOut { + value: amount, + script_pubkey: btc_address.payload.script_pubkey(), + }]; + let mut tx = Transaction { + version: 2, + lock_time: bitcoin::PackedLockTime(0), + input: txins.clone(), + output: tx_out, + }; + + let witness_input_size: u64 = 110; + let tx_weight = tx.strippedsize() as u64 * WITNESS_SCALE_FACTOR as u64 + + witness_input_size * txins.len() as u64; + let fee: u64 = tx_weight * req.sats_per_vbyte / WITNESS_SCALE_FACTOR as u64; + if fee >= amount { + return Err(anyhow!("insufficient funds to pay fees")); + } + tx.output[0].value = amount - fee; + + return Ok(PrepareSweepResponse { + sweep_tx_weight: tx_weight, + sweep_tx_fee_sat: fee, + }); + } + /// Starts the signer that listens in a loop until the shutdown signal is received async fn start_signer(&self, shutdown: mpsc::Receiver<()>) { match self.signer.run_forever(shutdown).await { @@ -783,7 +856,7 @@ impl NodeAPI for Greenlight { let resp = self .get_node_client() .await? - .list_funds(pb::cln::ListfundsRequest::default()) + .list_funds(ListfundsRequest::default()) .await? .into_inner(); Ok(format!("{resp:?}")) diff --git a/libs/sdk-core/src/models.rs b/libs/sdk-core/src/models.rs index 279e57b89..079b07b6d 100644 --- a/libs/sdk-core/src/models.rs +++ b/libs/sdk-core/src/models.rs @@ -1,3 +1,4 @@ +use std::cmp::max; use std::ops::Add; use std::pin::Pin; use std::str::FromStr; @@ -17,7 +18,7 @@ use ripemd::Ripemd160; use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ToSqlOutput, ValueRef}; use rusqlite::ToSql; use serde::{Deserialize, Serialize}; -use std::cmp::max; +use strum_macros::{Display, EnumString}; use tokio::sync::mpsc; use tokio_stream::Stream; use tonic::Streaming; @@ -32,7 +33,6 @@ use crate::{LNInvoice, LnUrlErrorData, LnUrlPayRequestData, LnUrlWithdrawRequest use crate::breez_services::BreezServer; use crate::error::{SdkError, SdkResult}; -use strum_macros::{Display, EnumString}; pub const SWAP_PAYMENT_FEE_EXPIRY_SECONDS: u32 = 60 * 60 * 24 * 2; // 2 days pub const INVOICE_PAYMENT_FEE_EXPIRY_SECONDS: u32 = 60 * 60; // 60 minutes @@ -80,14 +80,15 @@ pub trait NodeAPI: Send + Sync { &self, bolt11: String, amount_msat: Option, - ) -> Result; + ) -> Result; async fn send_spontaneous_payment( &self, node_id: String, amount_msat: u64, - ) -> Result; + ) -> Result; async fn start(&self) -> Result<()>; async fn sweep(&self, to_address: String, fee_rate_sats_per_vbyte: u32) -> Result>; + async fn prepare_sweep(&self, req: PrepareSweepRequest) -> Result; async fn start_signer(&self, shutdown: mpsc::Receiver<()>); async fn list_peers(&self) -> Result>; async fn connect_peer(&self, node_id: String, addr: String) -> Result<()>; @@ -1235,6 +1236,23 @@ pub enum BuyBitcoinProvider { Moonpay, } +/// We need to prepare a sweep transaction to know what fee will be charged in satoshis this +/// model holds the request data which consists of the address to sweep to and the fee rate in +/// satoshis per vbyte which will be converted to absolute satoshis. +#[derive(PartialEq, Eq, Debug, Clone, Deserialize, Serialize)] +pub struct PrepareSweepRequest { + pub to_address: String, + pub sats_per_vbyte: u64, +} + +/// We need to prepare a sweep transaction to know what a fee it will be charged in satoshis +/// this model holds the response data, which consists of the weight and the absolute fee in sats +#[derive(PartialEq, Eq, Debug, Clone, Deserialize, Serialize)] +pub struct PrepareSweepResponse { + pub sweep_tx_weight: u64, + pub sweep_tx_fee_sat: u64, +} + impl FromStr for BuyBitcoinProvider { type Err = anyhow::Error; @@ -1248,7 +1266,6 @@ impl FromStr for BuyBitcoinProvider { #[cfg(test)] mod tests { - use super::OpeningFeeParamsMenu; use anyhow::Result; use prost::Message; use rand::random; @@ -1257,6 +1274,8 @@ mod tests { use crate::test_utils::{get_test_ofp, rand_vec_u8}; use crate::OpeningFeeParams; + use super::OpeningFeeParamsMenu; + #[test] fn test_ofp_menu_validation() -> Result<()> { // Menu with one entry is valid diff --git a/libs/sdk-core/src/test_utils.rs b/libs/sdk-core/src/test_utils.rs index e734a6fa4..8f1701415 100644 --- a/libs/sdk-core/src/test_utils.rs +++ b/libs/sdk-core/src/test_utils.rs @@ -34,7 +34,10 @@ use crate::lsp::LspInformation; use crate::models::{FiatAPI, LspAPI, NodeAPI, NodeState, Payment, Swap, SwapperAPI, SyncResponse}; use crate::moonpay::MoonPayApi; use crate::swap::create_submarine_swap_script; -use crate::{parse_invoice, Config, CustomMessage, LNInvoice, PaymentResponse, Peer, RouteHint}; +use crate::{ + parse_invoice, Config, CustomMessage, LNInvoice, PaymentResponse, Peer, PrepareSweepRequest, + PrepareSweepResponse, RouteHint, +}; use crate::{OpeningFeeParams, OpeningFeeParamsMenu}; use crate::{ReceivePaymentRequest, SwapInfo}; @@ -327,6 +330,10 @@ impl NodeAPI for MockNodeAPI { Ok(rand_vec_u8(32)) } + async fn prepare_sweep(&self, _req: PrepareSweepRequest) -> Result { + Err(anyhow!("Not implemented")) + } + async fn start_signer(&self, _shutdown: mpsc::Receiver<()>) {} async fn list_peers(&self) -> Result> { diff --git a/libs/sdk-flutter/ios/Classes/bridge_generated.h b/libs/sdk-flutter/ios/Classes/bridge_generated.h index 8903ad31a..79dad5b4b 100644 --- a/libs/sdk-flutter/ios/Classes/bridge_generated.h +++ b/libs/sdk-flutter/ios/Classes/bridge_generated.h @@ -173,6 +173,11 @@ typedef struct wire_SweepRequest { uint32_t fee_rate_sats_per_vbyte; } wire_SweepRequest; +typedef struct wire_PrepareSweepRequest { + struct wire_uint_8_list *to_address; + uint64_t sats_per_vbyte; +} wire_PrepareSweepRequest; + typedef struct wire_RefundRequest { struct wire_uint_8_list *swap_address; struct wire_uint_8_list *to_address; @@ -275,6 +280,8 @@ void wire_buy_bitcoin(int64_t port_, struct wire_BuyBitcoinRequest *req); void wire_sweep(int64_t port_, struct wire_SweepRequest *req); +void wire_prepare_sweep(int64_t port_, struct wire_PrepareSweepRequest *req); + void wire_list_refundables(int64_t port_); void wire_refund(int64_t port_, struct wire_RefundRequest *req); @@ -319,6 +326,8 @@ struct wire_OpenChannelFeeRequest *new_box_autoadd_open_channel_fee_request_0(vo struct wire_OpeningFeeParams *new_box_autoadd_opening_fee_params_0(void); +struct wire_PrepareSweepRequest *new_box_autoadd_prepare_sweep_request_0(void); + struct wire_ReceiveOnchainRequest *new_box_autoadd_receive_onchain_request_0(void); struct wire_ReceivePaymentRequest *new_box_autoadd_receive_payment_request_0(void); @@ -389,6 +398,7 @@ static int64_t dummy_method_to_enforce_bundling(void) { dummy_var ^= ((int64_t) (void*) wire_receive_onchain); dummy_var ^= ((int64_t) (void*) wire_buy_bitcoin); dummy_var ^= ((int64_t) (void*) wire_sweep); + dummy_var ^= ((int64_t) (void*) wire_prepare_sweep); dummy_var ^= ((int64_t) (void*) wire_list_refundables); dummy_var ^= ((int64_t) (void*) wire_refund); dummy_var ^= ((int64_t) (void*) wire_in_progress_swap); @@ -411,6 +421,7 @@ static int64_t dummy_method_to_enforce_bundling(void) { dummy_var ^= ((int64_t) (void*) new_box_autoadd_node_config_0); dummy_var ^= ((int64_t) (void*) new_box_autoadd_open_channel_fee_request_0); dummy_var ^= ((int64_t) (void*) new_box_autoadd_opening_fee_params_0); + dummy_var ^= ((int64_t) (void*) new_box_autoadd_prepare_sweep_request_0); dummy_var ^= ((int64_t) (void*) new_box_autoadd_receive_onchain_request_0); dummy_var ^= ((int64_t) (void*) new_box_autoadd_receive_payment_request_0); dummy_var ^= ((int64_t) (void*) new_box_autoadd_refund_request_0); diff --git a/libs/sdk-flutter/lib/breez_sdk.dart b/libs/sdk-flutter/lib/breez_sdk.dart index 6a833db2a..8299680ff 100644 --- a/libs/sdk-flutter/lib/breez_sdk.dart +++ b/libs/sdk-flutter/lib/breez_sdk.dart @@ -356,6 +356,17 @@ class BreezSDK { /// Fetches the current recommended fees Future recommendedFees() async => await _lnToolkit.recommendedFees(); + Future prepareSweep({ + required String address, + required int satsPerVbyte, + }) async => + _lnToolkit.prepareSweep( + req: PrepareSweepRequest( + toAddress: address, + satsPerVbyte: satsPerVbyte, + ), + ); + /* CLI API's */ /// Execute a command directly on the NodeAPI interface. diff --git a/libs/sdk-flutter/lib/bridge_generated.dart b/libs/sdk-flutter/lib/bridge_generated.dart index c3fd8ae9d..688a05845 100644 --- a/libs/sdk-flutter/lib/bridge_generated.dart +++ b/libs/sdk-flutter/lib/bridge_generated.dart @@ -197,6 +197,11 @@ abstract class BreezSdkCore { FlutterRustBridgeTaskConstMeta get kSweepConstMeta; + /// See [BreezServices::prepare_sweep] + Future prepareSweep({required PrepareSweepRequest req, dynamic hint}); + + FlutterRustBridgeTaskConstMeta get kPrepareSweepConstMeta; + /// See [BreezServices::list_refundables] Future> listRefundables({dynamic hint}); @@ -1099,6 +1104,31 @@ enum PaymentTypeFilter { ClosedChannels, } +/// We need to prepare a sweep transaction to know what fee will be charged in satoshis this +/// model holds the request data which consists of the address to sweep to and the fee rate in +/// satoshis per vbyte which will be converted to absolute satoshis. +class PrepareSweepRequest { + final String toAddress; + final int satsPerVbyte; + + const PrepareSweepRequest({ + required this.toAddress, + required this.satsPerVbyte, + }); +} + +/// We need to prepare a sweep transaction to know what a fee it will be charged in satoshis +/// this model holds the response data, which consists of the weight and the absolute fee in sats +class PrepareSweepResponse { + final int sweepTxWeight; + final int sweepTxFeeSat; + + const PrepareSweepResponse({ + required this.sweepTxWeight, + required this.sweepTxFeeSat, + }); +} + /// Denominator in an exchange rate class Rate { final String coin; @@ -2160,6 +2190,22 @@ class BreezSdkCoreImpl implements BreezSdkCore { argNames: ["req"], ); + Future prepareSweep({required PrepareSweepRequest req, dynamic hint}) { + var arg0 = _platform.api2wire_box_autoadd_prepare_sweep_request(req); + return _platform.executeNormal(FlutterRustBridgeTask( + callFfi: (port_) => _platform.inner.wire_prepare_sweep(port_, arg0), + parseSuccessData: _wire2api_prepare_sweep_response, + constMeta: kPrepareSweepConstMeta, + argValues: [req], + hint: hint, + )); + } + + FlutterRustBridgeTaskConstMeta get kPrepareSweepConstMeta => const FlutterRustBridgeTaskConstMeta( + debugName: "prepare_sweep", + argNames: ["req"], + ); + Future> listRefundables({dynamic hint}) { return _platform.executeNormal(FlutterRustBridgeTask( callFfi: (port_) => _platform.inner.wire_list_refundables(port_), @@ -3031,6 +3077,15 @@ class BreezSdkCoreImpl implements BreezSdkCore { return PaymentType.values[raw as int]; } + PrepareSweepResponse _wire2api_prepare_sweep_response(dynamic raw) { + final arr = raw as List; + if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}'); + return PrepareSweepResponse( + sweepTxWeight: _wire2api_u64(arr[0]), + sweepTxFeeSat: _wire2api_u64(arr[1]), + ); + } + Rate _wire2api_rate(dynamic raw) { final arr = raw as List; if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}'); @@ -3434,6 +3489,13 @@ class BreezSdkCorePlatform extends FlutterRustBridgeBase { return ptr; } + @protected + ffi.Pointer api2wire_box_autoadd_prepare_sweep_request(PrepareSweepRequest raw) { + final ptr = inner.new_box_autoadd_prepare_sweep_request_0(); + _api_fill_to_wire_prepare_sweep_request(raw, ptr.ref); + return ptr; + } + @protected ffi.Pointer api2wire_box_autoadd_receive_onchain_request( ReceiveOnchainRequest raw) { @@ -3652,6 +3714,11 @@ class BreezSdkCorePlatform extends FlutterRustBridgeBase { _api_fill_to_wire_opening_fee_params(apiObj, wireObj.ref); } + void _api_fill_to_wire_box_autoadd_prepare_sweep_request( + PrepareSweepRequest apiObj, ffi.Pointer wireObj) { + _api_fill_to_wire_prepare_sweep_request(apiObj, wireObj.ref); + } + void _api_fill_to_wire_box_autoadd_receive_onchain_request( ReceiveOnchainRequest apiObj, ffi.Pointer wireObj) { _api_fill_to_wire_receive_onchain_request(apiObj, wireObj.ref); @@ -3823,6 +3890,11 @@ class BreezSdkCorePlatform extends FlutterRustBridgeBase { if (apiObj != null) _api_fill_to_wire_box_autoadd_opening_fee_params(apiObj, wireObj); } + void _api_fill_to_wire_prepare_sweep_request(PrepareSweepRequest apiObj, wire_PrepareSweepRequest wireObj) { + wireObj.to_address = api2wire_String(apiObj.toAddress); + wireObj.sats_per_vbyte = api2wire_u64(apiObj.satsPerVbyte); + } + void _api_fill_to_wire_receive_onchain_request( ReceiveOnchainRequest apiObj, wire_ReceiveOnchainRequest wireObj) { wireObj.opening_fee_params = api2wire_opt_box_autoadd_opening_fee_params(apiObj.openingFeeParams); @@ -4486,6 +4558,22 @@ class BreezSdkCoreWire implements FlutterRustBridgeWireBase { _lookup)>>('wire_sweep'); late final _wire_sweep = _wire_sweepPtr.asFunction)>(); + void wire_prepare_sweep( + int port_, + ffi.Pointer req, + ) { + return _wire_prepare_sweep( + port_, + req, + ); + } + + late final _wire_prepare_sweepPtr = + _lookup)>>( + 'wire_prepare_sweep'); + late final _wire_prepare_sweep = + _wire_prepare_sweepPtr.asFunction)>(); + void wire_list_refundables( int port_, ) { @@ -4742,6 +4830,16 @@ class BreezSdkCoreWire implements FlutterRustBridgeWireBase { late final _new_box_autoadd_opening_fee_params_0 = _new_box_autoadd_opening_fee_params_0Ptr.asFunction Function()>(); + ffi.Pointer new_box_autoadd_prepare_sweep_request_0() { + return _new_box_autoadd_prepare_sweep_request_0(); + } + + late final _new_box_autoadd_prepare_sweep_request_0Ptr = + _lookup Function()>>( + 'new_box_autoadd_prepare_sweep_request_0'); + late final _new_box_autoadd_prepare_sweep_request_0 = _new_box_autoadd_prepare_sweep_request_0Ptr + .asFunction Function()>(); + ffi.Pointer new_box_autoadd_receive_onchain_request_0() { return _new_box_autoadd_receive_onchain_request_0(); } @@ -5156,6 +5254,13 @@ class wire_SweepRequest extends ffi.Struct { external int fee_rate_sats_per_vbyte; } +class wire_PrepareSweepRequest extends ffi.Struct { + external ffi.Pointer to_address; + + @ffi.Uint64() + external int sats_per_vbyte; +} + class wire_RefundRequest extends ffi.Struct { external ffi.Pointer swap_address; diff --git a/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt b/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt index 634fa0d5d..456aadea2 100644 --- a/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt +++ b/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt @@ -1773,6 +1773,80 @@ fun asPaymentFailedDataList(arr: ReadableArray): List { return list } +fun asPrepareSweepRequest(prepareSweepRequest: ReadableMap): PrepareSweepRequest? { + if (!validateMandatoryFields( + prepareSweepRequest, + arrayOf( + "toAddress", + "satsPerVbyte", + ), + ) + ) { + return null + } + val toAddress = prepareSweepRequest.getString("toAddress")!! + val satsPerVbyte = prepareSweepRequest.getDouble("satsPerVbyte").toULong() + return PrepareSweepRequest( + toAddress, + satsPerVbyte, + ) +} + +fun readableMapOf(prepareSweepRequest: PrepareSweepRequest): ReadableMap { + return readableMapOf( + "toAddress" to prepareSweepRequest.toAddress, + "satsPerVbyte" to prepareSweepRequest.satsPerVbyte, + ) +} + +fun asPrepareSweepRequestList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is ReadableMap -> list.add(asPrepareSweepRequest(value)!!) + else -> throw IllegalArgumentException("Unsupported type ${value::class.java.name}") + } + } + return list +} + +fun asPrepareSweepResponse(prepareSweepResponse: ReadableMap): PrepareSweepResponse? { + if (!validateMandatoryFields( + prepareSweepResponse, + arrayOf( + "sweepTxWeight", + "sweepTxFeeSat", + ), + ) + ) { + return null + } + val sweepTxWeight = prepareSweepResponse.getDouble("sweepTxWeight").toULong() + val sweepTxFeeSat = prepareSweepResponse.getDouble("sweepTxFeeSat").toULong() + return PrepareSweepResponse( + sweepTxWeight, + sweepTxFeeSat, + ) +} + +fun readableMapOf(prepareSweepResponse: PrepareSweepResponse): ReadableMap { + return readableMapOf( + "sweepTxWeight" to prepareSweepResponse.sweepTxWeight, + "sweepTxFeeSat" to prepareSweepResponse.sweepTxFeeSat, + ) +} + +fun asPrepareSweepResponseList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is ReadableMap -> list.add(asPrepareSweepResponse(value)!!) + else -> throw IllegalArgumentException("Unsupported type ${value::class.java.name}") + } + } + return list +} + fun asRate(rate: ReadableMap): Rate? { if (!validateMandatoryFields( rate, diff --git a/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKModule.kt b/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKModule.kt index e8142eeda..c37888e41 100644 --- a/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKModule.kt +++ b/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKModule.kt @@ -702,4 +702,23 @@ class BreezSDKModule(reactContext: ReactApplicationContext) : ReactContextBaseJa } } } + + @ReactMethod + fun prepareSweep( + req: ReadableMap, + promise: Promise, + ) { + executor.execute { + try { + val prepareSweepRequest = + asPrepareSweepRequest(req) ?: run { + throw SdkException.Generic("Missing mandatory field req of type PrepareSweepRequest") + } + val res = getBreezServices().prepareSweep(prepareSweepRequest) + promise.resolve(readableMapOf(res)) + } catch (e: SdkException) { + promise.reject(e.javaClass.simpleName, e.message, e) + } + } + } } diff --git a/libs/sdk-react-native/ios/BreezSDKMapper.swift b/libs/sdk-react-native/ios/BreezSDKMapper.swift index ebe5eaa5a..c82c8b219 100644 --- a/libs/sdk-react-native/ios/BreezSDKMapper.swift +++ b/libs/sdk-react-native/ios/BreezSDKMapper.swift @@ -1585,6 +1585,74 @@ class BreezSDKMapper { return paymentFailedDataList.map { v -> [String: Any?] in dictionaryOf(paymentFailedData: v) } } + static func asPrepareSweepRequest(prepareSweepRequest: [String: Any?]) throws -> PrepareSweepRequest { + guard let toAddress = prepareSweepRequest["toAddress"] as? String else { throw SdkError.Generic(message: "Missing mandatory field toAddress for type PrepareSweepRequest") } + guard let satsPerVbyte = prepareSweepRequest["satsPerVbyte"] as? UInt64 else { throw SdkError.Generic(message: "Missing mandatory field satsPerVbyte for type PrepareSweepRequest") } + + return PrepareSweepRequest( + toAddress: toAddress, + satsPerVbyte: satsPerVbyte + ) + } + + static func dictionaryOf(prepareSweepRequest: PrepareSweepRequest) -> [String: Any?] { + return [ + "toAddress": prepareSweepRequest.toAddress, + "satsPerVbyte": prepareSweepRequest.satsPerVbyte, + ] + } + + static func asPrepareSweepRequestList(arr: [Any]) throws -> [PrepareSweepRequest] { + var list = [PrepareSweepRequest]() + for value in arr { + if let val = value as? [String: Any?] { + var prepareSweepRequest = try asPrepareSweepRequest(prepareSweepRequest: val) + list.append(prepareSweepRequest) + } else { + throw SdkError.Generic(message: "Invalid element type PrepareSweepRequest") + } + } + return list + } + + static func arrayOf(prepareSweepRequestList: [PrepareSweepRequest]) -> [Any] { + return prepareSweepRequestList.map { v -> [String: Any?] in dictionaryOf(prepareSweepRequest: v) } + } + + static func asPrepareSweepResponse(prepareSweepResponse: [String: Any?]) throws -> PrepareSweepResponse { + guard let sweepTxWeight = prepareSweepResponse["sweepTxWeight"] as? UInt64 else { throw SdkError.Generic(message: "Missing mandatory field sweepTxWeight for type PrepareSweepResponse") } + guard let sweepTxFeeSat = prepareSweepResponse["sweepTxFeeSat"] as? UInt64 else { throw SdkError.Generic(message: "Missing mandatory field sweepTxFeeSat for type PrepareSweepResponse") } + + return PrepareSweepResponse( + sweepTxWeight: sweepTxWeight, + sweepTxFeeSat: sweepTxFeeSat + ) + } + + static func dictionaryOf(prepareSweepResponse: PrepareSweepResponse) -> [String: Any?] { + return [ + "sweepTxWeight": prepareSweepResponse.sweepTxWeight, + "sweepTxFeeSat": prepareSweepResponse.sweepTxFeeSat, + ] + } + + static func asPrepareSweepResponseList(arr: [Any]) throws -> [PrepareSweepResponse] { + var list = [PrepareSweepResponse]() + for value in arr { + if let val = value as? [String: Any?] { + var prepareSweepResponse = try asPrepareSweepResponse(prepareSweepResponse: val) + list.append(prepareSweepResponse) + } else { + throw SdkError.Generic(message: "Invalid element type PrepareSweepResponse") + } + } + return list + } + + static func arrayOf(prepareSweepResponseList: [PrepareSweepResponse]) -> [Any] { + return prepareSweepResponseList.map { v -> [String: Any?] in dictionaryOf(prepareSweepResponse: v) } + } + static func asRate(rate: [String: Any?]) throws -> Rate { guard let coin = rate["coin"] as? String else { throw SdkError.Generic(message: "Missing mandatory field coin for type Rate") } guard let value = rate["value"] as? Double else { throw SdkError.Generic(message: "Missing mandatory field value for type Rate") } diff --git a/libs/sdk-react-native/ios/RNBreezSDK.m b/libs/sdk-react-native/ios/RNBreezSDK.m index a78ad83af..ad8406856 100644 --- a/libs/sdk-react-native/ios/RNBreezSDK.m +++ b/libs/sdk-react-native/ios/RNBreezSDK.m @@ -242,4 +242,10 @@ @interface RCT_EXTERN_MODULE(RNBreezSDK, RCTEventEmitter) reject: (RCTPromiseRejectBlock)reject ) +RCT_EXTERN_METHOD( + prepareSweep: (NSDictionary*)req + resolve: (RCTPromiseResolveBlock)resolve + reject: (RCTPromiseRejectBlock)reject +) + @end \ No newline at end of file diff --git a/libs/sdk-react-native/ios/RNBreezSDK.swift b/libs/sdk-react-native/ios/RNBreezSDK.swift index 596a3fbc0..af98d4152 100644 --- a/libs/sdk-react-native/ios/RNBreezSDK.swift +++ b/libs/sdk-react-native/ios/RNBreezSDK.swift @@ -502,6 +502,17 @@ class RNBreezSDK: RCTEventEmitter { } } + @objc(prepareSweep:resolve:reject:) + func prepareSweep(_ req: [String: Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + do { + let prepareSweepRequest = try BreezSDKMapper.asPrepareSweepRequest(prepareSweepRequest: req) + var res = try getBreezServices().prepareSweep(req: prepareSweepRequest) + resolve(BreezSDKMapper.dictionaryOf(prepareSweepResponse: res)) + } catch let err { + rejectErr(err: err, reject: reject) + } + } + func rejectErr(err: Error, reject: @escaping RCTPromiseRejectBlock) { var errorCode = "Generic" var message = "\(err)" diff --git a/libs/sdk-react-native/src/index.ts b/libs/sdk-react-native/src/index.ts index 9a63b0fea..7272cdb2b 100644 --- a/libs/sdk-react-native/src/index.ts +++ b/libs/sdk-react-native/src/index.ts @@ -286,6 +286,16 @@ export type PaymentFailedData = { invoice?: LnInvoice } +export type PrepareSweepRequest = { + toAddress: string + satsPerVbyte: number +} + +export type PrepareSweepResponse = { + sweepTxWeight: number + sweepTxFeeSat: number +} + export type Rate = { coin: string value: number @@ -882,3 +892,8 @@ export const buyBitcoin = async (req: BuyBitcoinRequest): Promise => { + const response = await BreezSDK.prepareSweep(req) + return response +} diff --git a/tools/sdk-cli/Cargo.lock b/tools/sdk-cli/Cargo.lock index d74bf55c7..421ef13da 100644 --- a/tools/sdk-cli/Cargo.lock +++ b/tools/sdk-cli/Cargo.lock @@ -478,6 +478,7 @@ dependencies = [ "ecies", "env_logger 0.10.0", "flutter_rust_bridge", + "futures", "gl-client", "hex", "lazy_static", @@ -2377,9 +2378,21 @@ dependencies = [ [[package]] name = "regex" -version = "1.8.4" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81bc1d4caf89fac26a70747fe603c130093b53c773888797a6329091246d651a" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0ab3ca65655bb1e41f2a8c8cd662eb4fb035e67c3f78da1d61dffe89d07300f" +checksum = "fed1ceff11a1dddaee50c9dc8e4938bd106e9d89ae372f192311e7da498e3b69" dependencies = [ "aho-corasick", "memchr", @@ -2388,9 +2401,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.7.2" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "436b050e76ed2903236f032a59761c1eb99e1b0aead2c257922771dab1fc8c78" +checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" [[package]] name = "reqwest" diff --git a/tools/sdk-cli/src/command_handlers.rs b/tools/sdk-cli/src/command_handlers.rs index 27c4937bc..2f397fd5d 100644 --- a/tools/sdk-cli/src/command_handlers.rs +++ b/tools/sdk-cli/src/command_handlers.rs @@ -115,7 +115,7 @@ pub(crate) async fn handle_command( } Commands::Sync {} => { sdk()?.sync().await?; - Ok("Sync finished succesfully".to_string()) + Ok("Sync finished successfully".to_string()) } Commands::Parse { input } => parse(&input) .await @@ -232,12 +232,24 @@ pub(crate) async fn handle_command( } Commands::Sweep { to_address, - sat_per_vbyte: sat_per_byte, + fee_rate_sats_per_vbyte, } => { sdk()? .sweep(SweepRequest { to_address, - fee_rate_sats_per_vbyte: sat_per_byte, + fee_rate_sats_per_vbyte, + }) + .await?; + Ok("Onchain funds were swept successfully".to_string()) + } + Commands::PrepareSweep { + to_address, + sats_per_vbyte, + } => { + sdk()? + .sweep(SweepRequest { + to_address, + fee_rate_sats_per_vbyte: sats_per_vbyte, }) .await?; Ok("Onchain funds were swept succesfully".to_string()) @@ -248,7 +260,7 @@ pub(crate) async fn handle_command( } Commands::ConnectLSP { lsp_id } => { sdk()?.connect_lsp(lsp_id).await?; - Ok("LSP connected succesfully".to_string()) + Ok("LSP connected successfully".to_string()) } Commands::OpenChannelFee { amount_msat, diff --git a/tools/sdk-cli/src/commands.rs b/tools/sdk-cli/src/commands.rs index 8d6ea29b6..ac828f173 100644 --- a/tools/sdk-cli/src/commands.rs +++ b/tools/sdk-cli/src/commands.rs @@ -142,7 +142,16 @@ pub(crate) enum Commands { to_address: String, /// The fee rate for the sweep transaction - sat_per_vbyte: u32, + fee_rate_sats_per_vbyte: u32, + }, + + /// Calculate the fee (in sats) for a potential transaction + PrepareSweep { + /// The destination address + to_address: String, + + /// The fee rate for the transaction in vbyte/sats + sats_per_vbyte: u32, }, /// List available LSPs From 3a3975956228231e7891d76e8a1f92d6886664a9 Mon Sep 17 00:00:00 2001 From: Ross Savage Date: Wed, 25 Oct 2023 16:27:21 +0200 Subject: [PATCH 08/48] Bump example app to 0.2.7 --- libs/sdk-react-native/example/package.json | 2 +- libs/sdk-react-native/example/yarn.lock | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libs/sdk-react-native/example/package.json b/libs/sdk-react-native/example/package.json index 7e5e32104..1a4ed8db4 100644 --- a/libs/sdk-react-native/example/package.json +++ b/libs/sdk-react-native/example/package.json @@ -13,7 +13,7 @@ "rebuild": "rm -rf node_modules && yarn && yarn pods" }, "dependencies": { - "@breeztech/react-native-breez-sdk": "0.2.5", + "@breeztech/react-native-breez-sdk": "0.2.7", "@dreson4/react-native-quick-bip39": "^0.0.5", "react": "18.1.0", "react-native": "0.70.6", diff --git a/libs/sdk-react-native/example/yarn.lock b/libs/sdk-react-native/example/yarn.lock index 4251d7818..e3b91741d 100644 --- a/libs/sdk-react-native/example/yarn.lock +++ b/libs/sdk-react-native/example/yarn.lock @@ -914,8 +914,10 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@breeztech/react-native-breez-sdk@file:..": - version "0.2.5" +"@breeztech/react-native-breez-sdk@0.2.7": + version "0.2.7" + resolved "https://registry.yarnpkg.com/@breeztech/react-native-breez-sdk/-/react-native-breez-sdk-0.2.7.tgz#8c2fae69df11e43852f0744b1f39f45057a7cabd" + integrity sha512-/d0O54YNzd6dIjPVu6uX3iBFXu54EjunUvdT0cWsaIXUXfAlVyr3DLio4dQ+PDSMQXM3vtaggC3MBFGeGfq9OA== "@cnakazawa/watch@^1.0.3": version "1.0.4" From 8c2b75334bc9f330f73c955a5f4386909bef80d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Granh=C3=A3o?= Date: Mon, 23 Oct 2023 16:58:20 +0100 Subject: [PATCH 09/48] Implement `prepare_refund()` --- libs/sdk-bindings/src/breez_sdk.udl | 14 ++ libs/sdk-bindings/src/uniffi_binding.rs | 23 +-- libs/sdk-core/src/binding.rs | 17 ++- libs/sdk-core/src/breez_services.rs | 8 ++ libs/sdk-core/src/bridge_generated.io.rs | 49 +++++++ libs/sdk-core/src/bridge_generated.rs | 29 ++++ libs/sdk-core/src/models.rs | 11 ++ libs/sdk-core/src/swap.rs | 132 +++++++++++++++--- .../ios/Classes/bridge_generated.h | 12 ++ libs/sdk-flutter/lib/bridge_generated.dart | 107 ++++++++++++++ .../main/java/com/breezsdk/BreezSDKMapper.kt | 78 +++++++++++ .../main/java/com/breezsdk/BreezSDKModule.kt | 19 +++ .../sdk-react-native/ios/BreezSDKMapper.swift | 71 ++++++++++ libs/sdk-react-native/ios/RNBreezSDK.m | 6 + libs/sdk-react-native/ios/RNBreezSDK.swift | 11 ++ libs/sdk-react-native/src/index.ts | 16 +++ tools/sdk-cli/src/command_handlers.rs | 23 ++- tools/sdk-cli/src/commands.rs | 7 + 18 files changed, 595 insertions(+), 38 deletions(-) diff --git a/libs/sdk-bindings/src/breez_sdk.udl b/libs/sdk-bindings/src/breez_sdk.udl index 8d6d07b33..170866871 100644 --- a/libs/sdk-bindings/src/breez_sdk.udl +++ b/libs/sdk-bindings/src/breez_sdk.udl @@ -580,6 +580,17 @@ dictionary SendOnchainResponse { ReverseSwapInfo reverse_swap_info; }; +dictionary PrepareRefundRequest { + string swap_address; + string to_address; + u32 sat_per_vbyte; +}; + +dictionary PrepareRefundResponse { + u32 refund_tx_weight; + u64 refund_tx_fee_sat; +}; + dictionary RefundRequest { string swap_address; string to_address; @@ -673,6 +684,9 @@ interface BlockingBreezServices { [Throws=SdkError] sequence list_refundables(); + [Throws=SdkError] + PrepareRefundResponse prepare_refund(PrepareRefundRequest req); + [Throws=SdkError] RefundResponse refund(RefundRequest req); diff --git a/libs/sdk-bindings/src/uniffi_binding.rs b/libs/sdk-bindings/src/uniffi_binding.rs index 0ad41147f..f0f43b55c 100644 --- a/libs/sdk-bindings/src/uniffi_binding.rs +++ b/libs/sdk-bindings/src/uniffi_binding.rs @@ -12,14 +12,14 @@ use breez_sdk_core::{ LocaleOverrides, LocalizedName, LogEntry, LogStream, LspInformation, MessageSuccessActionData, MetadataItem, Network, NodeConfig, NodeState, OpenChannelFeeRequest, OpenChannelFeeResponse, OpeningFeeParams, OpeningFeeParamsMenu, Payment, PaymentDetails, PaymentFailedData, - PaymentStatus, PaymentType, PaymentTypeFilter, PrepareSweepRequest, PrepareSweepResponse, Rate, - ReceiveOnchainRequest, ReceivePaymentRequest, ReceivePaymentResponse, RecommendedFees, - RefundRequest, RefundResponse, ReverseSwapFeesRequest, ReverseSwapInfo, ReverseSwapPairInfo, - ReverseSwapStatus, RouteHint, RouteHintHop, SendOnchainRequest, SendOnchainResponse, - SendPaymentRequest, SendPaymentResponse, SendSpontaneousPaymentRequest, SignMessageRequest, - SignMessageResponse, StaticBackupRequest, StaticBackupResponse, SuccessActionProcessed, - SwapInfo, SwapStatus, SweepRequest, SweepResponse, Symbol, UnspentTransactionOutput, - UrlSuccessActionData, + PaymentStatus, PaymentType, PaymentTypeFilter, PrepareRefundRequest, PrepareRefundResponse, + PrepareSweepRequest, PrepareSweepResponse, Rate, ReceiveOnchainRequest, ReceivePaymentRequest, + ReceivePaymentResponse, RecommendedFees, RefundRequest, RefundResponse, ReverseSwapFeesRequest, + ReverseSwapInfo, ReverseSwapPairInfo, ReverseSwapStatus, RouteHint, RouteHintHop, + SendOnchainRequest, SendOnchainResponse, SendPaymentRequest, SendPaymentResponse, + SendSpontaneousPaymentRequest, SignMessageRequest, SignMessageResponse, StaticBackupRequest, + StaticBackupResponse, SuccessActionProcessed, SwapInfo, SwapStatus, SweepRequest, + SweepResponse, Symbol, UnspentTransactionOutput, UrlSuccessActionData, }; use log::{Level, LevelFilter, Metadata, Record}; use once_cell::sync::{Lazy, OnceCell}; @@ -245,6 +245,13 @@ impl BlockingBreezServices { .map_err(|e| e.into()) } + // prepare a refund transaction for a failed/expired swap + // optionally used to know fees before calling `refund()` + pub fn prepare_refund(&self, req: PrepareRefundRequest) -> SdkResult { + rt().block_on(self.breez_services.prepare_refund(req)) + .map_err(|e| e.into()) + } + // construct and broadcast a refund transaction for a faile/expired swap pub fn refund(&self, req: RefundRequest) -> SdkResult { rt().block_on(self.breez_services.refund(req)) diff --git a/libs/sdk-core/src/binding.rs b/libs/sdk-core/src/binding.rs index 9608a5441..06fa4b1f5 100644 --- a/libs/sdk-core/src/binding.rs +++ b/libs/sdk-core/src/binding.rs @@ -32,12 +32,12 @@ use crate::{ BackupStatus, BuyBitcoinRequest, BuyBitcoinResponse, CheckMessageRequest, CheckMessageResponse, EnvironmentType, ListPaymentsRequest, LnUrlCallbackStatus, LnUrlPayRequest, LnUrlWithdrawRequest, LnUrlWithdrawResult, NodeConfig, OpenChannelFeeRequest, - OpenChannelFeeResponse, PrepareSweepRequest, PrepareSweepResponse, ReceiveOnchainRequest, - ReceivePaymentRequest, ReceivePaymentResponse, RefundRequest, RefundResponse, - ReverseSwapFeesRequest, ReverseSwapInfo, ReverseSwapPairInfo, SendOnchainRequest, - SendOnchainResponse, SendPaymentRequest, SendPaymentResponse, SendSpontaneousPaymentRequest, - SignMessageRequest, SignMessageResponse, StaticBackupRequest, StaticBackupResponse, - SweepRequest, SweepResponse, + OpenChannelFeeResponse, PrepareRefundRequest, PrepareRefundResponse, PrepareSweepRequest, + PrepareSweepResponse, ReceiveOnchainRequest, ReceivePaymentRequest, ReceivePaymentResponse, + RefundRequest, RefundResponse, ReverseSwapFeesRequest, ReverseSwapInfo, ReverseSwapPairInfo, + SendOnchainRequest, SendOnchainResponse, SendPaymentRequest, SendPaymentResponse, + SendSpontaneousPaymentRequest, SignMessageRequest, SignMessageResponse, StaticBackupRequest, + StaticBackupResponse, SweepRequest, SweepResponse, }; /* @@ -314,6 +314,11 @@ pub fn list_refundables() -> Result> { block_on(async { get_breez_services().await?.list_refundables().await }) } +/// See [BreezServices::prepare_refund] +pub fn prepare_refund(req: PrepareRefundRequest) -> Result { + block_on(async { get_breez_services().await?.prepare_refund(req).await }) +} + /// See [BreezServices::refund] pub fn refund(req: RefundRequest) -> Result { block_on(async { get_breez_services().await?.refund(req).await }) diff --git a/libs/sdk-core/src/breez_services.rs b/libs/sdk-core/src/breez_services.rs index b956d4eba..48e5da435 100644 --- a/libs/sdk-core/src/breez_services.rs +++ b/libs/sdk-core/src/breez_services.rs @@ -682,6 +682,14 @@ impl BreezServices { self.btc_receive_swapper.list_refundables() } + /// Prepares a refund transaction for a failed/expired swap. + /// + /// Can optionally be used before [BreezServices::refund] to know how much fees will be paid + /// to perform the refund. + pub async fn prepare_refund(&self, req: PrepareRefundRequest) -> Result { + self.btc_receive_swapper.prepare_refund_swap(req).await + } + /// Construct and broadcast a refund transaction for a failed/expired swap /// /// Returns the txid of the refund transaction. diff --git a/libs/sdk-core/src/bridge_generated.io.rs b/libs/sdk-core/src/bridge_generated.io.rs index 546393469..de1bced64 100644 --- a/libs/sdk-core/src/bridge_generated.io.rs +++ b/libs/sdk-core/src/bridge_generated.io.rs @@ -199,6 +199,11 @@ pub extern "C" fn wire_list_refundables(port_: i64) { wire_list_refundables_impl(port_) } +#[no_mangle] +pub extern "C" fn wire_prepare_refund(port_: i64, req: *mut wire_PrepareRefundRequest) { + wire_prepare_refund_impl(port_, req) +} + #[no_mangle] pub extern "C" fn wire_refund(port_: i64, req: *mut wire_RefundRequest) { wire_refund_impl(port_, req) @@ -306,6 +311,11 @@ pub extern "C" fn new_box_autoadd_opening_fee_params_0() -> *mut wire_OpeningFee support::new_leak_box_ptr(wire_OpeningFeeParams::new_with_null_ptr()) } +#[no_mangle] +pub extern "C" fn new_box_autoadd_prepare_refund_request_0() -> *mut wire_PrepareRefundRequest { + support::new_leak_box_ptr(wire_PrepareRefundRequest::new_with_null_ptr()) +} + #[no_mangle] pub extern "C" fn new_box_autoadd_prepare_sweep_request_0() -> *mut wire_PrepareSweepRequest { support::new_leak_box_ptr(wire_PrepareSweepRequest::new_with_null_ptr()) @@ -484,6 +494,12 @@ impl Wire2Api for *mut wire_OpeningFeeParams { Wire2Api::::wire2api(*wrap).into() } } +impl Wire2Api for *mut wire_PrepareRefundRequest { + fn wire2api(self) -> PrepareRefundRequest { + let wrap = unsafe { support::box_from_leak_ptr(self) }; + Wire2Api::::wire2api(*wrap).into() + } +} impl Wire2Api for *mut wire_PrepareSweepRequest { fn wire2api(self) -> PrepareSweepRequest { let wrap = unsafe { support::box_from_leak_ptr(self) }; @@ -721,6 +737,15 @@ impl Wire2Api for wire_OpeningFeeParams { } } +impl Wire2Api for wire_PrepareRefundRequest { + fn wire2api(self) -> PrepareRefundRequest { + PrepareRefundRequest { + swap_address: self.swap_address.wire2api(), + to_address: self.to_address.wire2api(), + sat_per_vbyte: self.sat_per_vbyte.wire2api(), + } + } +} impl Wire2Api for wire_PrepareSweepRequest { fn wire2api(self) -> PrepareSweepRequest { PrepareSweepRequest { @@ -951,6 +976,14 @@ pub struct wire_OpeningFeeParams { promise: *mut wire_uint_8_list, } +#[repr(C)] +#[derive(Clone)] +pub struct wire_PrepareRefundRequest { + swap_address: *mut wire_uint_8_list, + to_address: *mut wire_uint_8_list, + sat_per_vbyte: u32, +} + #[repr(C)] #[derive(Clone)] pub struct wire_PrepareSweepRequest { @@ -1317,6 +1350,22 @@ impl Default for wire_OpeningFeeParams { } } +impl NewWithNullPtr for wire_PrepareRefundRequest { + fn new_with_null_ptr() -> Self { + Self { + swap_address: core::ptr::null_mut(), + to_address: core::ptr::null_mut(), + sat_per_vbyte: Default::default(), + } + } +} + +impl Default for wire_PrepareRefundRequest { + fn default() -> Self { + Self::new_with_null_ptr() + } +} + impl NewWithNullPtr for wire_PrepareSweepRequest { fn new_with_null_ptr() -> Self { Self { diff --git a/libs/sdk-core/src/bridge_generated.rs b/libs/sdk-core/src/bridge_generated.rs index 39fe66edd..1e377b140 100644 --- a/libs/sdk-core/src/bridge_generated.rs +++ b/libs/sdk-core/src/bridge_generated.rs @@ -79,6 +79,8 @@ use crate::models::PaymentDetails; use crate::models::PaymentStatus; use crate::models::PaymentType; use crate::models::PaymentTypeFilter; +use crate::models::PrepareRefundRequest; +use crate::models::PrepareRefundResponse; use crate::models::PrepareSweepRequest; use crate::models::PrepareSweepResponse; use crate::models::ReceiveOnchainRequest; @@ -593,6 +595,22 @@ fn wire_list_refundables_impl(port_: MessagePort) { move || move |task_callback| list_refundables(), ) } +fn wire_prepare_refund_impl( + port_: MessagePort, + req: impl Wire2Api + UnwindSafe, +) { + FLUTTER_RUST_BRIDGE_HANDLER.wrap( + WrapInfo { + debug_name: "prepare_refund", + port: Some(port_), + mode: FfiCallMode::Normal, + }, + move || { + let api_req = req.wire2api(); + move |task_callback| prepare_refund(api_req) + }, + ) +} fn wire_refund_impl(port_: MessagePort, req: impl Wire2Api + UnwindSafe) { FLUTTER_RUST_BRIDGE_HANDLER.wrap( WrapInfo { @@ -1279,6 +1297,17 @@ impl support::IntoDart for PaymentType { } } impl support::IntoDartExceptPrimitive for PaymentType {} +impl support::IntoDart for PrepareRefundResponse { + fn into_dart(self) -> support::DartAbi { + vec![ + self.refund_tx_weight.into_dart(), + self.refund_tx_fee_sat.into_dart(), + ] + .into_dart() + } +} +impl support::IntoDartExceptPrimitive for PrepareRefundResponse {} + impl support::IntoDart for PrepareSweepResponse { fn into_dart(self) -> support::DartAbi { vec![ diff --git a/libs/sdk-core/src/models.rs b/libs/sdk-core/src/models.rs index 079b07b6d..a4b09fdb8 100644 --- a/libs/sdk-core/src/models.rs +++ b/libs/sdk-core/src/models.rs @@ -842,12 +842,23 @@ pub struct SendOnchainResponse { pub reverse_swap_info: ReverseSwapInfo, } +pub struct PrepareRefundRequest { + pub swap_address: String, + pub to_address: String, + pub sat_per_vbyte: u32, +} + pub struct RefundRequest { pub swap_address: String, pub to_address: String, pub sat_per_vbyte: u32, } +pub struct PrepareRefundResponse { + pub refund_tx_weight: u32, + pub refund_tx_fee_sat: u64, +} + pub struct RefundResponse { pub refund_tx_id: String, } diff --git a/libs/sdk-core/src/swap.rs b/libs/sdk-core/src/swap.rs index c80d9a0f9..5d3b93c86 100644 --- a/libs/sdk-core/src/swap.rs +++ b/libs/sdk-core/src/swap.rs @@ -5,8 +5,8 @@ use crate::binding::parse_invoice; use crate::chain::{get_utxos, AddressUtxos, ChainService, MempoolSpace, OnchainTx}; use crate::grpc::{AddFundInitRequest, GetSwapPaymentRequest}; use crate::{ - OpeningFeeParams, ReceivePaymentRequest, RefundRequest, RefundResponse, - SWAP_PAYMENT_FEE_EXPIRY_SECONDS, + OpeningFeeParams, PrepareRefundRequest, PrepareRefundResponse, ReceivePaymentRequest, + RefundRequest, RefundResponse, SWAP_PAYMENT_FEE_EXPIRY_SECONDS, }; use anyhow::{anyhow, Result}; use bitcoin::blockdata::constants::WITNESS_SCALE_FACTOR; @@ -434,6 +434,31 @@ impl BTCReceiveSwap { self.swapper_api.complete_swap(payreq.clone()).await } + pub(crate) async fn prepare_refund_swap( + &self, + req: PrepareRefundRequest, + ) -> Result { + let swap_info = self + .persister + .get_swap_info_by_address(req.swap_address.clone())? + .ok_or_else(|| anyhow!(format!("swap address {} was not found", req.swap_address)))?; + + let transactions = self + .chain_service + .address_transactions(req.swap_address.clone()) + .await?; + let utxos = get_utxos(req.swap_address, transactions)?; + + let refund_tx = prepare_refund_tx(&utxos, req.to_address, swap_info.lock_height as u32)?; + + let refund_tx_weight = compute_refund_tx_weight(&refund_tx); + let refund_tx_fee_sat = compute_tx_fee(refund_tx_weight, req.sat_per_vbyte); + Ok(PrepareRefundResponse { + refund_tx_weight, + refund_tx_fee_sat, + }) + } + // refund_swap is the user way to receive on-chain refund for failed swaps. pub(crate) async fn refund_swap(&self, req: RefundRequest) -> Result { let swap_info = self @@ -541,22 +566,28 @@ pub(crate) fn create_submarine_swap_script( .into_script()) } -/// Creating the refund transaction that is to be used by the user in case where the swap has -/// expired. -fn create_refund_tx( - utxos: AddressUtxos, - private_key: Vec, +fn compute_refund_tx_weight(tx: &Transaction) -> u32 { + #[allow(clippy::identity_op)] // Allow "+ 0" term in sum below for clarity + let refund_witness_input_size: u32 = 1 + 1 + 73 + 1 + 0 + 1 + 100; + tx.strippedsize() as u32 * WITNESS_SCALE_FACTOR as u32 + + refund_witness_input_size * tx.input.len() as u32 +} + +fn compute_tx_fee(tx_weight: u32, sat_per_vbyte: u32) -> u64 { + (tx_weight * sat_per_vbyte / WITNESS_SCALE_FACTOR as u32) as u64 +} + +/// Prepare the refund transaction that is to be used by the user in case where the swap has +/// expired +fn prepare_refund_tx( + utxos: &AddressUtxos, to_address: String, lock_delay: u32, - input_script: &Script, - sat_per_vbyte: u32, -) -> Result> { +) -> Result { if utxos.confirmed.is_empty() { return Err(anyhow!("must have at least one input")); } - info!("creating refund tx sat_per_vbyte {}", sat_per_vbyte); - let lock_time = utxos.confirmed.iter().fold(0, |accum, item| { let confirmed_height = item.block_height.unwrap(); if accum >= confirmed_height + lock_delay { @@ -591,22 +622,37 @@ fn create_refund_tx( }]; // construct the transaction - let mut tx = Transaction { + let tx = Transaction { version: 2, lock_time: bitcoin::PackedLockTime(lock_time), input: txins.clone(), output: tx_out, }; - #[allow(clippy::identity_op)] // Allow "+ 0" term in sum below for clarity - let refund_witness_input_size: u32 = 1 + 1 + 73 + 1 + 0 + 1 + 100; - let tx_weight = tx.strippedsize() as u32 * WITNESS_SCALE_FACTOR as u32 - + refund_witness_input_size * txins.len() as u32; - let fees: u64 = (tx_weight * sat_per_vbyte / WITNESS_SCALE_FACTOR as u32) as u64; - if fees >= confirmed_amount { + Ok(tx) +} + +/// Creating the refund transaction that is to be used by the user in case where the swap has +/// expired. +fn create_refund_tx( + utxos: AddressUtxos, + private_key: Vec, + to_address: String, + lock_delay: u32, + input_script: &Script, + sat_per_vbyte: u32, +) -> Result> { + info!("creating refund tx sat_per_vbyte {}", sat_per_vbyte); + + let mut tx = prepare_refund_tx(&utxos, to_address, lock_delay)?; + + let tx_weight = compute_refund_tx_weight(&tx); + let fees = compute_tx_fee(tx_weight, sat_per_vbyte); + + if fees >= tx.output[0].value { return Err(anyhow!("insufficient funds to pay fees")); } - tx.output[0].value = confirmed_amount - fees; + tx.output[0].value -= fees; let scpt = Secp256k1::signing_only(); @@ -645,13 +691,15 @@ mod tests { use std::{sync::Arc, vec}; use anyhow::Result; + use bitcoin::consensus::deserialize; use bitcoin::hashes::{hex::FromHex, sha256}; use bitcoin::{ secp256k1::{Message, PublicKey, Secp256k1, SecretKey}, - OutPoint, Txid, + OutPoint, Transaction, Txid, }; use crate::chain::{AddressUtxos, Utxo}; + use crate::swap::{compute_refund_tx_weight, compute_tx_fee, prepare_refund_tx}; use crate::test_utils::get_test_ofp; use crate::{ breez_services::tests::get_dummy_node_state, @@ -927,6 +975,48 @@ mod tests { Ok(()) } + #[test] + fn test_prepare_refund() -> Result<()> { + // test parameters + let to_address = String::from("bc1qvhykeqcpdzu0pdvy99xnh9ckhwzcfskct6h6l2"); + let lock_time = 288; + + let utxos = AddressUtxos { + confirmed: vec![Utxo { + out: OutPoint { + txid: Txid::from_hex( + "1ab3fe9f94ff1332d6f198484c3677832d1162781f86ce85f6d7587fa97f0330", + )?, + vout: 0, + }, + value: 20000, + block_height: Some(700000), + }], + unconfirmed: vec![], + }; + + let prepared_refund_tx = prepare_refund_tx(&utxos, to_address, lock_time as u32)?; + + // Get the same `Transaction` used in `test_refund()` + let raw_tx_bytes = hex::decode("0200000000010130037fa97f58d7f685ce861f7862112d8377364c4898f1d63213ff949ffeb31a00000000002001000001204e00000000000016001465c96c830168b8f0b584294d3b9716bb8584c2d80347304402203285efcf44640551a56c53bde677988964ef1b4d11182d5d6634096042c320120220227b625f7827993aca5b9d2f4690c5e5fae44d8d42fdd5f3778ba21df8ba7c7b010064a9148a486ff2e31d6158bf39e2608864d63fefd09d5b876321024d4b6cd1361032ca9bd2aeb9d900aa4d45d9ead80ac9423374c451a7254d076667022001b27521031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f68ac80af0a00").unwrap(); + let tx: Transaction = deserialize(&raw_tx_bytes).unwrap(); + let weight = Transaction::weight(&tx) as u64; + + let refund_tx_weight = compute_refund_tx_weight(&prepared_refund_tx); + assert_eq!(refund_tx_weight, weight as u32); + + let refund_tx_fee_sat = compute_tx_fee(refund_tx_weight, 0); + assert_eq!(refund_tx_fee_sat, 0); + + let refund_tx_fee_sat = compute_tx_fee(refund_tx_weight, 1); + assert_eq!(refund_tx_fee_sat, weight / 4); + + let refund_tx_fee_sat = compute_tx_fee(refund_tx_weight, 20); + assert_eq!(refund_tx_fee_sat, weight * 20 / 4); + + Ok(()) + } + #[test] fn test_refund() -> Result<()> { // test parameters diff --git a/libs/sdk-flutter/ios/Classes/bridge_generated.h b/libs/sdk-flutter/ios/Classes/bridge_generated.h index 79dad5b4b..1297ad312 100644 --- a/libs/sdk-flutter/ios/Classes/bridge_generated.h +++ b/libs/sdk-flutter/ios/Classes/bridge_generated.h @@ -178,6 +178,12 @@ typedef struct wire_PrepareSweepRequest { uint64_t sats_per_vbyte; } wire_PrepareSweepRequest; +typedef struct wire_PrepareRefundRequest { + struct wire_uint_8_list *swap_address; + struct wire_uint_8_list *to_address; + uint32_t sat_per_vbyte; +} wire_PrepareRefundRequest; + typedef struct wire_RefundRequest { struct wire_uint_8_list *swap_address; struct wire_uint_8_list *to_address; @@ -284,6 +290,8 @@ void wire_prepare_sweep(int64_t port_, struct wire_PrepareSweepRequest *req); void wire_list_refundables(int64_t port_); +void wire_prepare_refund(int64_t port_, struct wire_PrepareRefundRequest *req); + void wire_refund(int64_t port_, struct wire_RefundRequest *req); void wire_in_progress_swap(int64_t port_); @@ -326,6 +334,8 @@ struct wire_OpenChannelFeeRequest *new_box_autoadd_open_channel_fee_request_0(vo struct wire_OpeningFeeParams *new_box_autoadd_opening_fee_params_0(void); +struct wire_PrepareRefundRequest *new_box_autoadd_prepare_refund_request_0(void); + struct wire_PrepareSweepRequest *new_box_autoadd_prepare_sweep_request_0(void); struct wire_ReceiveOnchainRequest *new_box_autoadd_receive_onchain_request_0(void); @@ -400,6 +410,7 @@ static int64_t dummy_method_to_enforce_bundling(void) { dummy_var ^= ((int64_t) (void*) wire_sweep); dummy_var ^= ((int64_t) (void*) wire_prepare_sweep); dummy_var ^= ((int64_t) (void*) wire_list_refundables); + dummy_var ^= ((int64_t) (void*) wire_prepare_refund); dummy_var ^= ((int64_t) (void*) wire_refund); dummy_var ^= ((int64_t) (void*) wire_in_progress_swap); dummy_var ^= ((int64_t) (void*) wire_in_progress_reverse_swaps); @@ -421,6 +432,7 @@ static int64_t dummy_method_to_enforce_bundling(void) { dummy_var ^= ((int64_t) (void*) new_box_autoadd_node_config_0); dummy_var ^= ((int64_t) (void*) new_box_autoadd_open_channel_fee_request_0); dummy_var ^= ((int64_t) (void*) new_box_autoadd_opening_fee_params_0); + dummy_var ^= ((int64_t) (void*) new_box_autoadd_prepare_refund_request_0); dummy_var ^= ((int64_t) (void*) new_box_autoadd_prepare_sweep_request_0); dummy_var ^= ((int64_t) (void*) new_box_autoadd_receive_onchain_request_0); dummy_var ^= ((int64_t) (void*) new_box_autoadd_receive_payment_request_0); diff --git a/libs/sdk-flutter/lib/bridge_generated.dart b/libs/sdk-flutter/lib/bridge_generated.dart index 688a05845..1bd42d724 100644 --- a/libs/sdk-flutter/lib/bridge_generated.dart +++ b/libs/sdk-flutter/lib/bridge_generated.dart @@ -207,6 +207,11 @@ abstract class BreezSdkCore { FlutterRustBridgeTaskConstMeta get kListRefundablesConstMeta; + /// See [BreezServices::prepare_refund] + Future prepareRefund({required PrepareRefundRequest req, dynamic hint}); + + FlutterRustBridgeTaskConstMeta get kPrepareRefundConstMeta; + /// See [BreezServices::refund] Future refund({required RefundRequest req, dynamic hint}); @@ -1104,6 +1109,28 @@ enum PaymentTypeFilter { ClosedChannels, } +class PrepareRefundRequest { + final String swapAddress; + final String toAddress; + final int satPerVbyte; + + const PrepareRefundRequest({ + required this.swapAddress, + required this.toAddress, + required this.satPerVbyte, + }); +} + +class PrepareRefundResponse { + final int refundTxWeight; + final int refundTxFeeSat; + + const PrepareRefundResponse({ + required this.refundTxWeight, + required this.refundTxFeeSat, + }); +} + /// We need to prepare a sweep transaction to know what fee will be charged in satoshis this /// model holds the request data which consists of the address to sweep to and the fee rate in /// satoshis per vbyte which will be converted to absolute satoshis. @@ -2221,6 +2248,22 @@ class BreezSdkCoreImpl implements BreezSdkCore { argNames: [], ); + Future prepareRefund({required PrepareRefundRequest req, dynamic hint}) { + var arg0 = _platform.api2wire_box_autoadd_prepare_refund_request(req); + return _platform.executeNormal(FlutterRustBridgeTask( + callFfi: (port_) => _platform.inner.wire_prepare_refund(port_, arg0), + parseSuccessData: _wire2api_prepare_refund_response, + constMeta: kPrepareRefundConstMeta, + argValues: [req], + hint: hint, + )); + } + + FlutterRustBridgeTaskConstMeta get kPrepareRefundConstMeta => const FlutterRustBridgeTaskConstMeta( + debugName: "prepare_refund", + argNames: ["req"], + ); + Future refund({required RefundRequest req, dynamic hint}) { var arg0 = _platform.api2wire_box_autoadd_refund_request(req); return _platform.executeNormal(FlutterRustBridgeTask( @@ -3077,6 +3120,15 @@ class BreezSdkCoreImpl implements BreezSdkCore { return PaymentType.values[raw as int]; } + PrepareRefundResponse _wire2api_prepare_refund_response(dynamic raw) { + final arr = raw as List; + if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}'); + return PrepareRefundResponse( + refundTxWeight: _wire2api_u32(arr[0]), + refundTxFeeSat: _wire2api_u64(arr[1]), + ); + } + PrepareSweepResponse _wire2api_prepare_sweep_response(dynamic raw) { final arr = raw as List; if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}'); @@ -3489,6 +3541,14 @@ class BreezSdkCorePlatform extends FlutterRustBridgeBase { return ptr; } + @protected + ffi.Pointer api2wire_box_autoadd_prepare_refund_request( + PrepareRefundRequest raw) { + final ptr = inner.new_box_autoadd_prepare_refund_request_0(); + _api_fill_to_wire_prepare_refund_request(raw, ptr.ref); + return ptr; + } + @protected ffi.Pointer api2wire_box_autoadd_prepare_sweep_request(PrepareSweepRequest raw) { final ptr = inner.new_box_autoadd_prepare_sweep_request_0(); @@ -3714,6 +3774,11 @@ class BreezSdkCorePlatform extends FlutterRustBridgeBase { _api_fill_to_wire_opening_fee_params(apiObj, wireObj.ref); } + void _api_fill_to_wire_box_autoadd_prepare_refund_request( + PrepareRefundRequest apiObj, ffi.Pointer wireObj) { + _api_fill_to_wire_prepare_refund_request(apiObj, wireObj.ref); + } + void _api_fill_to_wire_box_autoadd_prepare_sweep_request( PrepareSweepRequest apiObj, ffi.Pointer wireObj) { _api_fill_to_wire_prepare_sweep_request(apiObj, wireObj.ref); @@ -3890,6 +3955,13 @@ class BreezSdkCorePlatform extends FlutterRustBridgeBase { if (apiObj != null) _api_fill_to_wire_box_autoadd_opening_fee_params(apiObj, wireObj); } + void _api_fill_to_wire_prepare_refund_request( + PrepareRefundRequest apiObj, wire_PrepareRefundRequest wireObj) { + wireObj.swap_address = api2wire_String(apiObj.swapAddress); + wireObj.to_address = api2wire_String(apiObj.toAddress); + wireObj.sat_per_vbyte = api2wire_u32(apiObj.satPerVbyte); + } + void _api_fill_to_wire_prepare_sweep_request(PrepareSweepRequest apiObj, wire_PrepareSweepRequest wireObj) { wireObj.to_address = api2wire_String(apiObj.toAddress); wireObj.sats_per_vbyte = api2wire_u64(apiObj.satsPerVbyte); @@ -4586,6 +4658,22 @@ class BreezSdkCoreWire implements FlutterRustBridgeWireBase { _lookup>('wire_list_refundables'); late final _wire_list_refundables = _wire_list_refundablesPtr.asFunction(); + void wire_prepare_refund( + int port_, + ffi.Pointer req, + ) { + return _wire_prepare_refund( + port_, + req, + ); + } + + late final _wire_prepare_refundPtr = + _lookup)>>( + 'wire_prepare_refund'); + late final _wire_prepare_refund = + _wire_prepare_refundPtr.asFunction)>(); + void wire_refund( int port_, ffi.Pointer req, @@ -4830,6 +4918,16 @@ class BreezSdkCoreWire implements FlutterRustBridgeWireBase { late final _new_box_autoadd_opening_fee_params_0 = _new_box_autoadd_opening_fee_params_0Ptr.asFunction Function()>(); + ffi.Pointer new_box_autoadd_prepare_refund_request_0() { + return _new_box_autoadd_prepare_refund_request_0(); + } + + late final _new_box_autoadd_prepare_refund_request_0Ptr = + _lookup Function()>>( + 'new_box_autoadd_prepare_refund_request_0'); + late final _new_box_autoadd_prepare_refund_request_0 = _new_box_autoadd_prepare_refund_request_0Ptr + .asFunction Function()>(); + ffi.Pointer new_box_autoadd_prepare_sweep_request_0() { return _new_box_autoadd_prepare_sweep_request_0(); } @@ -5261,6 +5359,15 @@ class wire_PrepareSweepRequest extends ffi.Struct { external int sats_per_vbyte; } +class wire_PrepareRefundRequest extends ffi.Struct { + external ffi.Pointer swap_address; + + external ffi.Pointer to_address; + + @ffi.Uint32() + external int sat_per_vbyte; +} + class wire_RefundRequest extends ffi.Struct { external ffi.Pointer swap_address; diff --git a/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt b/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt index 456aadea2..51ba5f0ae 100644 --- a/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt +++ b/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt @@ -1773,6 +1773,84 @@ fun asPaymentFailedDataList(arr: ReadableArray): List { return list } +fun asPrepareRefundRequest(prepareRefundRequest: ReadableMap): PrepareRefundRequest? { + if (!validateMandatoryFields( + prepareRefundRequest, + arrayOf( + "swapAddress", + "toAddress", + "satPerVbyte", + ), + ) + ) { + return null + } + val swapAddress = prepareRefundRequest.getString("swapAddress")!! + val toAddress = prepareRefundRequest.getString("toAddress")!! + val satPerVbyte = prepareRefundRequest.getInt("satPerVbyte").toUInt() + return PrepareRefundRequest( + swapAddress, + toAddress, + satPerVbyte, + ) +} + +fun readableMapOf(prepareRefundRequest: PrepareRefundRequest): ReadableMap { + return readableMapOf( + "swapAddress" to prepareRefundRequest.swapAddress, + "toAddress" to prepareRefundRequest.toAddress, + "satPerVbyte" to prepareRefundRequest.satPerVbyte, + ) +} + +fun asPrepareRefundRequestList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is ReadableMap -> list.add(asPrepareRefundRequest(value)!!) + else -> throw IllegalArgumentException("Unsupported type ${value::class.java.name}") + } + } + return list +} + +fun asPrepareRefundResponse(prepareRefundResponse: ReadableMap): PrepareRefundResponse? { + if (!validateMandatoryFields( + prepareRefundResponse, + arrayOf( + "refundTxWeight", + "refundTxFeeSat", + ), + ) + ) { + return null + } + val refundTxWeight = prepareRefundResponse.getInt("refundTxWeight").toUInt() + val refundTxFeeSat = prepareRefundResponse.getDouble("refundTxFeeSat").toULong() + return PrepareRefundResponse( + refundTxWeight, + refundTxFeeSat, + ) +} + +fun readableMapOf(prepareRefundResponse: PrepareRefundResponse): ReadableMap { + return readableMapOf( + "refundTxWeight" to prepareRefundResponse.refundTxWeight, + "refundTxFeeSat" to prepareRefundResponse.refundTxFeeSat, + ) +} + +fun asPrepareRefundResponseList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is ReadableMap -> list.add(asPrepareRefundResponse(value)!!) + else -> throw IllegalArgumentException("Unsupported type ${value::class.java.name}") + } + } + return list +} + fun asPrepareSweepRequest(prepareSweepRequest: ReadableMap): PrepareSweepRequest? { if (!validateMandatoryFields( prepareSweepRequest, diff --git a/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKModule.kt b/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKModule.kt index c37888e41..f5528ebee 100644 --- a/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKModule.kt +++ b/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKModule.kt @@ -579,6 +579,25 @@ class BreezSDKModule(reactContext: ReactApplicationContext) : ReactContextBaseJa } } + @ReactMethod + fun prepareRefund( + req: ReadableMap, + promise: Promise, + ) { + executor.execute { + try { + val prepareRefundRequest = + asPrepareRefundRequest(req) ?: run { + throw SdkException.Generic("Missing mandatory field req of type PrepareRefundRequest") + } + val res = getBreezServices().prepareRefund(prepareRefundRequest) + promise.resolve(readableMapOf(res)) + } catch (e: SdkException) { + promise.reject(e.javaClass.simpleName, e.message, e) + } + } + } + @ReactMethod fun refund( req: ReadableMap, diff --git a/libs/sdk-react-native/ios/BreezSDKMapper.swift b/libs/sdk-react-native/ios/BreezSDKMapper.swift index c82c8b219..7c92c42d6 100644 --- a/libs/sdk-react-native/ios/BreezSDKMapper.swift +++ b/libs/sdk-react-native/ios/BreezSDKMapper.swift @@ -1585,6 +1585,77 @@ class BreezSDKMapper { return paymentFailedDataList.map { v -> [String: Any?] in dictionaryOf(paymentFailedData: v) } } + static func asPrepareRefundRequest(prepareRefundRequest: [String: Any?]) throws -> PrepareRefundRequest { + guard let swapAddress = prepareRefundRequest["swapAddress"] as? String else { throw SdkError.Generic(message: "Missing mandatory field swapAddress for type PrepareRefundRequest") } + guard let toAddress = prepareRefundRequest["toAddress"] as? String else { throw SdkError.Generic(message: "Missing mandatory field toAddress for type PrepareRefundRequest") } + guard let satPerVbyte = prepareRefundRequest["satPerVbyte"] as? UInt32 else { throw SdkError.Generic(message: "Missing mandatory field satPerVbyte for type PrepareRefundRequest") } + + return PrepareRefundRequest( + swapAddress: swapAddress, + toAddress: toAddress, + satPerVbyte: satPerVbyte + ) + } + + static func dictionaryOf(prepareRefundRequest: PrepareRefundRequest) -> [String: Any?] { + return [ + "swapAddress": prepareRefundRequest.swapAddress, + "toAddress": prepareRefundRequest.toAddress, + "satPerVbyte": prepareRefundRequest.satPerVbyte, + ] + } + + static func asPrepareRefundRequestList(arr: [Any]) throws -> [PrepareRefundRequest] { + var list = [PrepareRefundRequest]() + for value in arr { + if let val = value as? [String: Any?] { + var prepareRefundRequest = try asPrepareRefundRequest(prepareRefundRequest: val) + list.append(prepareRefundRequest) + } else { + throw SdkError.Generic(message: "Invalid element type PrepareRefundRequest") + } + } + return list + } + + static func arrayOf(prepareRefundRequestList: [PrepareRefundRequest]) -> [Any] { + return prepareRefundRequestList.map { v -> [String: Any?] in dictionaryOf(prepareRefundRequest: v) } + } + + static func asPrepareRefundResponse(prepareRefundResponse: [String: Any?]) throws -> PrepareRefundResponse { + guard let refundTxWeight = prepareRefundResponse["refundTxWeight"] as? UInt32 else { throw SdkError.Generic(message: "Missing mandatory field refundTxWeight for type PrepareRefundResponse") } + guard let refundTxFeeSat = prepareRefundResponse["refundTxFeeSat"] as? UInt64 else { throw SdkError.Generic(message: "Missing mandatory field refundTxFeeSat for type PrepareRefundResponse") } + + return PrepareRefundResponse( + refundTxWeight: refundTxWeight, + refundTxFeeSat: refundTxFeeSat + ) + } + + static func dictionaryOf(prepareRefundResponse: PrepareRefundResponse) -> [String: Any?] { + return [ + "refundTxWeight": prepareRefundResponse.refundTxWeight, + "refundTxFeeSat": prepareRefundResponse.refundTxFeeSat, + ] + } + + static func asPrepareRefundResponseList(arr: [Any]) throws -> [PrepareRefundResponse] { + var list = [PrepareRefundResponse]() + for value in arr { + if let val = value as? [String: Any?] { + var prepareRefundResponse = try asPrepareRefundResponse(prepareRefundResponse: val) + list.append(prepareRefundResponse) + } else { + throw SdkError.Generic(message: "Invalid element type PrepareRefundResponse") + } + } + return list + } + + static func arrayOf(prepareRefundResponseList: [PrepareRefundResponse]) -> [Any] { + return prepareRefundResponseList.map { v -> [String: Any?] in dictionaryOf(prepareRefundResponse: v) } + } + static func asPrepareSweepRequest(prepareSweepRequest: [String: Any?]) throws -> PrepareSweepRequest { guard let toAddress = prepareSweepRequest["toAddress"] as? String else { throw SdkError.Generic(message: "Missing mandatory field toAddress for type PrepareSweepRequest") } guard let satsPerVbyte = prepareSweepRequest["satsPerVbyte"] as? UInt64 else { throw SdkError.Generic(message: "Missing mandatory field satsPerVbyte for type PrepareSweepRequest") } diff --git a/libs/sdk-react-native/ios/RNBreezSDK.m b/libs/sdk-react-native/ios/RNBreezSDK.m index ad8406856..f05845e9c 100644 --- a/libs/sdk-react-native/ios/RNBreezSDK.m +++ b/libs/sdk-react-native/ios/RNBreezSDK.m @@ -197,6 +197,12 @@ @interface RCT_EXTERN_MODULE(RNBreezSDK, RCTEventEmitter) reject: (RCTPromiseRejectBlock)reject ) +RCT_EXTERN_METHOD( + prepareRefund: (NSDictionary*)req + resolve: (RCTPromiseResolveBlock)resolve + reject: (RCTPromiseRejectBlock)reject +) + RCT_EXTERN_METHOD( refund: (NSDictionary*)req resolve: (RCTPromiseResolveBlock)resolve diff --git a/libs/sdk-react-native/ios/RNBreezSDK.swift b/libs/sdk-react-native/ios/RNBreezSDK.swift index af98d4152..a5a0cefe4 100644 --- a/libs/sdk-react-native/ios/RNBreezSDK.swift +++ b/libs/sdk-react-native/ios/RNBreezSDK.swift @@ -418,6 +418,17 @@ class RNBreezSDK: RCTEventEmitter { } } + @objc(prepareRefund:resolve:reject:) + func prepareRefund(_ req: [String: Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + do { + let prepareRefundRequest = try BreezSDKMapper.asPrepareRefundRequest(prepareRefundRequest: req) + var res = try getBreezServices().prepareRefund(req: prepareRefundRequest) + resolve(BreezSDKMapper.dictionaryOf(prepareRefundResponse: res)) + } catch let err { + rejectErr(err: err, reject: reject) + } + } + @objc(refund:resolve:reject:) func refund(_ req: [String: Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { do { diff --git a/libs/sdk-react-native/src/index.ts b/libs/sdk-react-native/src/index.ts index 7272cdb2b..0902f9038 100644 --- a/libs/sdk-react-native/src/index.ts +++ b/libs/sdk-react-native/src/index.ts @@ -286,6 +286,17 @@ export type PaymentFailedData = { invoice?: LnInvoice } +export type PrepareRefundRequest = { + swapAddress: string + toAddress: string + satPerVbyte: number +} + +export type PrepareRefundResponse = { + refundTxWeight: number + refundTxFeeSat: number +} + export type PrepareSweepRequest = { toAddress: string satsPerVbyte: number @@ -854,6 +865,11 @@ export const listRefundables = async (): Promise => { return response } +export const prepareRefund = async (req: PrepareRefundRequest): Promise => { + const response = await BreezSDK.prepareRefund(req) + return response +} + export const refund = async (req: RefundRequest): Promise => { const response = await BreezSDK.refund(req) return response diff --git a/tools/sdk-cli/src/command_handlers.rs b/tools/sdk-cli/src/command_handlers.rs index 2f397fd5d..46f4a98f3 100644 --- a/tools/sdk-cli/src/command_handlers.rs +++ b/tools/sdk-cli/src/command_handlers.rs @@ -6,9 +6,9 @@ use breez_sdk_core::InputType::{LnUrlAuth, LnUrlPay, LnUrlWithdraw}; use breez_sdk_core::{ parse, BreezEvent, BreezServices, BuyBitcoinRequest, CheckMessageRequest, EventListener, GreenlightCredentials, ListPaymentsRequest, LnUrlPayRequest, LnUrlWithdrawRequest, - ReceiveOnchainRequest, ReceivePaymentRequest, RefundRequest, ReverseSwapFeesRequest, - SendOnchainRequest, SendPaymentRequest, SendSpontaneousPaymentRequest, SignMessageRequest, - StaticBackupRequest, SweepRequest, + PrepareRefundRequest, ReceiveOnchainRequest, ReceivePaymentRequest, RefundRequest, + ReverseSwapFeesRequest, SendOnchainRequest, SendPaymentRequest, SendSpontaneousPaymentRequest, + SignMessageRequest, StaticBackupRequest, SweepRequest, }; use breez_sdk_core::{Config, GreenlightNodeConfig, NodeConfig}; use once_cell::sync::OnceCell; @@ -309,6 +309,23 @@ pub(crate) async fn handle_command( Commands::ListRefundables {} => { serde_json::to_string_pretty(&sdk()?.list_refundables().await?).map_err(|e| e.into()) } + Commands::PrepareRefund { + swap_address, + to_address, + sat_per_vbyte, + } => { + let res = sdk()? + .prepare_refund(PrepareRefundRequest { + swap_address, + to_address, + sat_per_vbyte, + }) + .await?; + Ok(format!( + "Prepared refund tx - weight: {} - fees: {} sat", + res.refund_tx_weight, res.refund_tx_fee_sat + )) + } Commands::Refund { swap_address, to_address, diff --git a/tools/sdk-cli/src/commands.rs b/tools/sdk-cli/src/commands.rs index ac828f173..4c6b32d61 100644 --- a/tools/sdk-cli/src/commands.rs +++ b/tools/sdk-cli/src/commands.rs @@ -198,6 +198,13 @@ pub(crate) enum Commands { /// List refundable swap addresses ListRefundables {}, + /// Prepare a refund transaction for an incomplete swap + PrepareRefund { + swap_address: String, + to_address: String, + sat_per_vbyte: u32, + }, + /// Broadcast a refund transaction for an incomplete swap Refund { swap_address: String, From 88207b5edfcef44cad263dbaa0e5321811379f46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Granh=C3=A3o?= Date: Tue, 24 Oct 2023 11:56:51 +0100 Subject: [PATCH 10/48] Address review comments * Created `get_address_utxos` * Created `get_swap_info_ok` --- libs/sdk-core/src/swap.rs | 36 +++++++++++++++++------------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/libs/sdk-core/src/swap.rs b/libs/sdk-core/src/swap.rs index 5d3b93c86..ac60598fc 100644 --- a/libs/sdk-core/src/swap.rs +++ b/libs/sdk-core/src/swap.rs @@ -257,11 +257,15 @@ impl BTCReceiveSwap { .collect()) } - #[allow(dead_code)] pub(crate) fn get_swap_info(&self, address: String) -> Result> { self.persister.get_swap_info_by_address(address) } + fn get_swap_info_ok(&self, address: String) -> Result { + self.get_swap_info(address.clone())? + .ok_or_else(|| anyhow!(format!("swap address {} was not found", address))) + } + pub(crate) async fn execute_pending_swaps(&self, tip: u32) -> Result<()> { // first refresh all swaps we monitor _ = self.refresh_monitored_swaps(tip).await?; @@ -438,16 +442,9 @@ impl BTCReceiveSwap { &self, req: PrepareRefundRequest, ) -> Result { - let swap_info = self - .persister - .get_swap_info_by_address(req.swap_address.clone())? - .ok_or_else(|| anyhow!(format!("swap address {} was not found", req.swap_address)))?; + let swap_info = self.get_swap_info_ok(req.swap_address.clone())?; - let transactions = self - .chain_service - .address_transactions(req.swap_address.clone()) - .await?; - let utxos = get_utxos(req.swap_address, transactions)?; + let utxos = self.get_address_utxos(req.swap_address).await?; let refund_tx = prepare_refund_tx(&utxos, req.to_address, swap_info.lock_height as u32)?; @@ -461,16 +458,9 @@ impl BTCReceiveSwap { // refund_swap is the user way to receive on-chain refund for failed swaps. pub(crate) async fn refund_swap(&self, req: RefundRequest) -> Result { - let swap_info = self - .persister - .get_swap_info_by_address(req.swap_address.clone())? - .ok_or_else(|| anyhow!(format!("swap address {} was not found", req.swap_address)))?; + let swap_info = self.get_swap_info_ok(req.swap_address.clone())?; - let transactions = self - .chain_service - .address_transactions(req.swap_address.clone()) - .await?; - let utxos = get_utxos(req.swap_address, transactions)?; + let utxos = self.get_address_utxos(req.swap_address).await?; let script = create_submarine_swap_script( swap_info.payment_hash, @@ -504,6 +494,14 @@ impl BTCReceiveSwap { refund_tx_id: tx_id, }) } + + async fn get_address_utxos(&self, address: String) -> Result { + let transactions = self + .chain_service + .address_transactions(address.clone()) + .await?; + get_utxos(address, transactions) + } } pub(crate) struct SwapKeys { From f56f2bb4f278eec84248d04171aae522e2d12a29 Mon Sep 17 00:00:00 2001 From: cnixbtc <111755602+cnixbtc@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:16:35 +0200 Subject: [PATCH 11/48] Poll for mvn to be ready --- .github/workflows/publish-android.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/publish-android.yml b/.github/workflows/publish-android.yml index 6ce4d2b49..45ad6df58 100644 --- a/.github/workflows/publish-android.yml +++ b/.github/workflows/publish-android.yml @@ -71,8 +71,8 @@ jobs: # Jitpack only makes artifacts avaiable when someone requests them. # Here we trick Jitpack into thinking we're already requesting the newly built package # to make sure it is available right away for anyone that needs it later. - # We're sleeping for 30s before triggering the Jitpack build to give our Maven repo + # We're waiting for at most 60s before triggering the Jitpack build to give our Maven repo # some time to process the just uploaded files (the Jitpack build is dependent upon them being available). # If anything fails here, we'll still finish sucessfully as this is an optional optimization. - sleep 60s + timeout 60 bash -c 'while [[ "$(curl --output /dev/null --silent --head --write-out ''%{http_code}'' https://mvn.breez.technology/releases/breez_sdk/bindings-android/${{ inputs.package-version }}/bindings-android-${{ inputs.package-version }}.pom)" != "200" ]]; do sleep 5; done' || true curl -s -m 30 https://jitpack.io/api/builds/com.github.breez/breez-sdk/${{ inputs.package-version }} || true From 35a62c8db85e1d6c35bb6592508515e828952b19 Mon Sep 17 00:00:00 2001 From: cnixbtc <111755602+cnixbtc@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:20:35 +0200 Subject: [PATCH 12/48] Add workflow call for testing --- .github/workflows/publish-android.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/publish-android.yml b/.github/workflows/publish-android.yml index 45ad6df58..5edbd3fb4 100644 --- a/.github/workflows/publish-android.yml +++ b/.github/workflows/publish-android.yml @@ -22,6 +22,12 @@ on: BREEZ_MVN_PASSWORD: description: 'password for gradlew publish' required: true + workflow_dispatch: + inputs: + package-version: + description: 'version for the gradle library (MAJOR.MINOR.BUILD)' + required: true + type: string jobs: build-package: From 72067b44bc919cbd608a929ec4574c842efcf151 Mon Sep 17 00:00:00 2001 From: cnixbtc <111755602+cnixbtc@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:21:30 +0200 Subject: [PATCH 13/48] Revert "Add workflow call for testing" This reverts commit 35a62c8db85e1d6c35bb6592508515e828952b19. --- .github/workflows/publish-android.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/publish-android.yml b/.github/workflows/publish-android.yml index 5edbd3fb4..45ad6df58 100644 --- a/.github/workflows/publish-android.yml +++ b/.github/workflows/publish-android.yml @@ -22,12 +22,6 @@ on: BREEZ_MVN_PASSWORD: description: 'password for gradlew publish' required: true - workflow_dispatch: - inputs: - package-version: - description: 'version for the gradle library (MAJOR.MINOR.BUILD)' - required: true - type: string jobs: build-package: From 2f3a268c05d6bd4645a9b714416ae864330f7642 Mon Sep 17 00:00:00 2001 From: cnixbtc <111755602+cnixbtc@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:26:12 +0200 Subject: [PATCH 14/48] Setup for testing --- .github/workflows/publish-all-platforms.yml | 4 +- .github/workflows/publish-android.yml | 62 ++++++++++----------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/.github/workflows/publish-all-platforms.yml b/.github/workflows/publish-all-platforms.yml index 03258c463..9b5d80fd0 100644 --- a/.github/workflows/publish-all-platforms.yml +++ b/.github/workflows/publish-all-platforms.yml @@ -176,8 +176,8 @@ jobs: publish-maven: needs: - setup - - build-bindings-android - - build-language-bindings + # - build-bindings-android + # - build-language-bindings if: ${{ needs.setup.outputs.maven == 'true' }} uses: ./.github/workflows/publish-android.yml with: diff --git a/.github/workflows/publish-android.yml b/.github/workflows/publish-android.yml index 45ad6df58..4d9f811eb 100644 --- a/.github/workflows/publish-android.yml +++ b/.github/workflows/publish-android.yml @@ -27,42 +27,42 @@ jobs: build-package: runs-on: ubuntu-latest steps: - - name: Checkout breez-sdk repo - uses: actions/checkout@v3 - with: - ref: ${{ inputs.ref || github.sha }} + # - name: Checkout breez-sdk repo + # uses: actions/checkout@v3 + # with: + # ref: ${{ inputs.ref || github.sha }} - - uses: actions/download-artifact@v3 - with: - name: sdk-bindings-android-jniLibs - path: libs/sdk-bindings/bindings-android/lib/src/main/jniLibs + # - uses: actions/download-artifact@v3 + # with: + # name: sdk-bindings-android-jniLibs + # path: libs/sdk-bindings/bindings-android/lib/src/main/jniLibs - - uses: actions/download-artifact@v3 - with: - name: bindings-kotlin - path: libs/sdk-bindings/bindings-android/lib/src/main/kotlin + # - uses: actions/download-artifact@v3 + # with: + # name: bindings-kotlin + # path: libs/sdk-bindings/bindings-android/lib/src/main/kotlin - - name: Build Android project - working-directory: libs/sdk-bindings/bindings-android - env: - ORG_GRADLE_PROJECT_libraryVersion: ${{ inputs.package-version || '0.0.1' }} - run: ./gradlew assemble + # - name: Build Android project + # working-directory: libs/sdk-bindings/bindings-android + # env: + # ORG_GRADLE_PROJECT_libraryVersion: ${{ inputs.package-version || '0.0.1' }} + # run: ./gradlew assemble - - name: Archive aar - uses: actions/upload-artifact@v3 - with: - name: android-release.aar - path: libs/sdk-bindings/bindings-android/lib/build/outputs/aar/lib-release.aar + # - name: Archive aar + # uses: actions/upload-artifact@v3 + # with: + # name: android-release.aar + # path: libs/sdk-bindings/bindings-android/lib/build/outputs/aar/lib-release.aar - - name: Publish artifacts - if: ${{ inputs.publish }} - working-directory: libs/sdk-bindings/bindings-android - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - BREEZ_MVN_USERNAME: ${{ secrets.BREEZ_MVN_USERNAME }} - BREEZ_MVN_PASSWORD: ${{ secrets.BREEZ_MVN_PASSWORD }} - run: | - ./gradlew publish -PlibraryVersion=${{ inputs.package-version }} -PbreezReposiliteUsername="$BREEZ_MVN_USERNAME" -PbreezReposilitePassword="$BREEZ_MVN_PASSWORD" + # - name: Publish artifacts + # if: ${{ inputs.publish }} + # working-directory: libs/sdk-bindings/bindings-android + # env: + # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + # BREEZ_MVN_USERNAME: ${{ secrets.BREEZ_MVN_USERNAME }} + # BREEZ_MVN_PASSWORD: ${{ secrets.BREEZ_MVN_PASSWORD }} + # run: | + # ./gradlew publish -PlibraryVersion=${{ inputs.package-version }} -PbreezReposiliteUsername="$BREEZ_MVN_USERNAME" -PbreezReposilitePassword="$BREEZ_MVN_PASSWORD" - name: Trigger Jitpack build if: ${{ inputs.publish }} From 83bdee382c07dac23faf17f327e3c0c1130fd880 Mon Sep 17 00:00:00 2001 From: cnixbtc <111755602+cnixbtc@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:33:36 +0200 Subject: [PATCH 15/48] Add some logging --- .github/workflows/publish-android.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/publish-android.yml b/.github/workflows/publish-android.yml index 4d9f811eb..09eae398f 100644 --- a/.github/workflows/publish-android.yml +++ b/.github/workflows/publish-android.yml @@ -74,5 +74,7 @@ jobs: # We're waiting for at most 60s before triggering the Jitpack build to give our Maven repo # some time to process the just uploaded files (the Jitpack build is dependent upon them being available). # If anything fails here, we'll still finish sucessfully as this is an optional optimization. - timeout 60 bash -c 'while [[ "$(curl --output /dev/null --silent --head --write-out ''%{http_code}'' https://mvn.breez.technology/releases/breez_sdk/bindings-android/${{ inputs.package-version }}/bindings-android-${{ inputs.package-version }}.pom)" != "200" ]]; do sleep 5; done' || true + timeout 10 bash -c 'while [[ "$(curl --output /dev/null --silent --head --write-out ''%{http_code}'' https://mvn.breez.technology/releases/breez_sdk/bindings-android/0.2.7/bindings-android-0.2.7.pom)" != "200" ]]; do echo "Waiting for package to be published on mvn.breez.technology..." && sleep 5; done && echo "Package found."' || echo "Package not found." && true + echo "Attempting to trigger Jitpack build..." curl -s -m 30 https://jitpack.io/api/builds/com.github.breez/breez-sdk/${{ inputs.package-version }} || true + echo "Done" From 6390a1b9894b5cd3c6d72937d5b3a4f5e76469ed Mon Sep 17 00:00:00 2001 From: cnixbtc <111755602+cnixbtc@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:35:14 +0200 Subject: [PATCH 16/48] More testing setup --- .github/workflows/publish-all-platforms.yml | 220 ++++++++++---------- .github/workflows/publish-android.yml | 2 +- 2 files changed, 111 insertions(+), 111 deletions(-) diff --git a/.github/workflows/publish-all-platforms.yml b/.github/workflows/publish-all-platforms.yml index 9b5d80fd0..7e14d9373 100644 --- a/.github/workflows/publish-all-platforms.yml +++ b/.github/workflows/publish-all-platforms.yml @@ -98,83 +98,83 @@ jobs: steps: - run: echo "set setup output variables" - build-bindings-windows: - needs: setup - if: ${{ needs.setup.outputs.bindings-windows == 'true' }} - uses: ./.github/workflows/build-bindings-windows.yml - with: - ref: ${{ needs.setup.outputs.ref }} - build-bindings-darwin: - needs: setup - if: ${{ needs.setup.outputs.bindings-darwin == 'true' }} - uses: ./.github/workflows/build-bindings-darwin.yml - with: - ref: ${{ needs.setup.outputs.ref }} - build-bindings-linux: - needs: setup - if: ${{ needs.setup.outputs.bindings-linux == 'true' }} - uses: ./.github/workflows/build-bindings-linux.yml - with: - ref: ${{ needs.setup.outputs.ref }} - build-bindings-android: - needs: setup - if: ${{ needs.setup.outputs.bindings-android == 'true' }} - uses: ./.github/workflows/build-bindings-android.yml - with: - ref: ${{ needs.setup.outputs.ref }} - build-bindings-ios: - needs: setup - if: ${{ needs.setup.outputs.bindings-ios == 'true' }} - uses: ./.github/workflows/build-bindings-ios.yml - with: - ref: ${{ needs.setup.outputs.ref }} + # build-bindings-windows: + # needs: setup + # if: ${{ needs.setup.outputs.bindings-windows == 'true' }} + # uses: ./.github/workflows/build-bindings-windows.yml + # with: + # ref: ${{ needs.setup.outputs.ref }} + # build-bindings-darwin: + # needs: setup + # if: ${{ needs.setup.outputs.bindings-darwin == 'true' }} + # uses: ./.github/workflows/build-bindings-darwin.yml + # with: + # ref: ${{ needs.setup.outputs.ref }} + # build-bindings-linux: + # needs: setup + # if: ${{ needs.setup.outputs.bindings-linux == 'true' }} + # uses: ./.github/workflows/build-bindings-linux.yml + # with: + # ref: ${{ needs.setup.outputs.ref }} + # build-bindings-android: + # needs: setup + # if: ${{ needs.setup.outputs.bindings-android == 'true' }} + # uses: ./.github/workflows/build-bindings-android.yml + # with: + # ref: ${{ needs.setup.outputs.ref }} + # build-bindings-ios: + # needs: setup + # if: ${{ needs.setup.outputs.bindings-ios == 'true' }} + # uses: ./.github/workflows/build-bindings-ios.yml + # with: + # ref: ${{ needs.setup.outputs.ref }} - build-language-bindings: - needs: setup - uses: ./.github/workflows/build-language-bindings.yml - with: - ref: ${{ needs.setup.outputs.ref }} - kotlin: ${{ needs.setup.outputs.kotlin == 'true'}} - csharp: ${{ needs.setup.outputs.csharp == 'true'}} - golang: ${{ needs.setup.outputs.golang == 'true'}} - python: ${{ needs.setup.outputs.python == 'true'}} - swift: ${{ needs.setup.outputs.swift == 'true'}} + # build-language-bindings: + # needs: setup + # uses: ./.github/workflows/build-language-bindings.yml + # with: + # ref: ${{ needs.setup.outputs.ref }} + # kotlin: ${{ needs.setup.outputs.kotlin == 'true'}} + # csharp: ${{ needs.setup.outputs.csharp == 'true'}} + # golang: ${{ needs.setup.outputs.golang == 'true'}} + # python: ${{ needs.setup.outputs.python == 'true'}} + # swift: ${{ needs.setup.outputs.swift == 'true'}} - publish-csharp: - needs: - - setup - - build-bindings-windows - - build-bindings-darwin - - build-bindings-linux - - build-language-bindings - if: ${{ needs.setup.outputs.csharp == 'true' }} - uses: ./.github/workflows/publish-csharp.yml - with: - ref: ${{ needs.setup.outputs.csharp-ref }} - package-version: ${{ needs.setup.outputs.csharp-package-version }} - publish: ${{ needs.setup.outputs.publish == 'true' }} - secrets: - NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} + # publish-csharp: + # needs: + # - setup + # - build-bindings-windows + # - build-bindings-darwin + # - build-bindings-linux + # - build-language-bindings + # if: ${{ needs.setup.outputs.csharp == 'true' }} + # uses: ./.github/workflows/publish-csharp.yml + # with: + # ref: ${{ needs.setup.outputs.csharp-ref }} + # package-version: ${{ needs.setup.outputs.csharp-package-version }} + # publish: ${{ needs.setup.outputs.publish == 'true' }} + # secrets: + # NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} - publish-golang: - needs: - - setup - - build-bindings-android - - build-bindings-windows - - build-bindings-darwin - - build-bindings-linux - - build-language-bindings - if: ${{ needs.setup.outputs.golang == 'true' }} - uses: ./.github/workflows/publish-golang.yml - with: - ref: ${{ needs.setup.outputs.ref }} - package-version: ${{ needs.setup.outputs.golang-package-version }} - publish: ${{ needs.setup.outputs.publish == 'true' }} - secrets: - REPO_SSH_KEY: ${{ secrets.REPO_SSH_KEY }} + # publish-golang: + # needs: + # - setup + # - build-bindings-android + # - build-bindings-windows + # - build-bindings-darwin + # - build-bindings-linux + # - build-language-bindings + # if: ${{ needs.setup.outputs.golang == 'true' }} + # uses: ./.github/workflows/publish-golang.yml + # with: + # ref: ${{ needs.setup.outputs.ref }} + # package-version: ${{ needs.setup.outputs.golang-package-version }} + # publish: ${{ needs.setup.outputs.publish == 'true' }} + # secrets: + # REPO_SSH_KEY: ${{ secrets.REPO_SSH_KEY }} publish-maven: - needs: + needs: - setup # - build-bindings-android # - build-language-bindings @@ -188,45 +188,45 @@ jobs: BREEZ_MVN_USERNAME: ${{ secrets.BREEZ_MVN_USERNAME }} BREEZ_MVN_PASSWORD: ${{ secrets.BREEZ_MVN_PASSWORD }} - publish-kotlin-mpp: - needs: - - setup - - build-bindings-android - - build-bindings-ios - - build-language-bindings - if: ${{ needs.setup.outputs.kotlin-mpp == 'true' }} - uses: ./.github/workflows/publish-kotlin-mpp.yml - with: - ref: ${{ needs.setup.outputs.ref }} - package-version: ${{ needs.setup.outputs.kotlin-mpp-package-version }} - publish: ${{ needs.setup.outputs.publish == 'true' }} - secrets: - BREEZ_MVN_USERNAME: ${{ secrets.BREEZ_MVN_USERNAME }} - BREEZ_MVN_PASSWORD: ${{ secrets.BREEZ_MVN_PASSWORD }} + # publish-kotlin-mpp: + # needs: + # - setup + # - build-bindings-android + # - build-bindings-ios + # - build-language-bindings + # if: ${{ needs.setup.outputs.kotlin-mpp == 'true' }} + # uses: ./.github/workflows/publish-kotlin-mpp.yml + # with: + # ref: ${{ needs.setup.outputs.ref }} + # package-version: ${{ needs.setup.outputs.kotlin-mpp-package-version }} + # publish: ${{ needs.setup.outputs.publish == 'true' }} + # secrets: + # BREEZ_MVN_USERNAME: ${{ secrets.BREEZ_MVN_USERNAME }} + # BREEZ_MVN_PASSWORD: ${{ secrets.BREEZ_MVN_PASSWORD }} - publish-flutter: - needs: - - setup - - build-bindings-android - if: ${{ needs.setup.outputs.flutter == 'true' }} - uses: ./.github/workflows/publish-flutter.yml - with: - ref: ${{ needs.setup.outputs.ref }} - package-version: ${{ needs.setup.outputs.flutter-package-version }} - publish: ${{ needs.setup.outputs.publish == 'true' }} - secrets: - REPO_SSH_KEY: ${{ secrets.REPO_SSH_KEY }} + # publish-flutter: + # needs: + # - setup + # - build-bindings-android + # if: ${{ needs.setup.outputs.flutter == 'true' }} + # uses: ./.github/workflows/publish-flutter.yml + # with: + # ref: ${{ needs.setup.outputs.ref }} + # package-version: ${{ needs.setup.outputs.flutter-package-version }} + # publish: ${{ needs.setup.outputs.publish == 'true' }} + # secrets: + # REPO_SSH_KEY: ${{ secrets.REPO_SSH_KEY }} # react native version x.y.z will at runtime require # ios and android packages x.y.z being published already. - publish-react-native: - needs: - - setup - if: ${{ needs.setup.outputs.react-native == 'true' }} - uses: ./.github/workflows/publish-react-native.yml - with: - ref: ${{ needs.setup.outputs.ref }} - package-version: ${{ needs.setup.outputs.react-native-package-version }} - publish: ${{ needs.setup.outputs.publish == 'true' }} - secrets: - NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + # publish-react-native: + # needs: + # - setup + # if: ${{ needs.setup.outputs.react-native == 'true' }} + # uses: ./.github/workflows/publish-react-native.yml + # with: + # ref: ${{ needs.setup.outputs.ref }} + # package-version: ${{ needs.setup.outputs.react-native-package-version }} + # publish: ${{ needs.setup.outputs.publish == 'true' }} + # secrets: + # NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/publish-android.yml b/.github/workflows/publish-android.yml index 09eae398f..428280e31 100644 --- a/.github/workflows/publish-android.yml +++ b/.github/workflows/publish-android.yml @@ -65,7 +65,7 @@ jobs: # ./gradlew publish -PlibraryVersion=${{ inputs.package-version }} -PbreezReposiliteUsername="$BREEZ_MVN_USERNAME" -PbreezReposilitePassword="$BREEZ_MVN_PASSWORD" - name: Trigger Jitpack build - if: ${{ inputs.publish }} + # if: ${{ inputs.publish }} shell: bash run: | # Jitpack only makes artifacts avaiable when someone requests them. From 8138629503b3a0d2a6bc29fad0333d4ae46087b3 Mon Sep 17 00:00:00 2001 From: cnixbtc <111755602+cnixbtc@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:46:33 +0200 Subject: [PATCH 17/48] Fix version --- .github/workflows/publish-android.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-android.yml b/.github/workflows/publish-android.yml index 428280e31..221716fd8 100644 --- a/.github/workflows/publish-android.yml +++ b/.github/workflows/publish-android.yml @@ -74,7 +74,7 @@ jobs: # We're waiting for at most 60s before triggering the Jitpack build to give our Maven repo # some time to process the just uploaded files (the Jitpack build is dependent upon them being available). # If anything fails here, we'll still finish sucessfully as this is an optional optimization. - timeout 10 bash -c 'while [[ "$(curl --output /dev/null --silent --head --write-out ''%{http_code}'' https://mvn.breez.technology/releases/breez_sdk/bindings-android/0.2.7/bindings-android-0.2.7.pom)" != "200" ]]; do echo "Waiting for package to be published on mvn.breez.technology..." && sleep 5; done && echo "Package found."' || echo "Package not found." && true + timeout 10 bash -c 'while [[ "$(curl --output /dev/null --silent --head --write-out ''%{http_code}'' https://mvn.breez.technology/releases/breez_sdk/bindings-android/${{ inputs.package-version }}/bindings-android-${{ inputs.package-version }}.pom)" != "200" ]]; do echo "Waiting for package to be published on mvn.breez.technology..." && sleep 5; done && echo "Package found."' || echo "Package not found." && true echo "Attempting to trigger Jitpack build..." curl -s -m 30 https://jitpack.io/api/builds/com.github.breez/breez-sdk/${{ inputs.package-version }} || true echo "Done" From dd034959052b24534e2bd538855dd447f7493341 Mon Sep 17 00:00:00 2001 From: cnixbtc <111755602+cnixbtc@users.noreply.github.com> Date: Wed, 25 Oct 2023 19:49:07 +0200 Subject: [PATCH 18/48] Revert testing setup --- .github/workflows/publish-all-platforms.yml | 224 ++++++++++---------- .github/workflows/publish-android.yml | 66 +++--- 2 files changed, 145 insertions(+), 145 deletions(-) diff --git a/.github/workflows/publish-all-platforms.yml b/.github/workflows/publish-all-platforms.yml index 7e14d9373..03258c463 100644 --- a/.github/workflows/publish-all-platforms.yml +++ b/.github/workflows/publish-all-platforms.yml @@ -98,86 +98,86 @@ jobs: steps: - run: echo "set setup output variables" - # build-bindings-windows: - # needs: setup - # if: ${{ needs.setup.outputs.bindings-windows == 'true' }} - # uses: ./.github/workflows/build-bindings-windows.yml - # with: - # ref: ${{ needs.setup.outputs.ref }} - # build-bindings-darwin: - # needs: setup - # if: ${{ needs.setup.outputs.bindings-darwin == 'true' }} - # uses: ./.github/workflows/build-bindings-darwin.yml - # with: - # ref: ${{ needs.setup.outputs.ref }} - # build-bindings-linux: - # needs: setup - # if: ${{ needs.setup.outputs.bindings-linux == 'true' }} - # uses: ./.github/workflows/build-bindings-linux.yml - # with: - # ref: ${{ needs.setup.outputs.ref }} - # build-bindings-android: - # needs: setup - # if: ${{ needs.setup.outputs.bindings-android == 'true' }} - # uses: ./.github/workflows/build-bindings-android.yml - # with: - # ref: ${{ needs.setup.outputs.ref }} - # build-bindings-ios: - # needs: setup - # if: ${{ needs.setup.outputs.bindings-ios == 'true' }} - # uses: ./.github/workflows/build-bindings-ios.yml - # with: - # ref: ${{ needs.setup.outputs.ref }} + build-bindings-windows: + needs: setup + if: ${{ needs.setup.outputs.bindings-windows == 'true' }} + uses: ./.github/workflows/build-bindings-windows.yml + with: + ref: ${{ needs.setup.outputs.ref }} + build-bindings-darwin: + needs: setup + if: ${{ needs.setup.outputs.bindings-darwin == 'true' }} + uses: ./.github/workflows/build-bindings-darwin.yml + with: + ref: ${{ needs.setup.outputs.ref }} + build-bindings-linux: + needs: setup + if: ${{ needs.setup.outputs.bindings-linux == 'true' }} + uses: ./.github/workflows/build-bindings-linux.yml + with: + ref: ${{ needs.setup.outputs.ref }} + build-bindings-android: + needs: setup + if: ${{ needs.setup.outputs.bindings-android == 'true' }} + uses: ./.github/workflows/build-bindings-android.yml + with: + ref: ${{ needs.setup.outputs.ref }} + build-bindings-ios: + needs: setup + if: ${{ needs.setup.outputs.bindings-ios == 'true' }} + uses: ./.github/workflows/build-bindings-ios.yml + with: + ref: ${{ needs.setup.outputs.ref }} - # build-language-bindings: - # needs: setup - # uses: ./.github/workflows/build-language-bindings.yml - # with: - # ref: ${{ needs.setup.outputs.ref }} - # kotlin: ${{ needs.setup.outputs.kotlin == 'true'}} - # csharp: ${{ needs.setup.outputs.csharp == 'true'}} - # golang: ${{ needs.setup.outputs.golang == 'true'}} - # python: ${{ needs.setup.outputs.python == 'true'}} - # swift: ${{ needs.setup.outputs.swift == 'true'}} + build-language-bindings: + needs: setup + uses: ./.github/workflows/build-language-bindings.yml + with: + ref: ${{ needs.setup.outputs.ref }} + kotlin: ${{ needs.setup.outputs.kotlin == 'true'}} + csharp: ${{ needs.setup.outputs.csharp == 'true'}} + golang: ${{ needs.setup.outputs.golang == 'true'}} + python: ${{ needs.setup.outputs.python == 'true'}} + swift: ${{ needs.setup.outputs.swift == 'true'}} - # publish-csharp: - # needs: - # - setup - # - build-bindings-windows - # - build-bindings-darwin - # - build-bindings-linux - # - build-language-bindings - # if: ${{ needs.setup.outputs.csharp == 'true' }} - # uses: ./.github/workflows/publish-csharp.yml - # with: - # ref: ${{ needs.setup.outputs.csharp-ref }} - # package-version: ${{ needs.setup.outputs.csharp-package-version }} - # publish: ${{ needs.setup.outputs.publish == 'true' }} - # secrets: - # NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} + publish-csharp: + needs: + - setup + - build-bindings-windows + - build-bindings-darwin + - build-bindings-linux + - build-language-bindings + if: ${{ needs.setup.outputs.csharp == 'true' }} + uses: ./.github/workflows/publish-csharp.yml + with: + ref: ${{ needs.setup.outputs.csharp-ref }} + package-version: ${{ needs.setup.outputs.csharp-package-version }} + publish: ${{ needs.setup.outputs.publish == 'true' }} + secrets: + NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} - # publish-golang: - # needs: - # - setup - # - build-bindings-android - # - build-bindings-windows - # - build-bindings-darwin - # - build-bindings-linux - # - build-language-bindings - # if: ${{ needs.setup.outputs.golang == 'true' }} - # uses: ./.github/workflows/publish-golang.yml - # with: - # ref: ${{ needs.setup.outputs.ref }} - # package-version: ${{ needs.setup.outputs.golang-package-version }} - # publish: ${{ needs.setup.outputs.publish == 'true' }} - # secrets: - # REPO_SSH_KEY: ${{ secrets.REPO_SSH_KEY }} + publish-golang: + needs: + - setup + - build-bindings-android + - build-bindings-windows + - build-bindings-darwin + - build-bindings-linux + - build-language-bindings + if: ${{ needs.setup.outputs.golang == 'true' }} + uses: ./.github/workflows/publish-golang.yml + with: + ref: ${{ needs.setup.outputs.ref }} + package-version: ${{ needs.setup.outputs.golang-package-version }} + publish: ${{ needs.setup.outputs.publish == 'true' }} + secrets: + REPO_SSH_KEY: ${{ secrets.REPO_SSH_KEY }} publish-maven: - needs: + needs: - setup - # - build-bindings-android - # - build-language-bindings + - build-bindings-android + - build-language-bindings if: ${{ needs.setup.outputs.maven == 'true' }} uses: ./.github/workflows/publish-android.yml with: @@ -188,45 +188,45 @@ jobs: BREEZ_MVN_USERNAME: ${{ secrets.BREEZ_MVN_USERNAME }} BREEZ_MVN_PASSWORD: ${{ secrets.BREEZ_MVN_PASSWORD }} - # publish-kotlin-mpp: - # needs: - # - setup - # - build-bindings-android - # - build-bindings-ios - # - build-language-bindings - # if: ${{ needs.setup.outputs.kotlin-mpp == 'true' }} - # uses: ./.github/workflows/publish-kotlin-mpp.yml - # with: - # ref: ${{ needs.setup.outputs.ref }} - # package-version: ${{ needs.setup.outputs.kotlin-mpp-package-version }} - # publish: ${{ needs.setup.outputs.publish == 'true' }} - # secrets: - # BREEZ_MVN_USERNAME: ${{ secrets.BREEZ_MVN_USERNAME }} - # BREEZ_MVN_PASSWORD: ${{ secrets.BREEZ_MVN_PASSWORD }} + publish-kotlin-mpp: + needs: + - setup + - build-bindings-android + - build-bindings-ios + - build-language-bindings + if: ${{ needs.setup.outputs.kotlin-mpp == 'true' }} + uses: ./.github/workflows/publish-kotlin-mpp.yml + with: + ref: ${{ needs.setup.outputs.ref }} + package-version: ${{ needs.setup.outputs.kotlin-mpp-package-version }} + publish: ${{ needs.setup.outputs.publish == 'true' }} + secrets: + BREEZ_MVN_USERNAME: ${{ secrets.BREEZ_MVN_USERNAME }} + BREEZ_MVN_PASSWORD: ${{ secrets.BREEZ_MVN_PASSWORD }} - # publish-flutter: - # needs: - # - setup - # - build-bindings-android - # if: ${{ needs.setup.outputs.flutter == 'true' }} - # uses: ./.github/workflows/publish-flutter.yml - # with: - # ref: ${{ needs.setup.outputs.ref }} - # package-version: ${{ needs.setup.outputs.flutter-package-version }} - # publish: ${{ needs.setup.outputs.publish == 'true' }} - # secrets: - # REPO_SSH_KEY: ${{ secrets.REPO_SSH_KEY }} + publish-flutter: + needs: + - setup + - build-bindings-android + if: ${{ needs.setup.outputs.flutter == 'true' }} + uses: ./.github/workflows/publish-flutter.yml + with: + ref: ${{ needs.setup.outputs.ref }} + package-version: ${{ needs.setup.outputs.flutter-package-version }} + publish: ${{ needs.setup.outputs.publish == 'true' }} + secrets: + REPO_SSH_KEY: ${{ secrets.REPO_SSH_KEY }} # react native version x.y.z will at runtime require # ios and android packages x.y.z being published already. - # publish-react-native: - # needs: - # - setup - # if: ${{ needs.setup.outputs.react-native == 'true' }} - # uses: ./.github/workflows/publish-react-native.yml - # with: - # ref: ${{ needs.setup.outputs.ref }} - # package-version: ${{ needs.setup.outputs.react-native-package-version }} - # publish: ${{ needs.setup.outputs.publish == 'true' }} - # secrets: - # NPM_TOKEN: ${{ secrets.NPM_TOKEN }} + publish-react-native: + needs: + - setup + if: ${{ needs.setup.outputs.react-native == 'true' }} + uses: ./.github/workflows/publish-react-native.yml + with: + ref: ${{ needs.setup.outputs.ref }} + package-version: ${{ needs.setup.outputs.react-native-package-version }} + publish: ${{ needs.setup.outputs.publish == 'true' }} + secrets: + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/publish-android.yml b/.github/workflows/publish-android.yml index 221716fd8..43642c279 100644 --- a/.github/workflows/publish-android.yml +++ b/.github/workflows/publish-android.yml @@ -27,45 +27,45 @@ jobs: build-package: runs-on: ubuntu-latest steps: - # - name: Checkout breez-sdk repo - # uses: actions/checkout@v3 - # with: - # ref: ${{ inputs.ref || github.sha }} + - name: Checkout breez-sdk repo + uses: actions/checkout@v3 + with: + ref: ${{ inputs.ref || github.sha }} - # - uses: actions/download-artifact@v3 - # with: - # name: sdk-bindings-android-jniLibs - # path: libs/sdk-bindings/bindings-android/lib/src/main/jniLibs + - uses: actions/download-artifact@v3 + with: + name: sdk-bindings-android-jniLibs + path: libs/sdk-bindings/bindings-android/lib/src/main/jniLibs - # - uses: actions/download-artifact@v3 - # with: - # name: bindings-kotlin - # path: libs/sdk-bindings/bindings-android/lib/src/main/kotlin + - uses: actions/download-artifact@v3 + with: + name: bindings-kotlin + path: libs/sdk-bindings/bindings-android/lib/src/main/kotlin - # - name: Build Android project - # working-directory: libs/sdk-bindings/bindings-android - # env: - # ORG_GRADLE_PROJECT_libraryVersion: ${{ inputs.package-version || '0.0.1' }} - # run: ./gradlew assemble + - name: Build Android project + working-directory: libs/sdk-bindings/bindings-android + env: + ORG_GRADLE_PROJECT_libraryVersion: ${{ inputs.package-version || '0.0.1' }} + run: ./gradlew assemble - # - name: Archive aar - # uses: actions/upload-artifact@v3 - # with: - # name: android-release.aar - # path: libs/sdk-bindings/bindings-android/lib/build/outputs/aar/lib-release.aar + - name: Archive aar + uses: actions/upload-artifact@v3 + with: + name: android-release.aar + path: libs/sdk-bindings/bindings-android/lib/build/outputs/aar/lib-release.aar - # - name: Publish artifacts - # if: ${{ inputs.publish }} - # working-directory: libs/sdk-bindings/bindings-android - # env: - # GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # BREEZ_MVN_USERNAME: ${{ secrets.BREEZ_MVN_USERNAME }} - # BREEZ_MVN_PASSWORD: ${{ secrets.BREEZ_MVN_PASSWORD }} - # run: | - # ./gradlew publish -PlibraryVersion=${{ inputs.package-version }} -PbreezReposiliteUsername="$BREEZ_MVN_USERNAME" -PbreezReposilitePassword="$BREEZ_MVN_PASSWORD" + - name: Publish artifacts + if: ${{ inputs.publish }} + working-directory: libs/sdk-bindings/bindings-android + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + BREEZ_MVN_USERNAME: ${{ secrets.BREEZ_MVN_USERNAME }} + BREEZ_MVN_PASSWORD: ${{ secrets.BREEZ_MVN_PASSWORD }} + run: | + ./gradlew publish -PlibraryVersion=${{ inputs.package-version }} -PbreezReposiliteUsername="$BREEZ_MVN_USERNAME" -PbreezReposilitePassword="$BREEZ_MVN_PASSWORD" - name: Trigger Jitpack build - # if: ${{ inputs.publish }} + if: ${{ inputs.publish }} shell: bash run: | # Jitpack only makes artifacts avaiable when someone requests them. @@ -74,7 +74,7 @@ jobs: # We're waiting for at most 60s before triggering the Jitpack build to give our Maven repo # some time to process the just uploaded files (the Jitpack build is dependent upon them being available). # If anything fails here, we'll still finish sucessfully as this is an optional optimization. - timeout 10 bash -c 'while [[ "$(curl --output /dev/null --silent --head --write-out ''%{http_code}'' https://mvn.breez.technology/releases/breez_sdk/bindings-android/${{ inputs.package-version }}/bindings-android-${{ inputs.package-version }}.pom)" != "200" ]]; do echo "Waiting for package to be published on mvn.breez.technology..." && sleep 5; done && echo "Package found."' || echo "Package not found." && true + timeout 60 bash -c 'while [[ "$(curl --output /dev/null --silent --head --write-out ''%{http_code}'' https://mvn.breez.technology/releases/breez_sdk/bindings-android/${{ inputs.package-version }}/bindings-android-${{ inputs.package-version }}.pom)" != "200" ]]; do echo "Waiting for package to be published on mvn.breez.technology..." && sleep 5; done && echo "Package found."' || echo "Package not found." && true echo "Attempting to trigger Jitpack build..." curl -s -m 30 https://jitpack.io/api/builds/com.github.breez/breez-sdk/${{ inputs.package-version }} || true echo "Done" From 9a56ad82b8fa27d46bdcd2578f48993ea2c1f1cb Mon Sep 17 00:00:00 2001 From: umiyahara <138246513+umiyahara@users.noreply.github.com> Date: Wed, 25 Oct 2023 16:28:39 -0400 Subject: [PATCH 19/48] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index d273b17c6..c9de6b6d3 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ Download our one pager [here](https://drive.google.com/file/d/1MBINTyEXX9tFLVXd3 To get started with the Breez SDK, follow [these examples](https://sdk-doc.breez.technology/). +The Breez SDK is open source and free for developers. + Note: in order to use the Breez SDK you need an API key from Breez, please email us at contact@breez.technology for more information. ## Demo From 1e33e5c5baead5cd77b3141e4f080141a6e3aac8 Mon Sep 17 00:00:00 2001 From: umiyahara <138246513+umiyahara@users.noreply.github.com> Date: Wed, 25 Oct 2023 16:31:41 -0400 Subject: [PATCH 20/48] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c9de6b6d3..c14bbba78 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Download our one pager [here](https://drive.google.com/file/d/1MBINTyEXX9tFLVXd3 To get started with the Breez SDK, follow [these examples](https://sdk-doc.breez.technology/). -The Breez SDK is open source and free for developers. +The Breez SDK is free for developers. Note: in order to use the Breez SDK you need an API key from Breez, please email us at contact@breez.technology for more information. From c659dd0836af5e20ce2dcd4744098fbf91d62759 Mon Sep 17 00:00:00 2001 From: umiyahara <138246513+umiyahara@users.noreply.github.com> Date: Wed, 25 Oct 2023 16:38:32 -0400 Subject: [PATCH 21/48] Update README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index c14bbba78..eaa5e91e5 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Breez SDK ## Overview -The Breez SDK enables mobile developers to integrate Lightning and bitcoin payments into their apps with a very shallow learning curve. The use cases are endless – from social apps that want to integrate tipping between users to content-creation apps interested in adding bitcoin monetization. Crucially, this SDK is an end-to-end, non-custodial, drop-in solution powered by Greenlight, a built-in LSP, on-chain interoperability, third-party fiat on-ramps, and other services users and operators need. +The Breez SDK enables mobile developers to integrate Lightning and bitcoin payments into their apps with a very shallow learning curve. The use cases are endless – from social apps that want to integrate tipping between users to content-creation apps interested in adding bitcoin monetization. Crucially, this SDK is an end-to-end, non-custodial, drop-in solution powered by Greenlight, a built-in LSP, on-chain interoperability, third-party fiat on-ramps, and other services users and operators need. The Breez SDK is free for developers. The Breez SDK provides the following services: * Sending payments (via various protocols such as: bolt11, keysend, lnurl-pay, lightning address, etc.) @@ -13,8 +13,6 @@ Download our one pager [here](https://drive.google.com/file/d/1MBINTyEXX9tFLVXd3 To get started with the Breez SDK, follow [these examples](https://sdk-doc.breez.technology/). -The Breez SDK is free for developers. - Note: in order to use the Breez SDK you need an API key from Breez, please email us at contact@breez.technology for more information. ## Demo From 189244c1f6eda62b6c976b204caa9c63f787df07 Mon Sep 17 00:00:00 2001 From: Erdem Yerebasmaz Date: Thu, 26 Oct 2023 13:14:48 +0300 Subject: [PATCH 22/48] Expose prepareRefund through sdk-flutter --- libs/sdk-flutter/lib/breez_sdk.dart | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libs/sdk-flutter/lib/breez_sdk.dart b/libs/sdk-flutter/lib/breez_sdk.dart index 8299680ff..e3fffe7f4 100644 --- a/libs/sdk-flutter/lib/breez_sdk.dart +++ b/libs/sdk-flutter/lib/breez_sdk.dart @@ -328,6 +328,16 @@ class BreezSDK { return await _lnToolkit.refund(req: req); } + /// Prepares a refund transaction for a failed/expired swap. + /// + /// Can optionally be used before refund to know how much fees will be paid + /// to perform the refund. + Future prepareRefund({ + required PrepareRefundRequest req, + }) async { + return await _lnToolkit.prepareRefund(req: req); + } + /* In Progress Swap API's */ /// Returns an optional in-progress [SwapInfo]. From 24c9c550a8aa7046deea2b246e801d0662cb0283 Mon Sep 17 00:00:00 2001 From: Erdem Yerebasmaz Date: Tue, 24 Oct 2023 00:50:22 +0300 Subject: [PATCH 23/48] Update Flutter to 3.13.x for sdk-flutter Update flutter_rust_bridge to 1.80.1 & generate bindings Bump sdk-flutter version to 0.2.8 Add SDK release notes to changelog --- libs/Cargo.lock | 39 +- libs/sdk-bindings/Cargo.toml | 2 +- libs/sdk-core/Cargo.toml | 2 +- libs/sdk-core/src/bridge_generated.rs | 843 +++++++++++----- libs/sdk-flutter/.gitignore | 1 + libs/sdk-flutter/CHANGELOG.md | 17 +- libs/sdk-flutter/README.md | 4 +- libs/sdk-flutter/lib/breez_sdk.dart | 4 +- libs/sdk-flutter/lib/bridge_generated.dart | 80 +- .../lib/bridge_generated.freezed.dart | 906 +++++++++--------- libs/sdk-flutter/makefile | 3 +- libs/sdk-flutter/pubspec.lock | 136 +-- libs/sdk-flutter/pubspec.yaml | 20 +- libs/sdk-flutter/test/breez_sdk_test.dart | 7 +- tools/sdk-cli/Cargo.lock | 10 +- 15 files changed, 1248 insertions(+), 826 deletions(-) diff --git a/libs/Cargo.lock b/libs/Cargo.lock index b918d6804..d64870308 100644 --- a/libs/Cargo.lock +++ b/libs/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.19.0" +version = "0.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" dependencies = [ "gimli", ] @@ -80,9 +80,9 @@ dependencies = [ [[package]] name = "allo-isolate" -version = "0.1.17" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9980a41e4f88ed39a4dc1f263f94c89ddf6c4b3c725643ecddbcb07d6f41ad3c" +checksum = "f56b7997817c178b853573e8bdfb6c3afe02810b43f17d766d6703560074b0c3" dependencies = [ "anyhow", "atomic", @@ -328,15 +328,15 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.67" +version = "0.3.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" dependencies = [ "addr2line", "cc", "cfg-if", "libc", - "miniz_oxide 0.6.2", + "miniz_oxide", "object", "rustc-demangle", ] @@ -538,7 +538,7 @@ dependencies = [ "lightning 0.0.115", "lightning-invoice 0.23.0", "log", - "miniz_oxide 0.7.1", + "miniz_oxide", "mockito", "once_cell", "openssl", @@ -1098,9 +1098,9 @@ dependencies = [ [[package]] name = "flutter_rust_bridge" -version = "1.77.1" +version = "1.80.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8525ccd3a804ab5ae55ab9883e56caf2e38ae307539685e3042bcf6fc494b4ce" +checksum = "fd0305ebc9f097d9826530a55fc2acd63222e912c663f7adce3ab641ecc0f346" dependencies = [ "allo-isolate", "anyhow", @@ -1293,9 +1293,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.27.2" +version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" +checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" [[package]] name = "gl-client" @@ -1306,7 +1306,7 @@ dependencies = [ "async-trait", "base64 0.21.2", "bech32", - "bitcoin 0.29.2", + "bitcoin 0.30.1", "bytes", "chacha20poly1305", "cln-grpc", @@ -1932,15 +1932,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" -[[package]] -name = "miniz_oxide" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" -dependencies = [ - "adler", -] - [[package]] name = "miniz_oxide" version = "0.7.1" @@ -2089,9 +2080,9 @@ dependencies = [ [[package]] name = "object" -version = "0.30.4" +version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ "memchr", ] diff --git a/libs/sdk-bindings/Cargo.toml b/libs/sdk-bindings/Cargo.toml index 205cf5292..e5be33277 100644 --- a/libs/sdk-bindings/Cargo.toml +++ b/libs/sdk-bindings/Cargo.toml @@ -26,7 +26,7 @@ camino = "1.1.1" lightning-invoice = "*" log = "*" once_cell = "*" -flutter_rust_bridge = "1.75.2" +flutter_rust_bridge = "=1.80.1" tiny-bip39 = "*" tonic = { version = "^0.8", features = [ "tls", diff --git a/libs/sdk-core/Cargo.toml b/libs/sdk-core/Cargo.toml index ff6dea08f..4c6386620 100644 --- a/libs/sdk-core/Cargo.toml +++ b/libs/sdk-core/Cargo.toml @@ -8,7 +8,7 @@ name = "breez_sdk_core" crate-type = ["staticlib", "cdylib", "lib"] [dependencies] -flutter_rust_bridge = "1.75.2" +flutter_rust_bridge = "=1.80.1" aes = "0.8" anyhow = { version = "1.0", features = ["backtrace"] } cbc = { version = "0.1", features = ["std"] } diff --git a/libs/sdk-core/src/bridge_generated.rs b/libs/sdk-core/src/bridge_generated.rs index 1e377b140..e3943521a 100644 --- a/libs/sdk-core/src/bridge_generated.rs +++ b/libs/sdk-core/src/bridge_generated.rs @@ -9,10 +9,11 @@ clippy::too_many_arguments )] // AUTO GENERATED FILE, DO NOT EDIT. -// Generated by `flutter_rust_bridge`@ 1.75.2. +// Generated by `flutter_rust_bridge`@ 1.80.1. use crate::binding::*; use core::panic::UnwindSafe; +use flutter_rust_bridge::rust2dart::IntoIntoDart; use flutter_rust_bridge::*; use std::ffi::c_void; use std::sync::Arc; @@ -112,7 +113,7 @@ fn wire_connect_impl( config: impl Wire2Api + UnwindSafe, seed: impl Wire2Api> + UnwindSafe, ) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, ()>( WrapInfo { debug_name: "connect", port: Some(port_), @@ -126,7 +127,7 @@ fn wire_connect_impl( ) } fn wire_is_initialized_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, bool>( WrapInfo { debug_name: "is_initialized", port: Some(port_), @@ -136,7 +137,7 @@ fn wire_is_initialized_impl(port_: MessagePort) { ) } fn wire_sync_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, ()>( WrapInfo { debug_name: "sync", port: Some(port_), @@ -146,7 +147,7 @@ fn wire_sync_impl(port_: MessagePort) { ) } fn wire_node_info_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, NodeState>( WrapInfo { debug_name: "node_info", port: Some(port_), @@ -156,7 +157,7 @@ fn wire_node_info_impl(port_: MessagePort) { ) } fn wire_disconnect_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, ()>( WrapInfo { debug_name: "disconnect", port: Some(port_), @@ -166,7 +167,7 @@ fn wire_disconnect_impl(port_: MessagePort) { ) } fn wire_sign_message_impl(port_: MessagePort, req: impl Wire2Api + UnwindSafe) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, SignMessageResponse>( WrapInfo { debug_name: "sign_message", port: Some(port_), @@ -182,7 +183,7 @@ fn wire_check_message_impl( port_: MessagePort, req: impl Wire2Api + UnwindSafe, ) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, CheckMessageResponse>( WrapInfo { debug_name: "check_message", port: Some(port_), @@ -195,7 +196,7 @@ fn wire_check_message_impl( ) } fn wire_mnemonic_to_seed_impl(port_: MessagePort, phrase: impl Wire2Api + UnwindSafe) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, Vec>( WrapInfo { debug_name: "mnemonic_to_seed", port: Some(port_), @@ -213,7 +214,7 @@ fn wire_default_config_impl( api_key: impl Wire2Api + UnwindSafe, node_config: impl Wire2Api + UnwindSafe, ) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, Config>( WrapInfo { debug_name: "default_config", port: Some(port_), @@ -231,7 +232,7 @@ fn wire_static_backup_impl( port_: MessagePort, req: impl Wire2Api + UnwindSafe, ) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, StaticBackupResponse>( WrapInfo { debug_name: "static_backup", port: Some(port_), @@ -244,27 +245,29 @@ fn wire_static_backup_impl( ) } fn wire_breez_events_stream_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, ()>( WrapInfo { debug_name: "breez_events_stream", port: Some(port_), mode: FfiCallMode::Stream, }, - move || move |task_callback| breez_events_stream(task_callback.stream_sink()), + move || { + move |task_callback| breez_events_stream(task_callback.stream_sink::<_, BreezEvent>()) + }, ) } fn wire_breez_log_stream_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, ()>( WrapInfo { debug_name: "breez_log_stream", port: Some(port_), mode: FfiCallMode::Stream, }, - move || move |task_callback| breez_log_stream(task_callback.stream_sink()), + move || move |task_callback| breez_log_stream(task_callback.stream_sink::<_, LogEntry>()), ) } fn wire_list_lsps_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, Vec>( WrapInfo { debug_name: "list_lsps", port: Some(port_), @@ -274,7 +277,7 @@ fn wire_list_lsps_impl(port_: MessagePort) { ) } fn wire_connect_lsp_impl(port_: MessagePort, lsp_id: impl Wire2Api + UnwindSafe) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, ()>( WrapInfo { debug_name: "connect_lsp", port: Some(port_), @@ -287,7 +290,7 @@ fn wire_connect_lsp_impl(port_: MessagePort, lsp_id: impl Wire2Api + Unw ) } fn wire_lsp_id_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, Option>( WrapInfo { debug_name: "lsp_id", port: Some(port_), @@ -297,7 +300,7 @@ fn wire_lsp_id_impl(port_: MessagePort) { ) } fn wire_fetch_lsp_info_impl(port_: MessagePort, id: impl Wire2Api + UnwindSafe) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, Option>( WrapInfo { debug_name: "fetch_lsp_info", port: Some(port_), @@ -310,7 +313,7 @@ fn wire_fetch_lsp_info_impl(port_: MessagePort, id: impl Wire2Api + Unwi ) } fn wire_lsp_info_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, LspInformation>( WrapInfo { debug_name: "lsp_info", port: Some(port_), @@ -320,7 +323,7 @@ fn wire_lsp_info_impl(port_: MessagePort) { ) } fn wire_close_lsp_channels_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, ()>( WrapInfo { debug_name: "close_lsp_channels", port: Some(port_), @@ -330,7 +333,7 @@ fn wire_close_lsp_channels_impl(port_: MessagePort) { ) } fn wire_backup_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, ()>( WrapInfo { debug_name: "backup", port: Some(port_), @@ -340,7 +343,7 @@ fn wire_backup_impl(port_: MessagePort) { ) } fn wire_backup_status_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, BackupStatus>( WrapInfo { debug_name: "backup_status", port: Some(port_), @@ -350,7 +353,7 @@ fn wire_backup_status_impl(port_: MessagePort) { ) } fn wire_parse_invoice_impl(port_: MessagePort, invoice: impl Wire2Api + UnwindSafe) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, LNInvoice>( WrapInfo { debug_name: "parse_invoice", port: Some(port_), @@ -363,7 +366,7 @@ fn wire_parse_invoice_impl(port_: MessagePort, invoice: impl Wire2Api + ) } fn wire_parse_input_impl(port_: MessagePort, input: impl Wire2Api + UnwindSafe) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, InputType>( WrapInfo { debug_name: "parse_input", port: Some(port_), @@ -379,7 +382,7 @@ fn wire_list_payments_impl( port_: MessagePort, req: impl Wire2Api + UnwindSafe, ) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, Vec>( WrapInfo { debug_name: "list_payments", port: Some(port_), @@ -392,7 +395,7 @@ fn wire_list_payments_impl( ) } fn wire_payment_by_hash_impl(port_: MessagePort, hash: impl Wire2Api + UnwindSafe) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, Option>( WrapInfo { debug_name: "payment_by_hash", port: Some(port_), @@ -405,7 +408,7 @@ fn wire_payment_by_hash_impl(port_: MessagePort, hash: impl Wire2Api + U ) } fn wire_send_payment_impl(port_: MessagePort, req: impl Wire2Api + UnwindSafe) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, SendPaymentResponse>( WrapInfo { debug_name: "send_payment", port: Some(port_), @@ -421,7 +424,7 @@ fn wire_send_spontaneous_payment_impl( port_: MessagePort, req: impl Wire2Api + UnwindSafe, ) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, SendPaymentResponse>( WrapInfo { debug_name: "send_spontaneous_payment", port: Some(port_), @@ -437,7 +440,7 @@ fn wire_receive_payment_impl( port_: MessagePort, req: impl Wire2Api + UnwindSafe, ) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, ReceivePaymentResponse>( WrapInfo { debug_name: "receive_payment", port: Some(port_), @@ -450,7 +453,7 @@ fn wire_receive_payment_impl( ) } fn wire_lnurl_pay_impl(port_: MessagePort, req: impl Wire2Api + UnwindSafe) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, LnUrlPayResult>( WrapInfo { debug_name: "lnurl_pay", port: Some(port_), @@ -466,7 +469,7 @@ fn wire_lnurl_withdraw_impl( port_: MessagePort, req: impl Wire2Api + UnwindSafe, ) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, LnUrlWithdrawResult>( WrapInfo { debug_name: "lnurl_withdraw", port: Some(port_), @@ -482,7 +485,7 @@ fn wire_lnurl_auth_impl( port_: MessagePort, req_data: impl Wire2Api + UnwindSafe, ) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, LnUrlCallbackStatus>( WrapInfo { debug_name: "lnurl_auth", port: Some(port_), @@ -495,7 +498,7 @@ fn wire_lnurl_auth_impl( ) } fn wire_fetch_fiat_rates_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, Vec>( WrapInfo { debug_name: "fetch_fiat_rates", port: Some(port_), @@ -505,7 +508,7 @@ fn wire_fetch_fiat_rates_impl(port_: MessagePort) { ) } fn wire_list_fiat_currencies_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, Vec>( WrapInfo { debug_name: "list_fiat_currencies", port: Some(port_), @@ -515,7 +518,7 @@ fn wire_list_fiat_currencies_impl(port_: MessagePort) { ) } fn wire_send_onchain_impl(port_: MessagePort, req: impl Wire2Api + UnwindSafe) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, SendOnchainResponse>( WrapInfo { debug_name: "send_onchain", port: Some(port_), @@ -531,7 +534,7 @@ fn wire_receive_onchain_impl( port_: MessagePort, req: impl Wire2Api + UnwindSafe, ) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, SwapInfo>( WrapInfo { debug_name: "receive_onchain", port: Some(port_), @@ -544,7 +547,7 @@ fn wire_receive_onchain_impl( ) } fn wire_buy_bitcoin_impl(port_: MessagePort, req: impl Wire2Api + UnwindSafe) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, BuyBitcoinResponse>( WrapInfo { debug_name: "buy_bitcoin", port: Some(port_), @@ -557,7 +560,7 @@ fn wire_buy_bitcoin_impl(port_: MessagePort, req: impl Wire2Api + UnwindSafe) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, SweepResponse>( WrapInfo { debug_name: "sweep", port: Some(port_), @@ -573,7 +576,7 @@ fn wire_prepare_sweep_impl( port_: MessagePort, req: impl Wire2Api + UnwindSafe, ) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, PrepareSweepResponse>( WrapInfo { debug_name: "prepare_sweep", port: Some(port_), @@ -586,7 +589,7 @@ fn wire_prepare_sweep_impl( ) } fn wire_list_refundables_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, Vec>( WrapInfo { debug_name: "list_refundables", port: Some(port_), @@ -599,7 +602,7 @@ fn wire_prepare_refund_impl( port_: MessagePort, req: impl Wire2Api + UnwindSafe, ) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, PrepareRefundResponse>( WrapInfo { debug_name: "prepare_refund", port: Some(port_), @@ -612,7 +615,7 @@ fn wire_prepare_refund_impl( ) } fn wire_refund_impl(port_: MessagePort, req: impl Wire2Api + UnwindSafe) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, RefundResponse>( WrapInfo { debug_name: "refund", port: Some(port_), @@ -625,7 +628,7 @@ fn wire_refund_impl(port_: MessagePort, req: impl Wire2Api + Unwi ) } fn wire_in_progress_swap_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, Option>( WrapInfo { debug_name: "in_progress_swap", port: Some(port_), @@ -635,7 +638,7 @@ fn wire_in_progress_swap_impl(port_: MessagePort) { ) } fn wire_in_progress_reverse_swaps_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, Vec>( WrapInfo { debug_name: "in_progress_reverse_swaps", port: Some(port_), @@ -648,7 +651,7 @@ fn wire_open_channel_fee_impl( port_: MessagePort, req: impl Wire2Api + UnwindSafe, ) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, OpenChannelFeeResponse>( WrapInfo { debug_name: "open_channel_fee", port: Some(port_), @@ -664,7 +667,7 @@ fn wire_fetch_reverse_swap_fees_impl( port_: MessagePort, req: impl Wire2Api + UnwindSafe, ) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, ReverseSwapPairInfo>( WrapInfo { debug_name: "fetch_reverse_swap_fees", port: Some(port_), @@ -677,7 +680,7 @@ fn wire_fetch_reverse_swap_fees_impl( ) } fn wire_recommended_fees_impl(port_: MessagePort) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, RecommendedFees>( WrapInfo { debug_name: "recommended_fees", port: Some(port_), @@ -687,7 +690,7 @@ fn wire_recommended_fees_impl(port_: MessagePort) { ) } fn wire_execute_command_impl(port_: MessagePort, command: impl Wire2Api + UnwindSafe) { - FLUTTER_RUST_BRIDGE_HANDLER.wrap( + FLUTTER_RUST_BRIDGE_HANDLER.wrap::<_, _, _, String>( WrapInfo { debug_name: "execute_command", port: Some(port_), @@ -811,34 +814,53 @@ impl Wire2Api for u8 { impl support::IntoDart for AesSuccessActionDataDecrypted { fn into_dart(self) -> support::DartAbi { - vec![self.description.into_dart(), self.plaintext.into_dart()].into_dart() + vec![ + self.description.into_into_dart().into_dart(), + self.plaintext.into_into_dart().into_dart(), + ] + .into_dart() } } impl support::IntoDartExceptPrimitive for AesSuccessActionDataDecrypted {} +impl rust2dart::IntoIntoDart for AesSuccessActionDataDecrypted { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for BackupFailedData { fn into_dart(self) -> support::DartAbi { - vec![self.error.into_dart()].into_dart() + vec![self.error.into_into_dart().into_dart()].into_dart() } } impl support::IntoDartExceptPrimitive for BackupFailedData {} +impl rust2dart::IntoIntoDart for BackupFailedData { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for BackupStatus { fn into_dart(self) -> support::DartAbi { vec![ - self.backed_up.into_dart(), + self.backed_up.into_into_dart().into_dart(), self.last_backup_time.into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for BackupStatus {} +impl rust2dart::IntoIntoDart for BackupStatus { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for BitcoinAddressData { fn into_dart(self) -> support::DartAbi { vec![ - self.address.into_dart(), - self.network.into_dart(), + self.address.into_into_dart().into_dart(), + self.network.into_into_dart().into_dart(), self.amount_sat.into_dart(), self.label.into_dart(), self.message.into_dart(), @@ -847,29 +869,57 @@ impl support::IntoDart for BitcoinAddressData { } } impl support::IntoDartExceptPrimitive for BitcoinAddressData {} +impl rust2dart::IntoIntoDart for BitcoinAddressData { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for BreezEvent { fn into_dart(self) -> support::DartAbi { match self { - Self::NewBlock { block } => vec![0.into_dart(), block.into_dart()], - Self::InvoicePaid { details } => vec![1.into_dart(), details.into_dart()], + Self::NewBlock { block } => vec![0.into_dart(), block.into_into_dart().into_dart()], + Self::InvoicePaid { details } => { + vec![1.into_dart(), details.into_into_dart().into_dart()] + } Self::Synced => vec![2.into_dart()], - Self::PaymentSucceed { details } => vec![3.into_dart(), details.into_dart()], - Self::PaymentFailed { details } => vec![4.into_dart(), details.into_dart()], + Self::PaymentSucceed { details } => { + vec![3.into_dart(), details.into_into_dart().into_dart()] + } + Self::PaymentFailed { details } => { + vec![4.into_dart(), details.into_into_dart().into_dart()] + } Self::BackupStarted => vec![5.into_dart()], Self::BackupSucceeded => vec![6.into_dart()], - Self::BackupFailed { details } => vec![7.into_dart(), details.into_dart()], + Self::BackupFailed { details } => { + vec![7.into_dart(), details.into_into_dart().into_dart()] + } } .into_dart() } } impl support::IntoDartExceptPrimitive for BreezEvent {} +impl rust2dart::IntoIntoDart for BreezEvent { + fn into_into_dart(self) -> Self { + self + } +} + impl support::IntoDart for BuyBitcoinResponse { fn into_dart(self) -> support::DartAbi { - vec![self.url.into_dart(), self.opening_fee_params.into_dart()].into_dart() + vec![ + self.url.into_into_dart().into_dart(), + self.opening_fee_params.into_dart(), + ] + .into_dart() } } impl support::IntoDartExceptPrimitive for BuyBitcoinResponse {} +impl rust2dart::IntoIntoDart for BuyBitcoinResponse { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for ChannelState { fn into_dart(self) -> support::DartAbi { @@ -883,50 +933,71 @@ impl support::IntoDart for ChannelState { } } impl support::IntoDartExceptPrimitive for ChannelState {} +impl rust2dart::IntoIntoDart for ChannelState { + fn into_into_dart(self) -> Self { + self + } +} + impl support::IntoDart for CheckMessageResponse { fn into_dart(self) -> support::DartAbi { - vec![self.is_valid.into_dart()].into_dart() + vec![self.is_valid.into_into_dart().into_dart()].into_dart() } } impl support::IntoDartExceptPrimitive for CheckMessageResponse {} +impl rust2dart::IntoIntoDart for CheckMessageResponse { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for ClosedChannelPaymentDetails { fn into_dart(self) -> support::DartAbi { vec![ - self.short_channel_id.into_dart(), - self.state.into_dart(), - self.funding_txid.into_dart(), + self.short_channel_id.into_into_dart().into_dart(), + self.state.into_into_dart().into_dart(), + self.funding_txid.into_into_dart().into_dart(), self.closing_txid.into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for ClosedChannelPaymentDetails {} +impl rust2dart::IntoIntoDart for ClosedChannelPaymentDetails { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for Config { fn into_dart(self) -> support::DartAbi { vec![ - self.breezserver.into_dart(), - self.mempoolspace_url.into_dart(), - self.working_dir.into_dart(), - self.network.into_dart(), - self.payment_timeout_sec.into_dart(), + self.breezserver.into_into_dart().into_dart(), + self.mempoolspace_url.into_into_dart().into_dart(), + self.working_dir.into_into_dart().into_dart(), + self.network.into_into_dart().into_dart(), + self.payment_timeout_sec.into_into_dart().into_dart(), self.default_lsp_id.into_dart(), self.api_key.into_dart(), - self.maxfee_percent.into_dart(), - self.exemptfee_msat.into_dart(), - self.node_config.into_dart(), + self.maxfee_percent.into_into_dart().into_dart(), + self.exemptfee_msat.into_into_dart().into_dart(), + self.node_config.into_into_dart().into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for Config {} +impl rust2dart::IntoIntoDart for Config { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for CurrencyInfo { fn into_dart(self) -> support::DartAbi { vec![ - self.name.into_dart(), - self.fraction_size.into_dart(), + self.name.into_into_dart().into_dart(), + self.fraction_size.into_into_dart().into_dart(), self.spacing.into_dart(), self.symbol.into_dart(), self.uniq_symbol.into_dart(), @@ -937,20 +1008,43 @@ impl support::IntoDart for CurrencyInfo { } } impl support::IntoDartExceptPrimitive for CurrencyInfo {} +impl rust2dart::IntoIntoDart for CurrencyInfo { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for FiatCurrency { fn into_dart(self) -> support::DartAbi { - vec![self.id.into_dart(), self.info.into_dart()].into_dart() + vec![ + self.id.into_into_dart().into_dart(), + self.info.into_into_dart().into_dart(), + ] + .into_dart() } } impl support::IntoDartExceptPrimitive for FiatCurrency {} +impl rust2dart::IntoIntoDart for FiatCurrency { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for GreenlightCredentials { fn into_dart(self) -> support::DartAbi { - vec![self.device_key.into_dart(), self.device_cert.into_dart()].into_dart() + vec![ + self.device_key.into_into_dart().into_dart(), + self.device_cert.into_into_dart().into_dart(), + ] + .into_dart() } } impl support::IntoDartExceptPrimitive for GreenlightCredentials {} +impl rust2dart::IntoIntoDart for GreenlightCredentials { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for GreenlightNodeConfig { fn into_dart(self) -> support::DartAbi { @@ -962,58 +1056,85 @@ impl support::IntoDart for GreenlightNodeConfig { } } impl support::IntoDartExceptPrimitive for GreenlightNodeConfig {} +impl rust2dart::IntoIntoDart for GreenlightNodeConfig { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for InputType { fn into_dart(self) -> support::DartAbi { match self { - Self::BitcoinAddress { address } => vec![0.into_dart(), address.into_dart()], - Self::Bolt11 { invoice } => vec![1.into_dart(), invoice.into_dart()], - Self::NodeId { node_id } => vec![2.into_dart(), node_id.into_dart()], - Self::Url { url } => vec![3.into_dart(), url.into_dart()], - Self::LnUrlPay { data } => vec![4.into_dart(), data.into_dart()], - Self::LnUrlWithdraw { data } => vec![5.into_dart(), data.into_dart()], - Self::LnUrlAuth { data } => vec![6.into_dart(), data.into_dart()], - Self::LnUrlError { data } => vec![7.into_dart(), data.into_dart()], + Self::BitcoinAddress { address } => { + vec![0.into_dart(), address.into_into_dart().into_dart()] + } + Self::Bolt11 { invoice } => vec![1.into_dart(), invoice.into_into_dart().into_dart()], + Self::NodeId { node_id } => vec![2.into_dart(), node_id.into_into_dart().into_dart()], + Self::Url { url } => vec![3.into_dart(), url.into_into_dart().into_dart()], + Self::LnUrlPay { data } => vec![4.into_dart(), data.into_into_dart().into_dart()], + Self::LnUrlWithdraw { data } => vec![5.into_dart(), data.into_into_dart().into_dart()], + Self::LnUrlAuth { data } => vec![6.into_dart(), data.into_into_dart().into_dart()], + Self::LnUrlError { data } => vec![7.into_dart(), data.into_into_dart().into_dart()], } .into_dart() } } impl support::IntoDartExceptPrimitive for InputType {} +impl rust2dart::IntoIntoDart for InputType { + fn into_into_dart(self) -> Self { + self + } +} + impl support::IntoDart for InvoicePaidDetails { fn into_dart(self) -> support::DartAbi { - vec![self.payment_hash.into_dart(), self.bolt11.into_dart()].into_dart() + vec![ + self.payment_hash.into_into_dart().into_dart(), + self.bolt11.into_into_dart().into_dart(), + ] + .into_dart() } } impl support::IntoDartExceptPrimitive for InvoicePaidDetails {} +impl rust2dart::IntoIntoDart for InvoicePaidDetails { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for LNInvoice { fn into_dart(self) -> support::DartAbi { vec![ - self.bolt11.into_dart(), - self.payee_pubkey.into_dart(), - self.payment_hash.into_dart(), + self.bolt11.into_into_dart().into_dart(), + self.payee_pubkey.into_into_dart().into_dart(), + self.payment_hash.into_into_dart().into_dart(), self.description.into_dart(), self.description_hash.into_dart(), self.amount_msat.into_dart(), - self.timestamp.into_dart(), - self.expiry.into_dart(), - self.routing_hints.into_dart(), - self.payment_secret.into_dart(), + self.timestamp.into_into_dart().into_dart(), + self.expiry.into_into_dart().into_dart(), + self.routing_hints.into_into_dart().into_dart(), + self.payment_secret.into_into_dart().into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for LNInvoice {} +impl rust2dart::IntoIntoDart for LNInvoice { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for LnPaymentDetails { fn into_dart(self) -> support::DartAbi { vec![ - self.payment_hash.into_dart(), - self.label.into_dart(), - self.destination_pubkey.into_dart(), - self.payment_preimage.into_dart(), - self.keysend.into_dart(), - self.bolt11.into_dart(), + self.payment_hash.into_into_dart().into_dart(), + self.label.into_into_dart().into_dart(), + self.destination_pubkey.into_into_dart().into_dart(), + self.payment_preimage.into_into_dart().into_dart(), + self.keysend.into_into_dart().into_dart(), + self.bolt11.into_into_dart().into_dart(), self.lnurl_success_action.into_dart(), self.ln_address.into_dart(), self.lnurl_metadata.into_dart(), @@ -1023,148 +1144,229 @@ impl support::IntoDart for LnPaymentDetails { } } impl support::IntoDartExceptPrimitive for LnPaymentDetails {} +impl rust2dart::IntoIntoDart for LnPaymentDetails { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for LnUrlAuthRequestData { fn into_dart(self) -> support::DartAbi { vec![ - self.k1.into_dart(), + self.k1.into_into_dart().into_dart(), self.action.into_dart(), - self.domain.into_dart(), - self.url.into_dart(), + self.domain.into_into_dart().into_dart(), + self.url.into_into_dart().into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for LnUrlAuthRequestData {} +impl rust2dart::IntoIntoDart for LnUrlAuthRequestData { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for LnUrlCallbackStatus { fn into_dart(self) -> support::DartAbi { match self { Self::Ok => vec![0.into_dart()], - Self::ErrorStatus { data } => vec![1.into_dart(), data.into_dart()], + Self::ErrorStatus { data } => vec![1.into_dart(), data.into_into_dart().into_dart()], } .into_dart() } } impl support::IntoDartExceptPrimitive for LnUrlCallbackStatus {} +impl rust2dart::IntoIntoDart for LnUrlCallbackStatus { + fn into_into_dart(self) -> Self { + self + } +} + impl support::IntoDart for LnUrlErrorData { fn into_dart(self) -> support::DartAbi { - vec![self.reason.into_dart()].into_dart() + vec![self.reason.into_into_dart().into_dart()].into_dart() } } impl support::IntoDartExceptPrimitive for LnUrlErrorData {} +impl rust2dart::IntoIntoDart for LnUrlErrorData { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for LnUrlPayRequestData { fn into_dart(self) -> support::DartAbi { vec![ - self.callback.into_dart(), - self.min_sendable.into_dart(), - self.max_sendable.into_dart(), - self.metadata_str.into_dart(), - self.comment_allowed.into_dart(), - self.domain.into_dart(), + self.callback.into_into_dart().into_dart(), + self.min_sendable.into_into_dart().into_dart(), + self.max_sendable.into_into_dart().into_dart(), + self.metadata_str.into_into_dart().into_dart(), + self.comment_allowed.into_into_dart().into_dart(), + self.domain.into_into_dart().into_dart(), self.ln_address.into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for LnUrlPayRequestData {} +impl rust2dart::IntoIntoDart for LnUrlPayRequestData { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for LnUrlPayResult { fn into_dart(self) -> support::DartAbi { match self { Self::EndpointSuccess { data } => vec![0.into_dart(), data.into_dart()], - Self::EndpointError { data } => vec![1.into_dart(), data.into_dart()], + Self::EndpointError { data } => vec![1.into_dart(), data.into_into_dart().into_dart()], } .into_dart() } } impl support::IntoDartExceptPrimitive for LnUrlPayResult {} +impl rust2dart::IntoIntoDart for LnUrlPayResult { + fn into_into_dart(self) -> Self { + self + } +} + impl support::IntoDart for LnUrlWithdrawRequestData { fn into_dart(self) -> support::DartAbi { vec![ - self.callback.into_dart(), - self.k1.into_dart(), - self.default_description.into_dart(), - self.min_withdrawable.into_dart(), - self.max_withdrawable.into_dart(), + self.callback.into_into_dart().into_dart(), + self.k1.into_into_dart().into_dart(), + self.default_description.into_into_dart().into_dart(), + self.min_withdrawable.into_into_dart().into_dart(), + self.max_withdrawable.into_into_dart().into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for LnUrlWithdrawRequestData {} +impl rust2dart::IntoIntoDart for LnUrlWithdrawRequestData { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for LnUrlWithdrawResult { fn into_dart(self) -> support::DartAbi { match self { - Self::Ok { data } => vec![0.into_dart(), data.into_dart()], - Self::ErrorStatus { data } => vec![1.into_dart(), data.into_dart()], + Self::Ok { data } => vec![0.into_dart(), data.into_into_dart().into_dart()], + Self::ErrorStatus { data } => vec![1.into_dart(), data.into_into_dart().into_dart()], } .into_dart() } } impl support::IntoDartExceptPrimitive for LnUrlWithdrawResult {} +impl rust2dart::IntoIntoDart for LnUrlWithdrawResult { + fn into_into_dart(self) -> Self { + self + } +} + impl support::IntoDart for LnUrlWithdrawSuccessData { fn into_dart(self) -> support::DartAbi { - vec![self.invoice.into_dart()].into_dart() + vec![self.invoice.into_into_dart().into_dart()].into_dart() } } impl support::IntoDartExceptPrimitive for LnUrlWithdrawSuccessData {} +impl rust2dart::IntoIntoDart for LnUrlWithdrawSuccessData { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for LocaleOverrides { fn into_dart(self) -> support::DartAbi { vec![ - self.locale.into_dart(), + self.locale.into_into_dart().into_dart(), self.spacing.into_dart(), - self.symbol.into_dart(), + self.symbol.into_into_dart().into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for LocaleOverrides {} +impl rust2dart::IntoIntoDart for LocaleOverrides { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for LocalizedName { fn into_dart(self) -> support::DartAbi { - vec![self.locale.into_dart(), self.name.into_dart()].into_dart() + vec![ + self.locale.into_into_dart().into_dart(), + self.name.into_into_dart().into_dart(), + ] + .into_dart() } } impl support::IntoDartExceptPrimitive for LocalizedName {} +impl rust2dart::IntoIntoDart for LocalizedName { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for LogEntry { fn into_dart(self) -> support::DartAbi { - vec![self.line.into_dart(), self.level.into_dart()].into_dart() + vec![ + self.line.into_into_dart().into_dart(), + self.level.into_into_dart().into_dart(), + ] + .into_dart() } } impl support::IntoDartExceptPrimitive for LogEntry {} +impl rust2dart::IntoIntoDart for LogEntry { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for LspInformation { fn into_dart(self) -> support::DartAbi { vec![ - self.id.into_dart(), - self.name.into_dart(), - self.widget_url.into_dart(), - self.pubkey.into_dart(), - self.host.into_dart(), - self.channel_capacity.into_dart(), - self.target_conf.into_dart(), - self.base_fee_msat.into_dart(), - self.fee_rate.into_dart(), - self.time_lock_delta.into_dart(), - self.min_htlc_msat.into_dart(), - self.lsp_pubkey.into_dart(), - self.opening_fee_params_list.into_dart(), + self.id.into_into_dart().into_dart(), + self.name.into_into_dart().into_dart(), + self.widget_url.into_into_dart().into_dart(), + self.pubkey.into_into_dart().into_dart(), + self.host.into_into_dart().into_dart(), + self.channel_capacity.into_into_dart().into_dart(), + self.target_conf.into_into_dart().into_dart(), + self.base_fee_msat.into_into_dart().into_dart(), + self.fee_rate.into_into_dart().into_dart(), + self.time_lock_delta.into_into_dart().into_dart(), + self.min_htlc_msat.into_into_dart().into_dart(), + self.lsp_pubkey.into_into_dart().into_dart(), + self.opening_fee_params_list.into_into_dart().into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for LspInformation {} +impl rust2dart::IntoIntoDart for LspInformation { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for MessageSuccessActionData { fn into_dart(self) -> support::DartAbi { - vec![self.message.into_dart()].into_dart() + vec![self.message.into_into_dart().into_dart()].into_dart() } } impl support::IntoDartExceptPrimitive for MessageSuccessActionData {} +impl rust2dart::IntoIntoDart for MessageSuccessActionData { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for Network { fn into_dart(self) -> support::DartAbi { @@ -1178,102 +1380,156 @@ impl support::IntoDart for Network { } } impl support::IntoDartExceptPrimitive for Network {} +impl rust2dart::IntoIntoDart for Network { + fn into_into_dart(self) -> Self { + self + } +} + impl support::IntoDart for NodeConfig { fn into_dart(self) -> support::DartAbi { match self { - Self::Greenlight { config } => vec![0.into_dart(), config.into_dart()], + Self::Greenlight { config } => vec![0.into_dart(), config.into_into_dart().into_dart()], } .into_dart() } } impl support::IntoDartExceptPrimitive for NodeConfig {} +impl rust2dart::IntoIntoDart for NodeConfig { + fn into_into_dart(self) -> Self { + self + } +} + impl support::IntoDart for NodeState { fn into_dart(self) -> support::DartAbi { vec![ - self.id.into_dart(), - self.block_height.into_dart(), - self.channels_balance_msat.into_dart(), - self.onchain_balance_msat.into_dart(), - self.utxos.into_dart(), - self.max_payable_msat.into_dart(), - self.max_receivable_msat.into_dart(), - self.max_single_payment_amount_msat.into_dart(), - self.max_chan_reserve_msats.into_dart(), - self.connected_peers.into_dart(), - self.inbound_liquidity_msats.into_dart(), + self.id.into_into_dart().into_dart(), + self.block_height.into_into_dart().into_dart(), + self.channels_balance_msat.into_into_dart().into_dart(), + self.onchain_balance_msat.into_into_dart().into_dart(), + self.utxos.into_into_dart().into_dart(), + self.max_payable_msat.into_into_dart().into_dart(), + self.max_receivable_msat.into_into_dart().into_dart(), + self.max_single_payment_amount_msat + .into_into_dart() + .into_dart(), + self.max_chan_reserve_msats.into_into_dart().into_dart(), + self.connected_peers.into_into_dart().into_dart(), + self.inbound_liquidity_msats.into_into_dart().into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for NodeState {} +impl rust2dart::IntoIntoDart for NodeState { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for OpenChannelFeeResponse { fn into_dart(self) -> support::DartAbi { - vec![self.fee_msat.into_dart(), self.used_fee_params.into_dart()].into_dart() + vec![ + self.fee_msat.into_into_dart().into_dart(), + self.used_fee_params.into_dart(), + ] + .into_dart() } } impl support::IntoDartExceptPrimitive for OpenChannelFeeResponse {} +impl rust2dart::IntoIntoDart for OpenChannelFeeResponse { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for OpeningFeeParams { fn into_dart(self) -> support::DartAbi { vec![ - self.min_msat.into_dart(), - self.proportional.into_dart(), - self.valid_until.into_dart(), - self.max_idle_time.into_dart(), - self.max_client_to_self_delay.into_dart(), - self.promise.into_dart(), + self.min_msat.into_into_dart().into_dart(), + self.proportional.into_into_dart().into_dart(), + self.valid_until.into_into_dart().into_dart(), + self.max_idle_time.into_into_dart().into_dart(), + self.max_client_to_self_delay.into_into_dart().into_dart(), + self.promise.into_into_dart().into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for OpeningFeeParams {} +impl rust2dart::IntoIntoDart for OpeningFeeParams { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for OpeningFeeParamsMenu { fn into_dart(self) -> support::DartAbi { - vec![self.values.into_dart()].into_dart() + vec![self.values.into_into_dart().into_dart()].into_dart() } } impl support::IntoDartExceptPrimitive for OpeningFeeParamsMenu {} +impl rust2dart::IntoIntoDart for OpeningFeeParamsMenu { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for Payment { fn into_dart(self) -> support::DartAbi { vec![ - self.id.into_dart(), - self.payment_type.into_dart(), - self.payment_time.into_dart(), - self.amount_msat.into_dart(), - self.fee_msat.into_dart(), - self.status.into_dart(), + self.id.into_into_dart().into_dart(), + self.payment_type.into_into_dart().into_dart(), + self.payment_time.into_into_dart().into_dart(), + self.amount_msat.into_into_dart().into_dart(), + self.fee_msat.into_into_dart().into_dart(), + self.status.into_into_dart().into_dart(), self.description.into_dart(), - self.details.into_dart(), + self.details.into_into_dart().into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for Payment {} +impl rust2dart::IntoIntoDart for Payment { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for PaymentDetails { fn into_dart(self) -> support::DartAbi { match self { - Self::Ln { data } => vec![0.into_dart(), data.into_dart()], - Self::ClosedChannel { data } => vec![1.into_dart(), data.into_dart()], + Self::Ln { data } => vec![0.into_dart(), data.into_into_dart().into_dart()], + Self::ClosedChannel { data } => vec![1.into_dart(), data.into_into_dart().into_dart()], } .into_dart() } } impl support::IntoDartExceptPrimitive for PaymentDetails {} +impl rust2dart::IntoIntoDart for PaymentDetails { + fn into_into_dart(self) -> Self { + self + } +} + impl support::IntoDart for PaymentFailedData { fn into_dart(self) -> support::DartAbi { vec![ - self.error.into_dart(), - self.node_id.into_dart(), + self.error.into_into_dart().into_dart(), + self.node_id.into_into_dart().into_dart(), self.invoice.into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for PaymentFailedData {} +impl rust2dart::IntoIntoDart for PaymentFailedData { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for PaymentStatus { fn into_dart(self) -> support::DartAbi { @@ -1286,6 +1542,12 @@ impl support::IntoDart for PaymentStatus { } } impl support::IntoDartExceptPrimitive for PaymentStatus {} +impl rust2dart::IntoIntoDart for PaymentStatus { + fn into_into_dart(self) -> Self { + self + } +} + impl support::IntoDart for PaymentType { fn into_dart(self) -> support::DartAbi { match self { @@ -1297,39 +1559,64 @@ impl support::IntoDart for PaymentType { } } impl support::IntoDartExceptPrimitive for PaymentType {} +impl rust2dart::IntoIntoDart for PaymentType { + fn into_into_dart(self) -> Self { + self + } +} + impl support::IntoDart for PrepareRefundResponse { fn into_dart(self) -> support::DartAbi { vec![ - self.refund_tx_weight.into_dart(), - self.refund_tx_fee_sat.into_dart(), + self.refund_tx_weight.into_into_dart().into_dart(), + self.refund_tx_fee_sat.into_into_dart().into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for PrepareRefundResponse {} +impl rust2dart::IntoIntoDart for PrepareRefundResponse { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for PrepareSweepResponse { fn into_dart(self) -> support::DartAbi { vec![ - self.sweep_tx_weight.into_dart(), - self.sweep_tx_fee_sat.into_dart(), + self.sweep_tx_weight.into_into_dart().into_dart(), + self.sweep_tx_fee_sat.into_into_dart().into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for PrepareSweepResponse {} +impl rust2dart::IntoIntoDart for PrepareSweepResponse { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for Rate { fn into_dart(self) -> support::DartAbi { - vec![self.coin.into_dart(), self.value.into_dart()].into_dart() + vec![ + self.coin.into_into_dart().into_dart(), + self.value.into_into_dart().into_dart(), + ] + .into_dart() } } impl support::IntoDartExceptPrimitive for Rate {} +impl rust2dart::IntoIntoDart for Rate { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for ReceivePaymentResponse { fn into_dart(self) -> support::DartAbi { vec![ - self.ln_invoice.into_dart(), + self.ln_invoice.into_into_dart().into_dart(), self.opening_fee_params.into_dart(), self.opening_fee_msat.into_dart(), ] @@ -1337,58 +1624,83 @@ impl support::IntoDart for ReceivePaymentResponse { } } impl support::IntoDartExceptPrimitive for ReceivePaymentResponse {} +impl rust2dart::IntoIntoDart for ReceivePaymentResponse { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for RecommendedFees { fn into_dart(self) -> support::DartAbi { vec![ - self.fastest_fee.into_dart(), - self.half_hour_fee.into_dart(), - self.hour_fee.into_dart(), - self.economy_fee.into_dart(), - self.minimum_fee.into_dart(), + self.fastest_fee.into_into_dart().into_dart(), + self.half_hour_fee.into_into_dart().into_dart(), + self.hour_fee.into_into_dart().into_dart(), + self.economy_fee.into_into_dart().into_dart(), + self.minimum_fee.into_into_dart().into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for RecommendedFees {} +impl rust2dart::IntoIntoDart for RecommendedFees { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for RefundResponse { fn into_dart(self) -> support::DartAbi { - vec![self.refund_tx_id.into_dart()].into_dart() + vec![self.refund_tx_id.into_into_dart().into_dart()].into_dart() } } impl support::IntoDartExceptPrimitive for RefundResponse {} +impl rust2dart::IntoIntoDart for RefundResponse { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for ReverseSwapInfo { fn into_dart(self) -> support::DartAbi { vec![ - self.id.into_dart(), - self.claim_pubkey.into_dart(), + self.id.into_into_dart().into_dart(), + self.claim_pubkey.into_into_dart().into_dart(), self.lockup_txid.into_dart(), self.claim_txid.into_dart(), - self.onchain_amount_sat.into_dart(), - self.status.into_dart(), + self.onchain_amount_sat.into_into_dart().into_dart(), + self.status.into_into_dart().into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for ReverseSwapInfo {} +impl rust2dart::IntoIntoDart for ReverseSwapInfo { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for ReverseSwapPairInfo { fn into_dart(self) -> support::DartAbi { vec![ - self.min.into_dart(), - self.max.into_dart(), - self.fees_hash.into_dart(), - self.fees_percentage.into_dart(), - self.fees_lockup.into_dart(), - self.fees_claim.into_dart(), + self.min.into_into_dart().into_dart(), + self.max.into_into_dart().into_dart(), + self.fees_hash.into_into_dart().into_dart(), + self.fees_percentage.into_into_dart().into_dart(), + self.fees_lockup.into_into_dart().into_dart(), + self.fees_claim.into_into_dart().into_dart(), self.total_estimated_fees.into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for ReverseSwapPairInfo {} +impl rust2dart::IntoIntoDart for ReverseSwapPairInfo { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for ReverseSwapStatus { fn into_dart(self) -> support::DartAbi { @@ -1403,21 +1715,34 @@ impl support::IntoDart for ReverseSwapStatus { } } impl support::IntoDartExceptPrimitive for ReverseSwapStatus {} +impl rust2dart::IntoIntoDart for ReverseSwapStatus { + fn into_into_dart(self) -> Self { + self + } +} + impl support::IntoDart for RouteHint { fn into_dart(self) -> support::DartAbi { - vec![self.hops.into_dart()].into_dart() + vec![self.hops.into_into_dart().into_dart()].into_dart() } } impl support::IntoDartExceptPrimitive for RouteHint {} +impl rust2dart::IntoIntoDart for RouteHint { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for RouteHintHop { fn into_dart(self) -> support::DartAbi { vec![ - self.src_node_id.into_dart(), - self.short_channel_id.into_dart(), - self.fees_base_msat.into_dart(), - self.fees_proportional_millionths.into_dart(), - self.cltv_expiry_delta.into_dart(), + self.src_node_id.into_into_dart().into_dart(), + self.short_channel_id.into_into_dart().into_dart(), + self.fees_base_msat.into_into_dart().into_dart(), + self.fees_proportional_millionths + .into_into_dart() + .into_dart(), + self.cltv_expiry_delta.into_into_dart().into_dart(), self.htlc_minimum_msat.into_dart(), self.htlc_maximum_msat.into_dart(), ] @@ -1425,27 +1750,47 @@ impl support::IntoDart for RouteHintHop { } } impl support::IntoDartExceptPrimitive for RouteHintHop {} +impl rust2dart::IntoIntoDart for RouteHintHop { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for SendOnchainResponse { fn into_dart(self) -> support::DartAbi { - vec![self.reverse_swap_info.into_dart()].into_dart() + vec![self.reverse_swap_info.into_into_dart().into_dart()].into_dart() } } impl support::IntoDartExceptPrimitive for SendOnchainResponse {} +impl rust2dart::IntoIntoDart for SendOnchainResponse { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for SendPaymentResponse { fn into_dart(self) -> support::DartAbi { - vec![self.payment.into_dart()].into_dart() + vec![self.payment.into_into_dart().into_dart()].into_dart() } } impl support::IntoDartExceptPrimitive for SendPaymentResponse {} +impl rust2dart::IntoIntoDart for SendPaymentResponse { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for SignMessageResponse { fn into_dart(self) -> support::DartAbi { - vec![self.signature.into_dart()].into_dart() + vec![self.signature.into_into_dart().into_dart()].into_dart() } } impl support::IntoDartExceptPrimitive for SignMessageResponse {} +impl rust2dart::IntoIntoDart for SignMessageResponse { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for StaticBackupResponse { fn into_dart(self) -> support::DartAbi { @@ -1453,40 +1798,51 @@ impl support::IntoDart for StaticBackupResponse { } } impl support::IntoDartExceptPrimitive for StaticBackupResponse {} +impl rust2dart::IntoIntoDart for StaticBackupResponse { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for SuccessActionProcessed { fn into_dart(self) -> support::DartAbi { match self { - Self::Aes { data } => vec![0.into_dart(), data.into_dart()], - Self::Message { data } => vec![1.into_dart(), data.into_dart()], - Self::Url { data } => vec![2.into_dart(), data.into_dart()], + Self::Aes { data } => vec![0.into_dart(), data.into_into_dart().into_dart()], + Self::Message { data } => vec![1.into_dart(), data.into_into_dart().into_dart()], + Self::Url { data } => vec![2.into_dart(), data.into_into_dart().into_dart()], } .into_dart() } } impl support::IntoDartExceptPrimitive for SuccessActionProcessed {} +impl rust2dart::IntoIntoDart for SuccessActionProcessed { + fn into_into_dart(self) -> Self { + self + } +} + impl support::IntoDart for SwapInfo { fn into_dart(self) -> support::DartAbi { vec![ - self.bitcoin_address.into_dart(), - self.created_at.into_dart(), - self.lock_height.into_dart(), - self.payment_hash.into_dart(), - self.preimage.into_dart(), - self.private_key.into_dart(), - self.public_key.into_dart(), - self.swapper_public_key.into_dart(), - self.script.into_dart(), + self.bitcoin_address.into_into_dart().into_dart(), + self.created_at.into_into_dart().into_dart(), + self.lock_height.into_into_dart().into_dart(), + self.payment_hash.into_into_dart().into_dart(), + self.preimage.into_into_dart().into_dart(), + self.private_key.into_into_dart().into_dart(), + self.public_key.into_into_dart().into_dart(), + self.swapper_public_key.into_into_dart().into_dart(), + self.script.into_into_dart().into_dart(), self.bolt11.into_dart(), - self.paid_sats.into_dart(), - self.confirmed_sats.into_dart(), - self.unconfirmed_sats.into_dart(), - self.status.into_dart(), - self.refund_tx_ids.into_dart(), - self.unconfirmed_tx_ids.into_dart(), - self.confirmed_tx_ids.into_dart(), - self.min_allowed_deposit.into_dart(), - self.max_allowed_deposit.into_dart(), + self.paid_sats.into_into_dart().into_dart(), + self.confirmed_sats.into_into_dart().into_dart(), + self.unconfirmed_sats.into_into_dart().into_dart(), + self.status.into_into_dart().into_dart(), + self.refund_tx_ids.into_into_dart().into_dart(), + self.unconfirmed_tx_ids.into_into_dart().into_dart(), + self.confirmed_tx_ids.into_into_dart().into_dart(), + self.min_allowed_deposit.into_into_dart().into_dart(), + self.max_allowed_deposit.into_into_dart().into_dart(), self.last_redeem_error.into_dart(), self.channel_opening_fees.into_dart(), ] @@ -1494,6 +1850,11 @@ impl support::IntoDart for SwapInfo { } } impl support::IntoDartExceptPrimitive for SwapInfo {} +impl rust2dart::IntoIntoDart for SwapInfo { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for SwapStatus { fn into_dart(self) -> support::DartAbi { @@ -1505,12 +1866,23 @@ impl support::IntoDart for SwapStatus { } } impl support::IntoDartExceptPrimitive for SwapStatus {} +impl rust2dart::IntoIntoDart for SwapStatus { + fn into_into_dart(self) -> Self { + self + } +} + impl support::IntoDart for SweepResponse { fn into_dart(self) -> support::DartAbi { - vec![self.txid.into_dart()].into_dart() + vec![self.txid.into_into_dart().into_dart()].into_dart() } } impl support::IntoDartExceptPrimitive for SweepResponse {} +impl rust2dart::IntoIntoDart for SweepResponse { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for Symbol { fn into_dart(self) -> support::DartAbi { @@ -1524,27 +1896,46 @@ impl support::IntoDart for Symbol { } } impl support::IntoDartExceptPrimitive for Symbol {} +impl rust2dart::IntoIntoDart for Symbol { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for UnspentTransactionOutput { fn into_dart(self) -> support::DartAbi { vec![ - self.txid.into_dart(), - self.outnum.into_dart(), - self.amount_millisatoshi.into_dart(), - self.address.into_dart(), - self.reserved.into_dart(), + self.txid.into_into_dart().into_dart(), + self.outnum.into_into_dart().into_dart(), + self.amount_millisatoshi.into_into_dart().into_dart(), + self.address.into_into_dart().into_dart(), + self.reserved.into_into_dart().into_dart(), ] .into_dart() } } impl support::IntoDartExceptPrimitive for UnspentTransactionOutput {} +impl rust2dart::IntoIntoDart for UnspentTransactionOutput { + fn into_into_dart(self) -> Self { + self + } +} impl support::IntoDart for UrlSuccessActionData { fn into_dart(self) -> support::DartAbi { - vec![self.description.into_dart(), self.url.into_dart()].into_dart() + vec![ + self.description.into_into_dart().into_dart(), + self.url.into_into_dart().into_dart(), + ] + .into_dart() } } impl support::IntoDartExceptPrimitive for UrlSuccessActionData {} +impl rust2dart::IntoIntoDart for UrlSuccessActionData { + fn into_into_dart(self) -> Self { + self + } +} // Section: executor diff --git a/libs/sdk-flutter/.gitignore b/libs/sdk-flutter/.gitignore index 567609b12..5ff897d48 100644 --- a/libs/sdk-flutter/.gitignore +++ b/libs/sdk-flutter/.gitignore @@ -1 +1,2 @@ build/ +.flutter-version \ No newline at end of file diff --git a/libs/sdk-flutter/CHANGELOG.md b/libs/sdk-flutter/CHANGELOG.md index 41cc7d819..ceed694cb 100644 --- a/libs/sdk-flutter/CHANGELOG.md +++ b/libs/sdk-flutter/CHANGELOG.md @@ -1,3 +1,16 @@ -## 0.0.1 +SDK release notes can be found at [breez-sdk/releases](https://github.com/breez/breez-sdk/releases/) -* TODO: Describe initial release. +## 0.2.8 +* Requires Dart 3.0 or later. +* Migrate to null safety. +* Introduce `prepareRefund` API +* **Breaking** `filter` field of `ListPaymentsRequest` is deprecated and must be replaced with the optional `filters` field. +* **Breaking** `PaymentTypeFilter.All` is removed. Unfiltered payment list will be retrieved if `filters` fields of `ListPaymentsRequest` is left empty(_or is a list that contains all PaymentTypeFilter types_). +* `ClosedChannel` transactions can now be filtered by adding `PaymentTypeFilter.ClosedChannels` to the `filters` list. + +## 0.2.7 +* **Breaking** All APIs which previously allowed multiple parameters to be + passed now require their corresponding `Request` object. + These API's include: `sendOnchain`, `sendPayment`, `sendSpontaneousPayment`, `refund`, `lnurlPay`, `lnurlWithdraw` +* **Breaking** All `request` params is renamed to `req` +* **Breaking** All `reqData` params that belong to a `req` object(_lnurlPay,lnurlWithdraw except lnurlAuth_) is renamed to `data` \ No newline at end of file diff --git a/libs/sdk-flutter/README.md b/libs/sdk-flutter/README.md index 3167f0c6b..0217b4b3a 100644 --- a/libs/sdk-flutter/README.md +++ b/libs/sdk-flutter/README.md @@ -6,7 +6,7 @@ The [flutter_rust_bridge](https://github.com/fzyzcjy/flutter_rust_bridge) is use ## Build ### Prerequisites: -* Flutter version `3.7.12` +* Flutter version `3.13.8` * set the ANDROID_NDK_HOME env variable to your sdk home folder ``` export ANDROID_NDK_HOME= @@ -26,7 +26,7 @@ cargo install cargo-ndk ``` * Install [flutter_rust_bridge](https://github.com/fzyzcjy/flutter_rust_bridge): ``` -cargo install flutter_rust_bridge_codegen --version 1.75.2 +cargo install flutter_rust_bridge_codegen --version 1.80.1 ``` ## Building the plugin diff --git a/libs/sdk-flutter/lib/breez_sdk.dart b/libs/sdk-flutter/lib/breez_sdk.dart index e3fffe7f4..116b076a7 100644 --- a/libs/sdk-flutter/lib/breez_sdk.dart +++ b/libs/sdk-flutter/lib/breez_sdk.dart @@ -312,7 +312,7 @@ class BreezSDK { required SweepRequest req, }) async { final sweepResponse = await _lnToolkit.sweep(req: req); - await listPayments(req: const ListPaymentsRequest(filter: PaymentTypeFilter.All)); + await listPayments(req: const ListPaymentsRequest()); return sweepResponse; } @@ -402,7 +402,7 @@ class BreezSDK { /// Fetch node state & payment list Future fetchNodeData() async { await nodeInfo(); - await listPayments(req: const ListPaymentsRequest(filter: PaymentTypeFilter.All)); + await listPayments(req: const ListPaymentsRequest()); } } diff --git a/libs/sdk-flutter/lib/bridge_generated.dart b/libs/sdk-flutter/lib/bridge_generated.dart index 1bd42d724..5a53d6144 100644 --- a/libs/sdk-flutter/lib/bridge_generated.dart +++ b/libs/sdk-flutter/lib/bridge_generated.dart @@ -1,5 +1,5 @@ // AUTO GENERATED FILE, DO NOT EDIT. -// Generated by `flutter_rust_bridge`@ 1.75.2. +// Generated by `flutter_rust_bridge`@ 1.80.1. // ignore_for_file: non_constant_identifier_names, unused_element, duplicate_ignore, directives_ordering, curly_braces_in_flow_control_structures, unnecessary_lambdas, slash_for_doc_comments, prefer_const_literals_to_create_immutables, implicit_dynamic_list_literal, duplicate_import, unused_import, unnecessary_import, prefer_single_quotes, prefer_const_constructors, use_super_parameters, always_use_package_imports, annotate_overrides, invalid_use_of_protected_member, constant_identifier_names, invalid_use_of_internal_member, prefer_is_empty, unnecessary_const import 'dart:convert'; @@ -298,7 +298,7 @@ class BitcoinAddressData { } @freezed -class BreezEvent with _$BreezEvent { +sealed class BreezEvent with _$BreezEvent { /// Indicates that a new block has just been found const factory BreezEvent.newBlock({ required int block, @@ -510,7 +510,7 @@ class GreenlightNodeConfig { } @freezed -class InputType with _$InputType { +sealed class InputType with _$InputType { /// # Supported standards /// /// - plain on-chain BTC address @@ -690,7 +690,7 @@ class LnUrlAuthRequestData { } @freezed -class LnUrlCallbackStatus with _$LnUrlCallbackStatus { +sealed class LnUrlCallbackStatus with _$LnUrlCallbackStatus { /// On-wire format is: `{"status": "OK"}` const factory LnUrlCallbackStatus.ok() = LnUrlCallbackStatus_Ok; @@ -771,7 +771,7 @@ class LnUrlPayRequestData { } @freezed -class LnUrlPayResult with _$LnUrlPayResult { +sealed class LnUrlPayResult with _$LnUrlPayResult { const factory LnUrlPayResult.endpointSuccess({ SuccessActionProcessed? data, }) = LnUrlPayResult_EndpointSuccess; @@ -827,7 +827,7 @@ class LnUrlWithdrawRequestData { } @freezed -class LnUrlWithdrawResult with _$LnUrlWithdrawResult { +sealed class LnUrlWithdrawResult with _$LnUrlWithdrawResult { const factory LnUrlWithdrawResult.ok({ required LnUrlWithdrawSuccessData data, }) = LnUrlWithdrawResult_Ok; @@ -950,7 +950,7 @@ enum Network { } @freezed -class NodeConfig with _$NodeConfig { +sealed class NodeConfig with _$NodeConfig { const factory NodeConfig.greenlight({ required GreenlightNodeConfig config, }) = NodeConfig_Greenlight; @@ -1067,7 +1067,7 @@ class Payment { } @freezed -class PaymentDetails with _$PaymentDetails { +sealed class PaymentDetails with _$PaymentDetails { const factory PaymentDetails.ln({ required LnPaymentDetails data, }) = PaymentDetails_Ln; @@ -1492,7 +1492,7 @@ class StaticBackupResponse { } @freezed -class SuccessActionProcessed with _$SuccessActionProcessed { +sealed class SuccessActionProcessed with _$SuccessActionProcessed { /// See [SuccessAction::Aes] for received payload /// /// See [AesSuccessActionDataDecrypted] for decrypted payload @@ -5114,43 +5114,43 @@ class BreezSdkCoreWire implements FlutterRustBridgeWireBase { late final _free_WireSyncReturn = _free_WireSyncReturnPtr.asFunction(); } -class _Dart_Handle extends ffi.Opaque {} +final class _Dart_Handle extends ffi.Opaque {} -class wire_uint_8_list extends ffi.Struct { +final class wire_uint_8_list extends ffi.Struct { external ffi.Pointer ptr; @ffi.Int32() external int len; } -class wire_GreenlightCredentials extends ffi.Struct { +final class wire_GreenlightCredentials extends ffi.Struct { external ffi.Pointer device_key; external ffi.Pointer device_cert; } -class wire_GreenlightNodeConfig extends ffi.Struct { +final class wire_GreenlightNodeConfig extends ffi.Struct { external ffi.Pointer partner_credentials; external ffi.Pointer invite_code; } -class wire_NodeConfig_Greenlight extends ffi.Struct { +final class wire_NodeConfig_Greenlight extends ffi.Struct { external ffi.Pointer config; } -class NodeConfigKind extends ffi.Union { +final class NodeConfigKind extends ffi.Union { external ffi.Pointer Greenlight; } -class wire_NodeConfig extends ffi.Struct { +final class wire_NodeConfig extends ffi.Struct { @ffi.Int32() external int tag; external ffi.Pointer kind; } -class wire_Config extends ffi.Struct { +final class wire_Config extends ffi.Struct { external ffi.Pointer breezserver; external ffi.Pointer mempoolspace_url; @@ -5176,11 +5176,11 @@ class wire_Config extends ffi.Struct { external wire_NodeConfig node_config; } -class wire_SignMessageRequest extends ffi.Struct { +final class wire_SignMessageRequest extends ffi.Struct { external ffi.Pointer message; } -class wire_CheckMessageRequest extends ffi.Struct { +final class wire_CheckMessageRequest extends ffi.Struct { external ffi.Pointer message; external ffi.Pointer pubkey; @@ -5188,18 +5188,18 @@ class wire_CheckMessageRequest extends ffi.Struct { external ffi.Pointer signature; } -class wire_StaticBackupRequest extends ffi.Struct { +final class wire_StaticBackupRequest extends ffi.Struct { external ffi.Pointer working_dir; } -class wire_list_payment_type_filter extends ffi.Struct { +final class wire_list_payment_type_filter extends ffi.Struct { external ffi.Pointer ptr; @ffi.Int32() external int len; } -class wire_ListPaymentsRequest extends ffi.Struct { +final class wire_ListPaymentsRequest extends ffi.Struct { external ffi.Pointer filters; external ffi.Pointer from_timestamp; @@ -5213,20 +5213,20 @@ class wire_ListPaymentsRequest extends ffi.Struct { external ffi.Pointer limit; } -class wire_SendPaymentRequest extends ffi.Struct { +final class wire_SendPaymentRequest extends ffi.Struct { external ffi.Pointer bolt11; external ffi.Pointer amount_msat; } -class wire_SendSpontaneousPaymentRequest extends ffi.Struct { +final class wire_SendSpontaneousPaymentRequest extends ffi.Struct { external ffi.Pointer node_id; @ffi.Uint64() external int amount_msat; } -class wire_OpeningFeeParams extends ffi.Struct { +final class wire_OpeningFeeParams extends ffi.Struct { @ffi.Uint64() external int min_msat; @@ -5244,7 +5244,7 @@ class wire_OpeningFeeParams extends ffi.Struct { external ffi.Pointer promise; } -class wire_ReceivePaymentRequest extends ffi.Struct { +final class wire_ReceivePaymentRequest extends ffi.Struct { @ffi.Uint64() external int amount_msat; @@ -5261,7 +5261,7 @@ class wire_ReceivePaymentRequest extends ffi.Struct { external ffi.Pointer cltv; } -class wire_LnUrlPayRequestData extends ffi.Struct { +final class wire_LnUrlPayRequestData extends ffi.Struct { external ffi.Pointer callback; @ffi.Uint64() @@ -5280,7 +5280,7 @@ class wire_LnUrlPayRequestData extends ffi.Struct { external ffi.Pointer ln_address; } -class wire_LnUrlPayRequest extends ffi.Struct { +final class wire_LnUrlPayRequest extends ffi.Struct { external wire_LnUrlPayRequestData data; @ffi.Uint64() @@ -5289,7 +5289,7 @@ class wire_LnUrlPayRequest extends ffi.Struct { external ffi.Pointer comment; } -class wire_LnUrlWithdrawRequestData extends ffi.Struct { +final class wire_LnUrlWithdrawRequestData extends ffi.Struct { external ffi.Pointer callback; external ffi.Pointer k1; @@ -5303,7 +5303,7 @@ class wire_LnUrlWithdrawRequestData extends ffi.Struct { external int max_withdrawable; } -class wire_LnUrlWithdrawRequest extends ffi.Struct { +final class wire_LnUrlWithdrawRequest extends ffi.Struct { external wire_LnUrlWithdrawRequestData data; @ffi.Uint64() @@ -5312,7 +5312,7 @@ class wire_LnUrlWithdrawRequest extends ffi.Struct { external ffi.Pointer description; } -class wire_LnUrlAuthRequestData extends ffi.Struct { +final class wire_LnUrlAuthRequestData extends ffi.Struct { external ffi.Pointer k1; external ffi.Pointer action; @@ -5322,7 +5322,7 @@ class wire_LnUrlAuthRequestData extends ffi.Struct { external ffi.Pointer url; } -class wire_SendOnchainRequest extends ffi.Struct { +final class wire_SendOnchainRequest extends ffi.Struct { @ffi.Uint64() external int amount_sat; @@ -5334,32 +5334,32 @@ class wire_SendOnchainRequest extends ffi.Struct { external int sat_per_vbyte; } -class wire_ReceiveOnchainRequest extends ffi.Struct { +final class wire_ReceiveOnchainRequest extends ffi.Struct { external ffi.Pointer opening_fee_params; } -class wire_BuyBitcoinRequest extends ffi.Struct { +final class wire_BuyBitcoinRequest extends ffi.Struct { @ffi.Int32() external int provider; external ffi.Pointer opening_fee_params; } -class wire_SweepRequest extends ffi.Struct { +final class wire_SweepRequest extends ffi.Struct { external ffi.Pointer to_address; @ffi.Uint32() external int fee_rate_sats_per_vbyte; } -class wire_PrepareSweepRequest extends ffi.Struct { +final class wire_PrepareSweepRequest extends ffi.Struct { external ffi.Pointer to_address; @ffi.Uint64() external int sats_per_vbyte; } -class wire_PrepareRefundRequest extends ffi.Struct { +final class wire_PrepareRefundRequest extends ffi.Struct { external ffi.Pointer swap_address; external ffi.Pointer to_address; @@ -5368,7 +5368,7 @@ class wire_PrepareRefundRequest extends ffi.Struct { external int sat_per_vbyte; } -class wire_RefundRequest extends ffi.Struct { +final class wire_RefundRequest extends ffi.Struct { external ffi.Pointer swap_address; external ffi.Pointer to_address; @@ -5377,14 +5377,14 @@ class wire_RefundRequest extends ffi.Struct { external int sat_per_vbyte; } -class wire_OpenChannelFeeRequest extends ffi.Struct { +final class wire_OpenChannelFeeRequest extends ffi.Struct { @ffi.Uint64() external int amount_msat; external ffi.Pointer expiry; } -class wire_ReverseSwapFeesRequest extends ffi.Struct { +final class wire_ReverseSwapFeesRequest extends ffi.Struct { external ffi.Pointer send_amount_sat; } diff --git a/libs/sdk-flutter/lib/bridge_generated.freezed.dart b/libs/sdk-flutter/lib/bridge_generated.freezed.dart index 659acf80a..d4445660c 100644 --- a/libs/sdk-flutter/lib/bridge_generated.freezed.dart +++ b/libs/sdk-flutter/lib/bridge_generated.freezed.dart @@ -109,19 +109,20 @@ class _$BreezEventCopyWithImpl<$Res, $Val extends BreezEvent> implements $BreezE } /// @nodoc -abstract class _$$BreezEvent_NewBlockCopyWith<$Res> { - factory _$$BreezEvent_NewBlockCopyWith( - _$BreezEvent_NewBlock value, $Res Function(_$BreezEvent_NewBlock) then) = - __$$BreezEvent_NewBlockCopyWithImpl<$Res>; +abstract class _$$BreezEvent_NewBlockImplCopyWith<$Res> { + factory _$$BreezEvent_NewBlockImplCopyWith( + _$BreezEvent_NewBlockImpl value, $Res Function(_$BreezEvent_NewBlockImpl) then) = + __$$BreezEvent_NewBlockImplCopyWithImpl<$Res>; @useResult $Res call({int block}); } /// @nodoc -class __$$BreezEvent_NewBlockCopyWithImpl<$Res> extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_NewBlock> - implements _$$BreezEvent_NewBlockCopyWith<$Res> { - __$$BreezEvent_NewBlockCopyWithImpl( - _$BreezEvent_NewBlock _value, $Res Function(_$BreezEvent_NewBlock) _then) +class __$$BreezEvent_NewBlockImplCopyWithImpl<$Res> + extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_NewBlockImpl> + implements _$$BreezEvent_NewBlockImplCopyWith<$Res> { + __$$BreezEvent_NewBlockImplCopyWithImpl( + _$BreezEvent_NewBlockImpl _value, $Res Function(_$BreezEvent_NewBlockImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -129,7 +130,7 @@ class __$$BreezEvent_NewBlockCopyWithImpl<$Res> extends _$BreezEventCopyWithImpl $Res call({ Object? block = null, }) { - return _then(_$BreezEvent_NewBlock( + return _then(_$BreezEvent_NewBlockImpl( block: null == block ? _value.block : block // ignore: cast_nullable_to_non_nullable @@ -140,8 +141,8 @@ class __$$BreezEvent_NewBlockCopyWithImpl<$Res> extends _$BreezEventCopyWithImpl /// @nodoc -class _$BreezEvent_NewBlock implements BreezEvent_NewBlock { - const _$BreezEvent_NewBlock({required this.block}); +class _$BreezEvent_NewBlockImpl implements BreezEvent_NewBlock { + const _$BreezEvent_NewBlockImpl({required this.block}); @override final int block; @@ -155,7 +156,7 @@ class _$BreezEvent_NewBlock implements BreezEvent_NewBlock { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$BreezEvent_NewBlock && + other is _$BreezEvent_NewBlockImpl && (identical(other.block, block) || other.block == block)); } @@ -165,8 +166,8 @@ class _$BreezEvent_NewBlock implements BreezEvent_NewBlock { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$BreezEvent_NewBlockCopyWith<_$BreezEvent_NewBlock> get copyWith => - __$$BreezEvent_NewBlockCopyWithImpl<_$BreezEvent_NewBlock>(this, _$identity); + _$$BreezEvent_NewBlockImplCopyWith<_$BreezEvent_NewBlockImpl> get copyWith => + __$$BreezEvent_NewBlockImplCopyWithImpl<_$BreezEvent_NewBlockImpl>(this, _$identity); @override @optionalTypeArgs @@ -268,28 +269,29 @@ class _$BreezEvent_NewBlock implements BreezEvent_NewBlock { } abstract class BreezEvent_NewBlock implements BreezEvent { - const factory BreezEvent_NewBlock({required final int block}) = _$BreezEvent_NewBlock; + const factory BreezEvent_NewBlock({required final int block}) = _$BreezEvent_NewBlockImpl; int get block; @JsonKey(ignore: true) - _$$BreezEvent_NewBlockCopyWith<_$BreezEvent_NewBlock> get copyWith => throw _privateConstructorUsedError; + _$$BreezEvent_NewBlockImplCopyWith<_$BreezEvent_NewBlockImpl> get copyWith => + throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$BreezEvent_InvoicePaidCopyWith<$Res> { - factory _$$BreezEvent_InvoicePaidCopyWith( - _$BreezEvent_InvoicePaid value, $Res Function(_$BreezEvent_InvoicePaid) then) = - __$$BreezEvent_InvoicePaidCopyWithImpl<$Res>; +abstract class _$$BreezEvent_InvoicePaidImplCopyWith<$Res> { + factory _$$BreezEvent_InvoicePaidImplCopyWith( + _$BreezEvent_InvoicePaidImpl value, $Res Function(_$BreezEvent_InvoicePaidImpl) then) = + __$$BreezEvent_InvoicePaidImplCopyWithImpl<$Res>; @useResult $Res call({InvoicePaidDetails details}); } /// @nodoc -class __$$BreezEvent_InvoicePaidCopyWithImpl<$Res> - extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_InvoicePaid> - implements _$$BreezEvent_InvoicePaidCopyWith<$Res> { - __$$BreezEvent_InvoicePaidCopyWithImpl( - _$BreezEvent_InvoicePaid _value, $Res Function(_$BreezEvent_InvoicePaid) _then) +class __$$BreezEvent_InvoicePaidImplCopyWithImpl<$Res> + extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_InvoicePaidImpl> + implements _$$BreezEvent_InvoicePaidImplCopyWith<$Res> { + __$$BreezEvent_InvoicePaidImplCopyWithImpl( + _$BreezEvent_InvoicePaidImpl _value, $Res Function(_$BreezEvent_InvoicePaidImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -297,7 +299,7 @@ class __$$BreezEvent_InvoicePaidCopyWithImpl<$Res> $Res call({ Object? details = null, }) { - return _then(_$BreezEvent_InvoicePaid( + return _then(_$BreezEvent_InvoicePaidImpl( details: null == details ? _value.details : details // ignore: cast_nullable_to_non_nullable @@ -308,8 +310,8 @@ class __$$BreezEvent_InvoicePaidCopyWithImpl<$Res> /// @nodoc -class _$BreezEvent_InvoicePaid implements BreezEvent_InvoicePaid { - const _$BreezEvent_InvoicePaid({required this.details}); +class _$BreezEvent_InvoicePaidImpl implements BreezEvent_InvoicePaid { + const _$BreezEvent_InvoicePaidImpl({required this.details}); @override final InvoicePaidDetails details; @@ -323,7 +325,7 @@ class _$BreezEvent_InvoicePaid implements BreezEvent_InvoicePaid { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$BreezEvent_InvoicePaid && + other is _$BreezEvent_InvoicePaidImpl && (identical(other.details, details) || other.details == details)); } @@ -333,8 +335,8 @@ class _$BreezEvent_InvoicePaid implements BreezEvent_InvoicePaid { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$BreezEvent_InvoicePaidCopyWith<_$BreezEvent_InvoicePaid> get copyWith => - __$$BreezEvent_InvoicePaidCopyWithImpl<_$BreezEvent_InvoicePaid>(this, _$identity); + _$$BreezEvent_InvoicePaidImplCopyWith<_$BreezEvent_InvoicePaidImpl> get copyWith => + __$$BreezEvent_InvoicePaidImplCopyWithImpl<_$BreezEvent_InvoicePaidImpl>(this, _$identity); @override @optionalTypeArgs @@ -437,31 +439,34 @@ class _$BreezEvent_InvoicePaid implements BreezEvent_InvoicePaid { abstract class BreezEvent_InvoicePaid implements BreezEvent { const factory BreezEvent_InvoicePaid({required final InvoicePaidDetails details}) = - _$BreezEvent_InvoicePaid; + _$BreezEvent_InvoicePaidImpl; InvoicePaidDetails get details; @JsonKey(ignore: true) - _$$BreezEvent_InvoicePaidCopyWith<_$BreezEvent_InvoicePaid> get copyWith => + _$$BreezEvent_InvoicePaidImplCopyWith<_$BreezEvent_InvoicePaidImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$BreezEvent_SyncedCopyWith<$Res> { - factory _$$BreezEvent_SyncedCopyWith(_$BreezEvent_Synced value, $Res Function(_$BreezEvent_Synced) then) = - __$$BreezEvent_SyncedCopyWithImpl<$Res>; +abstract class _$$BreezEvent_SyncedImplCopyWith<$Res> { + factory _$$BreezEvent_SyncedImplCopyWith( + _$BreezEvent_SyncedImpl value, $Res Function(_$BreezEvent_SyncedImpl) then) = + __$$BreezEvent_SyncedImplCopyWithImpl<$Res>; } /// @nodoc -class __$$BreezEvent_SyncedCopyWithImpl<$Res> extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_Synced> - implements _$$BreezEvent_SyncedCopyWith<$Res> { - __$$BreezEvent_SyncedCopyWithImpl(_$BreezEvent_Synced _value, $Res Function(_$BreezEvent_Synced) _then) +class __$$BreezEvent_SyncedImplCopyWithImpl<$Res> + extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_SyncedImpl> + implements _$$BreezEvent_SyncedImplCopyWith<$Res> { + __$$BreezEvent_SyncedImplCopyWithImpl( + _$BreezEvent_SyncedImpl _value, $Res Function(_$BreezEvent_SyncedImpl) _then) : super(_value, _then); } /// @nodoc -class _$BreezEvent_Synced implements BreezEvent_Synced { - const _$BreezEvent_Synced(); +class _$BreezEvent_SyncedImpl implements BreezEvent_Synced { + const _$BreezEvent_SyncedImpl(); @override String toString() { @@ -470,7 +475,7 @@ class _$BreezEvent_Synced implements BreezEvent_Synced { @override bool operator ==(dynamic other) { - return identical(this, other) || (other.runtimeType == runtimeType && other is _$BreezEvent_Synced); + return identical(this, other) || (other.runtimeType == runtimeType && other is _$BreezEvent_SyncedImpl); } @override @@ -576,24 +581,24 @@ class _$BreezEvent_Synced implements BreezEvent_Synced { } abstract class BreezEvent_Synced implements BreezEvent { - const factory BreezEvent_Synced() = _$BreezEvent_Synced; + const factory BreezEvent_Synced() = _$BreezEvent_SyncedImpl; } /// @nodoc -abstract class _$$BreezEvent_PaymentSucceedCopyWith<$Res> { - factory _$$BreezEvent_PaymentSucceedCopyWith( - _$BreezEvent_PaymentSucceed value, $Res Function(_$BreezEvent_PaymentSucceed) then) = - __$$BreezEvent_PaymentSucceedCopyWithImpl<$Res>; +abstract class _$$BreezEvent_PaymentSucceedImplCopyWith<$Res> { + factory _$$BreezEvent_PaymentSucceedImplCopyWith( + _$BreezEvent_PaymentSucceedImpl value, $Res Function(_$BreezEvent_PaymentSucceedImpl) then) = + __$$BreezEvent_PaymentSucceedImplCopyWithImpl<$Res>; @useResult $Res call({Payment details}); } /// @nodoc -class __$$BreezEvent_PaymentSucceedCopyWithImpl<$Res> - extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_PaymentSucceed> - implements _$$BreezEvent_PaymentSucceedCopyWith<$Res> { - __$$BreezEvent_PaymentSucceedCopyWithImpl( - _$BreezEvent_PaymentSucceed _value, $Res Function(_$BreezEvent_PaymentSucceed) _then) +class __$$BreezEvent_PaymentSucceedImplCopyWithImpl<$Res> + extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_PaymentSucceedImpl> + implements _$$BreezEvent_PaymentSucceedImplCopyWith<$Res> { + __$$BreezEvent_PaymentSucceedImplCopyWithImpl( + _$BreezEvent_PaymentSucceedImpl _value, $Res Function(_$BreezEvent_PaymentSucceedImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -601,7 +606,7 @@ class __$$BreezEvent_PaymentSucceedCopyWithImpl<$Res> $Res call({ Object? details = null, }) { - return _then(_$BreezEvent_PaymentSucceed( + return _then(_$BreezEvent_PaymentSucceedImpl( details: null == details ? _value.details : details // ignore: cast_nullable_to_non_nullable @@ -612,8 +617,8 @@ class __$$BreezEvent_PaymentSucceedCopyWithImpl<$Res> /// @nodoc -class _$BreezEvent_PaymentSucceed implements BreezEvent_PaymentSucceed { - const _$BreezEvent_PaymentSucceed({required this.details}); +class _$BreezEvent_PaymentSucceedImpl implements BreezEvent_PaymentSucceed { + const _$BreezEvent_PaymentSucceedImpl({required this.details}); @override final Payment details; @@ -627,7 +632,7 @@ class _$BreezEvent_PaymentSucceed implements BreezEvent_PaymentSucceed { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$BreezEvent_PaymentSucceed && + other is _$BreezEvent_PaymentSucceedImpl && (identical(other.details, details) || other.details == details)); } @@ -637,8 +642,8 @@ class _$BreezEvent_PaymentSucceed implements BreezEvent_PaymentSucceed { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$BreezEvent_PaymentSucceedCopyWith<_$BreezEvent_PaymentSucceed> get copyWith => - __$$BreezEvent_PaymentSucceedCopyWithImpl<_$BreezEvent_PaymentSucceed>(this, _$identity); + _$$BreezEvent_PaymentSucceedImplCopyWith<_$BreezEvent_PaymentSucceedImpl> get copyWith => + __$$BreezEvent_PaymentSucceedImplCopyWithImpl<_$BreezEvent_PaymentSucceedImpl>(this, _$identity); @override @optionalTypeArgs @@ -740,29 +745,29 @@ class _$BreezEvent_PaymentSucceed implements BreezEvent_PaymentSucceed { } abstract class BreezEvent_PaymentSucceed implements BreezEvent { - const factory BreezEvent_PaymentSucceed({required final Payment details}) = _$BreezEvent_PaymentSucceed; + const factory BreezEvent_PaymentSucceed({required final Payment details}) = _$BreezEvent_PaymentSucceedImpl; Payment get details; @JsonKey(ignore: true) - _$$BreezEvent_PaymentSucceedCopyWith<_$BreezEvent_PaymentSucceed> get copyWith => + _$$BreezEvent_PaymentSucceedImplCopyWith<_$BreezEvent_PaymentSucceedImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$BreezEvent_PaymentFailedCopyWith<$Res> { - factory _$$BreezEvent_PaymentFailedCopyWith( - _$BreezEvent_PaymentFailed value, $Res Function(_$BreezEvent_PaymentFailed) then) = - __$$BreezEvent_PaymentFailedCopyWithImpl<$Res>; +abstract class _$$BreezEvent_PaymentFailedImplCopyWith<$Res> { + factory _$$BreezEvent_PaymentFailedImplCopyWith( + _$BreezEvent_PaymentFailedImpl value, $Res Function(_$BreezEvent_PaymentFailedImpl) then) = + __$$BreezEvent_PaymentFailedImplCopyWithImpl<$Res>; @useResult $Res call({PaymentFailedData details}); } /// @nodoc -class __$$BreezEvent_PaymentFailedCopyWithImpl<$Res> - extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_PaymentFailed> - implements _$$BreezEvent_PaymentFailedCopyWith<$Res> { - __$$BreezEvent_PaymentFailedCopyWithImpl( - _$BreezEvent_PaymentFailed _value, $Res Function(_$BreezEvent_PaymentFailed) _then) +class __$$BreezEvent_PaymentFailedImplCopyWithImpl<$Res> + extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_PaymentFailedImpl> + implements _$$BreezEvent_PaymentFailedImplCopyWith<$Res> { + __$$BreezEvent_PaymentFailedImplCopyWithImpl( + _$BreezEvent_PaymentFailedImpl _value, $Res Function(_$BreezEvent_PaymentFailedImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -770,7 +775,7 @@ class __$$BreezEvent_PaymentFailedCopyWithImpl<$Res> $Res call({ Object? details = null, }) { - return _then(_$BreezEvent_PaymentFailed( + return _then(_$BreezEvent_PaymentFailedImpl( details: null == details ? _value.details : details // ignore: cast_nullable_to_non_nullable @@ -781,8 +786,8 @@ class __$$BreezEvent_PaymentFailedCopyWithImpl<$Res> /// @nodoc -class _$BreezEvent_PaymentFailed implements BreezEvent_PaymentFailed { - const _$BreezEvent_PaymentFailed({required this.details}); +class _$BreezEvent_PaymentFailedImpl implements BreezEvent_PaymentFailed { + const _$BreezEvent_PaymentFailedImpl({required this.details}); @override final PaymentFailedData details; @@ -796,7 +801,7 @@ class _$BreezEvent_PaymentFailed implements BreezEvent_PaymentFailed { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$BreezEvent_PaymentFailed && + other is _$BreezEvent_PaymentFailedImpl && (identical(other.details, details) || other.details == details)); } @@ -806,8 +811,8 @@ class _$BreezEvent_PaymentFailed implements BreezEvent_PaymentFailed { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$BreezEvent_PaymentFailedCopyWith<_$BreezEvent_PaymentFailed> get copyWith => - __$$BreezEvent_PaymentFailedCopyWithImpl<_$BreezEvent_PaymentFailed>(this, _$identity); + _$$BreezEvent_PaymentFailedImplCopyWith<_$BreezEvent_PaymentFailedImpl> get copyWith => + __$$BreezEvent_PaymentFailedImplCopyWithImpl<_$BreezEvent_PaymentFailedImpl>(this, _$identity); @override @optionalTypeArgs @@ -910,34 +915,34 @@ class _$BreezEvent_PaymentFailed implements BreezEvent_PaymentFailed { abstract class BreezEvent_PaymentFailed implements BreezEvent { const factory BreezEvent_PaymentFailed({required final PaymentFailedData details}) = - _$BreezEvent_PaymentFailed; + _$BreezEvent_PaymentFailedImpl; PaymentFailedData get details; @JsonKey(ignore: true) - _$$BreezEvent_PaymentFailedCopyWith<_$BreezEvent_PaymentFailed> get copyWith => + _$$BreezEvent_PaymentFailedImplCopyWith<_$BreezEvent_PaymentFailedImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$BreezEvent_BackupStartedCopyWith<$Res> { - factory _$$BreezEvent_BackupStartedCopyWith( - _$BreezEvent_BackupStarted value, $Res Function(_$BreezEvent_BackupStarted) then) = - __$$BreezEvent_BackupStartedCopyWithImpl<$Res>; +abstract class _$$BreezEvent_BackupStartedImplCopyWith<$Res> { + factory _$$BreezEvent_BackupStartedImplCopyWith( + _$BreezEvent_BackupStartedImpl value, $Res Function(_$BreezEvent_BackupStartedImpl) then) = + __$$BreezEvent_BackupStartedImplCopyWithImpl<$Res>; } /// @nodoc -class __$$BreezEvent_BackupStartedCopyWithImpl<$Res> - extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_BackupStarted> - implements _$$BreezEvent_BackupStartedCopyWith<$Res> { - __$$BreezEvent_BackupStartedCopyWithImpl( - _$BreezEvent_BackupStarted _value, $Res Function(_$BreezEvent_BackupStarted) _then) +class __$$BreezEvent_BackupStartedImplCopyWithImpl<$Res> + extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_BackupStartedImpl> + implements _$$BreezEvent_BackupStartedImplCopyWith<$Res> { + __$$BreezEvent_BackupStartedImplCopyWithImpl( + _$BreezEvent_BackupStartedImpl _value, $Res Function(_$BreezEvent_BackupStartedImpl) _then) : super(_value, _then); } /// @nodoc -class _$BreezEvent_BackupStarted implements BreezEvent_BackupStarted { - const _$BreezEvent_BackupStarted(); +class _$BreezEvent_BackupStartedImpl implements BreezEvent_BackupStarted { + const _$BreezEvent_BackupStartedImpl(); @override String toString() { @@ -947,7 +952,7 @@ class _$BreezEvent_BackupStarted implements BreezEvent_BackupStarted { @override bool operator ==(dynamic other) { return identical(this, other) || - (other.runtimeType == runtimeType && other is _$BreezEvent_BackupStarted); + (other.runtimeType == runtimeType && other is _$BreezEvent_BackupStartedImpl); } @override @@ -1053,29 +1058,29 @@ class _$BreezEvent_BackupStarted implements BreezEvent_BackupStarted { } abstract class BreezEvent_BackupStarted implements BreezEvent { - const factory BreezEvent_BackupStarted() = _$BreezEvent_BackupStarted; + const factory BreezEvent_BackupStarted() = _$BreezEvent_BackupStartedImpl; } /// @nodoc -abstract class _$$BreezEvent_BackupSucceededCopyWith<$Res> { - factory _$$BreezEvent_BackupSucceededCopyWith( - _$BreezEvent_BackupSucceeded value, $Res Function(_$BreezEvent_BackupSucceeded) then) = - __$$BreezEvent_BackupSucceededCopyWithImpl<$Res>; +abstract class _$$BreezEvent_BackupSucceededImplCopyWith<$Res> { + factory _$$BreezEvent_BackupSucceededImplCopyWith( + _$BreezEvent_BackupSucceededImpl value, $Res Function(_$BreezEvent_BackupSucceededImpl) then) = + __$$BreezEvent_BackupSucceededImplCopyWithImpl<$Res>; } /// @nodoc -class __$$BreezEvent_BackupSucceededCopyWithImpl<$Res> - extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_BackupSucceeded> - implements _$$BreezEvent_BackupSucceededCopyWith<$Res> { - __$$BreezEvent_BackupSucceededCopyWithImpl( - _$BreezEvent_BackupSucceeded _value, $Res Function(_$BreezEvent_BackupSucceeded) _then) +class __$$BreezEvent_BackupSucceededImplCopyWithImpl<$Res> + extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_BackupSucceededImpl> + implements _$$BreezEvent_BackupSucceededImplCopyWith<$Res> { + __$$BreezEvent_BackupSucceededImplCopyWithImpl( + _$BreezEvent_BackupSucceededImpl _value, $Res Function(_$BreezEvent_BackupSucceededImpl) _then) : super(_value, _then); } /// @nodoc -class _$BreezEvent_BackupSucceeded implements BreezEvent_BackupSucceeded { - const _$BreezEvent_BackupSucceeded(); +class _$BreezEvent_BackupSucceededImpl implements BreezEvent_BackupSucceeded { + const _$BreezEvent_BackupSucceededImpl(); @override String toString() { @@ -1085,7 +1090,7 @@ class _$BreezEvent_BackupSucceeded implements BreezEvent_BackupSucceeded { @override bool operator ==(dynamic other) { return identical(this, other) || - (other.runtimeType == runtimeType && other is _$BreezEvent_BackupSucceeded); + (other.runtimeType == runtimeType && other is _$BreezEvent_BackupSucceededImpl); } @override @@ -1191,24 +1196,24 @@ class _$BreezEvent_BackupSucceeded implements BreezEvent_BackupSucceeded { } abstract class BreezEvent_BackupSucceeded implements BreezEvent { - const factory BreezEvent_BackupSucceeded() = _$BreezEvent_BackupSucceeded; + const factory BreezEvent_BackupSucceeded() = _$BreezEvent_BackupSucceededImpl; } /// @nodoc -abstract class _$$BreezEvent_BackupFailedCopyWith<$Res> { - factory _$$BreezEvent_BackupFailedCopyWith( - _$BreezEvent_BackupFailed value, $Res Function(_$BreezEvent_BackupFailed) then) = - __$$BreezEvent_BackupFailedCopyWithImpl<$Res>; +abstract class _$$BreezEvent_BackupFailedImplCopyWith<$Res> { + factory _$$BreezEvent_BackupFailedImplCopyWith( + _$BreezEvent_BackupFailedImpl value, $Res Function(_$BreezEvent_BackupFailedImpl) then) = + __$$BreezEvent_BackupFailedImplCopyWithImpl<$Res>; @useResult $Res call({BackupFailedData details}); } /// @nodoc -class __$$BreezEvent_BackupFailedCopyWithImpl<$Res> - extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_BackupFailed> - implements _$$BreezEvent_BackupFailedCopyWith<$Res> { - __$$BreezEvent_BackupFailedCopyWithImpl( - _$BreezEvent_BackupFailed _value, $Res Function(_$BreezEvent_BackupFailed) _then) +class __$$BreezEvent_BackupFailedImplCopyWithImpl<$Res> + extends _$BreezEventCopyWithImpl<$Res, _$BreezEvent_BackupFailedImpl> + implements _$$BreezEvent_BackupFailedImplCopyWith<$Res> { + __$$BreezEvent_BackupFailedImplCopyWithImpl( + _$BreezEvent_BackupFailedImpl _value, $Res Function(_$BreezEvent_BackupFailedImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1216,7 +1221,7 @@ class __$$BreezEvent_BackupFailedCopyWithImpl<$Res> $Res call({ Object? details = null, }) { - return _then(_$BreezEvent_BackupFailed( + return _then(_$BreezEvent_BackupFailedImpl( details: null == details ? _value.details : details // ignore: cast_nullable_to_non_nullable @@ -1227,8 +1232,8 @@ class __$$BreezEvent_BackupFailedCopyWithImpl<$Res> /// @nodoc -class _$BreezEvent_BackupFailed implements BreezEvent_BackupFailed { - const _$BreezEvent_BackupFailed({required this.details}); +class _$BreezEvent_BackupFailedImpl implements BreezEvent_BackupFailed { + const _$BreezEvent_BackupFailedImpl({required this.details}); @override final BackupFailedData details; @@ -1242,7 +1247,7 @@ class _$BreezEvent_BackupFailed implements BreezEvent_BackupFailed { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$BreezEvent_BackupFailed && + other is _$BreezEvent_BackupFailedImpl && (identical(other.details, details) || other.details == details)); } @@ -1252,8 +1257,8 @@ class _$BreezEvent_BackupFailed implements BreezEvent_BackupFailed { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$BreezEvent_BackupFailedCopyWith<_$BreezEvent_BackupFailed> get copyWith => - __$$BreezEvent_BackupFailedCopyWithImpl<_$BreezEvent_BackupFailed>(this, _$identity); + _$$BreezEvent_BackupFailedImplCopyWith<_$BreezEvent_BackupFailedImpl> get copyWith => + __$$BreezEvent_BackupFailedImplCopyWithImpl<_$BreezEvent_BackupFailedImpl>(this, _$identity); @override @optionalTypeArgs @@ -1356,11 +1361,11 @@ class _$BreezEvent_BackupFailed implements BreezEvent_BackupFailed { abstract class BreezEvent_BackupFailed implements BreezEvent { const factory BreezEvent_BackupFailed({required final BackupFailedData details}) = - _$BreezEvent_BackupFailed; + _$BreezEvent_BackupFailedImpl; BackupFailedData get details; @JsonKey(ignore: true) - _$$BreezEvent_BackupFailedCopyWith<_$BreezEvent_BackupFailed> get copyWith => + _$$BreezEvent_BackupFailedImplCopyWith<_$BreezEvent_BackupFailedImpl> get copyWith => throw _privateConstructorUsedError; } @@ -1459,20 +1464,20 @@ class _$InputTypeCopyWithImpl<$Res, $Val extends InputType> implements $InputTyp } /// @nodoc -abstract class _$$InputType_BitcoinAddressCopyWith<$Res> { - factory _$$InputType_BitcoinAddressCopyWith( - _$InputType_BitcoinAddress value, $Res Function(_$InputType_BitcoinAddress) then) = - __$$InputType_BitcoinAddressCopyWithImpl<$Res>; +abstract class _$$InputType_BitcoinAddressImplCopyWith<$Res> { + factory _$$InputType_BitcoinAddressImplCopyWith( + _$InputType_BitcoinAddressImpl value, $Res Function(_$InputType_BitcoinAddressImpl) then) = + __$$InputType_BitcoinAddressImplCopyWithImpl<$Res>; @useResult $Res call({BitcoinAddressData address}); } /// @nodoc -class __$$InputType_BitcoinAddressCopyWithImpl<$Res> - extends _$InputTypeCopyWithImpl<$Res, _$InputType_BitcoinAddress> - implements _$$InputType_BitcoinAddressCopyWith<$Res> { - __$$InputType_BitcoinAddressCopyWithImpl( - _$InputType_BitcoinAddress _value, $Res Function(_$InputType_BitcoinAddress) _then) +class __$$InputType_BitcoinAddressImplCopyWithImpl<$Res> + extends _$InputTypeCopyWithImpl<$Res, _$InputType_BitcoinAddressImpl> + implements _$$InputType_BitcoinAddressImplCopyWith<$Res> { + __$$InputType_BitcoinAddressImplCopyWithImpl( + _$InputType_BitcoinAddressImpl _value, $Res Function(_$InputType_BitcoinAddressImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1480,7 +1485,7 @@ class __$$InputType_BitcoinAddressCopyWithImpl<$Res> $Res call({ Object? address = null, }) { - return _then(_$InputType_BitcoinAddress( + return _then(_$InputType_BitcoinAddressImpl( address: null == address ? _value.address : address // ignore: cast_nullable_to_non_nullable @@ -1491,8 +1496,8 @@ class __$$InputType_BitcoinAddressCopyWithImpl<$Res> /// @nodoc -class _$InputType_BitcoinAddress implements InputType_BitcoinAddress { - const _$InputType_BitcoinAddress({required this.address}); +class _$InputType_BitcoinAddressImpl implements InputType_BitcoinAddress { + const _$InputType_BitcoinAddressImpl({required this.address}); @override final BitcoinAddressData address; @@ -1506,7 +1511,7 @@ class _$InputType_BitcoinAddress implements InputType_BitcoinAddress { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$InputType_BitcoinAddress && + other is _$InputType_BitcoinAddressImpl && (identical(other.address, address) || other.address == address)); } @@ -1516,8 +1521,8 @@ class _$InputType_BitcoinAddress implements InputType_BitcoinAddress { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$InputType_BitcoinAddressCopyWith<_$InputType_BitcoinAddress> get copyWith => - __$$InputType_BitcoinAddressCopyWithImpl<_$InputType_BitcoinAddress>(this, _$identity); + _$$InputType_BitcoinAddressImplCopyWith<_$InputType_BitcoinAddressImpl> get copyWith => + __$$InputType_BitcoinAddressImplCopyWithImpl<_$InputType_BitcoinAddressImpl>(this, _$identity); @override @optionalTypeArgs @@ -1620,26 +1625,28 @@ class _$InputType_BitcoinAddress implements InputType_BitcoinAddress { abstract class InputType_BitcoinAddress implements InputType { const factory InputType_BitcoinAddress({required final BitcoinAddressData address}) = - _$InputType_BitcoinAddress; + _$InputType_BitcoinAddressImpl; BitcoinAddressData get address; @JsonKey(ignore: true) - _$$InputType_BitcoinAddressCopyWith<_$InputType_BitcoinAddress> get copyWith => + _$$InputType_BitcoinAddressImplCopyWith<_$InputType_BitcoinAddressImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$InputType_Bolt11CopyWith<$Res> { - factory _$$InputType_Bolt11CopyWith(_$InputType_Bolt11 value, $Res Function(_$InputType_Bolt11) then) = - __$$InputType_Bolt11CopyWithImpl<$Res>; +abstract class _$$InputType_Bolt11ImplCopyWith<$Res> { + factory _$$InputType_Bolt11ImplCopyWith( + _$InputType_Bolt11Impl value, $Res Function(_$InputType_Bolt11Impl) then) = + __$$InputType_Bolt11ImplCopyWithImpl<$Res>; @useResult $Res call({LNInvoice invoice}); } /// @nodoc -class __$$InputType_Bolt11CopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$Res, _$InputType_Bolt11> - implements _$$InputType_Bolt11CopyWith<$Res> { - __$$InputType_Bolt11CopyWithImpl(_$InputType_Bolt11 _value, $Res Function(_$InputType_Bolt11) _then) +class __$$InputType_Bolt11ImplCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$Res, _$InputType_Bolt11Impl> + implements _$$InputType_Bolt11ImplCopyWith<$Res> { + __$$InputType_Bolt11ImplCopyWithImpl( + _$InputType_Bolt11Impl _value, $Res Function(_$InputType_Bolt11Impl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1647,7 +1654,7 @@ class __$$InputType_Bolt11CopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$Re $Res call({ Object? invoice = null, }) { - return _then(_$InputType_Bolt11( + return _then(_$InputType_Bolt11Impl( invoice: null == invoice ? _value.invoice : invoice // ignore: cast_nullable_to_non_nullable @@ -1658,8 +1665,8 @@ class __$$InputType_Bolt11CopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$Re /// @nodoc -class _$InputType_Bolt11 implements InputType_Bolt11 { - const _$InputType_Bolt11({required this.invoice}); +class _$InputType_Bolt11Impl implements InputType_Bolt11 { + const _$InputType_Bolt11Impl({required this.invoice}); @override final LNInvoice invoice; @@ -1673,7 +1680,7 @@ class _$InputType_Bolt11 implements InputType_Bolt11 { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$InputType_Bolt11 && + other is _$InputType_Bolt11Impl && (identical(other.invoice, invoice) || other.invoice == invoice)); } @@ -1683,8 +1690,8 @@ class _$InputType_Bolt11 implements InputType_Bolt11 { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$InputType_Bolt11CopyWith<_$InputType_Bolt11> get copyWith => - __$$InputType_Bolt11CopyWithImpl<_$InputType_Bolt11>(this, _$identity); + _$$InputType_Bolt11ImplCopyWith<_$InputType_Bolt11Impl> get copyWith => + __$$InputType_Bolt11ImplCopyWithImpl<_$InputType_Bolt11Impl>(this, _$identity); @override @optionalTypeArgs @@ -1786,25 +1793,27 @@ class _$InputType_Bolt11 implements InputType_Bolt11 { } abstract class InputType_Bolt11 implements InputType { - const factory InputType_Bolt11({required final LNInvoice invoice}) = _$InputType_Bolt11; + const factory InputType_Bolt11({required final LNInvoice invoice}) = _$InputType_Bolt11Impl; LNInvoice get invoice; @JsonKey(ignore: true) - _$$InputType_Bolt11CopyWith<_$InputType_Bolt11> get copyWith => throw _privateConstructorUsedError; + _$$InputType_Bolt11ImplCopyWith<_$InputType_Bolt11Impl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$InputType_NodeIdCopyWith<$Res> { - factory _$$InputType_NodeIdCopyWith(_$InputType_NodeId value, $Res Function(_$InputType_NodeId) then) = - __$$InputType_NodeIdCopyWithImpl<$Res>; +abstract class _$$InputType_NodeIdImplCopyWith<$Res> { + factory _$$InputType_NodeIdImplCopyWith( + _$InputType_NodeIdImpl value, $Res Function(_$InputType_NodeIdImpl) then) = + __$$InputType_NodeIdImplCopyWithImpl<$Res>; @useResult $Res call({String nodeId}); } /// @nodoc -class __$$InputType_NodeIdCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$Res, _$InputType_NodeId> - implements _$$InputType_NodeIdCopyWith<$Res> { - __$$InputType_NodeIdCopyWithImpl(_$InputType_NodeId _value, $Res Function(_$InputType_NodeId) _then) +class __$$InputType_NodeIdImplCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$Res, _$InputType_NodeIdImpl> + implements _$$InputType_NodeIdImplCopyWith<$Res> { + __$$InputType_NodeIdImplCopyWithImpl( + _$InputType_NodeIdImpl _value, $Res Function(_$InputType_NodeIdImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1812,7 +1821,7 @@ class __$$InputType_NodeIdCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$Re $Res call({ Object? nodeId = null, }) { - return _then(_$InputType_NodeId( + return _then(_$InputType_NodeIdImpl( nodeId: null == nodeId ? _value.nodeId : nodeId // ignore: cast_nullable_to_non_nullable @@ -1823,8 +1832,8 @@ class __$$InputType_NodeIdCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$Re /// @nodoc -class _$InputType_NodeId implements InputType_NodeId { - const _$InputType_NodeId({required this.nodeId}); +class _$InputType_NodeIdImpl implements InputType_NodeId { + const _$InputType_NodeIdImpl({required this.nodeId}); @override final String nodeId; @@ -1838,7 +1847,7 @@ class _$InputType_NodeId implements InputType_NodeId { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$InputType_NodeId && + other is _$InputType_NodeIdImpl && (identical(other.nodeId, nodeId) || other.nodeId == nodeId)); } @@ -1848,8 +1857,8 @@ class _$InputType_NodeId implements InputType_NodeId { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$InputType_NodeIdCopyWith<_$InputType_NodeId> get copyWith => - __$$InputType_NodeIdCopyWithImpl<_$InputType_NodeId>(this, _$identity); + _$$InputType_NodeIdImplCopyWith<_$InputType_NodeIdImpl> get copyWith => + __$$InputType_NodeIdImplCopyWithImpl<_$InputType_NodeIdImpl>(this, _$identity); @override @optionalTypeArgs @@ -1951,25 +1960,25 @@ class _$InputType_NodeId implements InputType_NodeId { } abstract class InputType_NodeId implements InputType { - const factory InputType_NodeId({required final String nodeId}) = _$InputType_NodeId; + const factory InputType_NodeId({required final String nodeId}) = _$InputType_NodeIdImpl; String get nodeId; @JsonKey(ignore: true) - _$$InputType_NodeIdCopyWith<_$InputType_NodeId> get copyWith => throw _privateConstructorUsedError; + _$$InputType_NodeIdImplCopyWith<_$InputType_NodeIdImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$InputType_UrlCopyWith<$Res> { - factory _$$InputType_UrlCopyWith(_$InputType_Url value, $Res Function(_$InputType_Url) then) = - __$$InputType_UrlCopyWithImpl<$Res>; +abstract class _$$InputType_UrlImplCopyWith<$Res> { + factory _$$InputType_UrlImplCopyWith(_$InputType_UrlImpl value, $Res Function(_$InputType_UrlImpl) then) = + __$$InputType_UrlImplCopyWithImpl<$Res>; @useResult $Res call({String url}); } /// @nodoc -class __$$InputType_UrlCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$Res, _$InputType_Url> - implements _$$InputType_UrlCopyWith<$Res> { - __$$InputType_UrlCopyWithImpl(_$InputType_Url _value, $Res Function(_$InputType_Url) _then) +class __$$InputType_UrlImplCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$Res, _$InputType_UrlImpl> + implements _$$InputType_UrlImplCopyWith<$Res> { + __$$InputType_UrlImplCopyWithImpl(_$InputType_UrlImpl _value, $Res Function(_$InputType_UrlImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -1977,7 +1986,7 @@ class __$$InputType_UrlCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$Res, $Res call({ Object? url = null, }) { - return _then(_$InputType_Url( + return _then(_$InputType_UrlImpl( url: null == url ? _value.url : url // ignore: cast_nullable_to_non_nullable @@ -1988,8 +1997,8 @@ class __$$InputType_UrlCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$Res, /// @nodoc -class _$InputType_Url implements InputType_Url { - const _$InputType_Url({required this.url}); +class _$InputType_UrlImpl implements InputType_Url { + const _$InputType_UrlImpl({required this.url}); @override final String url; @@ -2003,7 +2012,7 @@ class _$InputType_Url implements InputType_Url { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$InputType_Url && + other is _$InputType_UrlImpl && (identical(other.url, url) || other.url == url)); } @@ -2013,8 +2022,8 @@ class _$InputType_Url implements InputType_Url { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$InputType_UrlCopyWith<_$InputType_Url> get copyWith => - __$$InputType_UrlCopyWithImpl<_$InputType_Url>(this, _$identity); + _$$InputType_UrlImplCopyWith<_$InputType_UrlImpl> get copyWith => + __$$InputType_UrlImplCopyWithImpl<_$InputType_UrlImpl>(this, _$identity); @override @optionalTypeArgs @@ -2116,26 +2125,28 @@ class _$InputType_Url implements InputType_Url { } abstract class InputType_Url implements InputType { - const factory InputType_Url({required final String url}) = _$InputType_Url; + const factory InputType_Url({required final String url}) = _$InputType_UrlImpl; String get url; @JsonKey(ignore: true) - _$$InputType_UrlCopyWith<_$InputType_Url> get copyWith => throw _privateConstructorUsedError; + _$$InputType_UrlImplCopyWith<_$InputType_UrlImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$InputType_LnUrlPayCopyWith<$Res> { - factory _$$InputType_LnUrlPayCopyWith( - _$InputType_LnUrlPay value, $Res Function(_$InputType_LnUrlPay) then) = - __$$InputType_LnUrlPayCopyWithImpl<$Res>; +abstract class _$$InputType_LnUrlPayImplCopyWith<$Res> { + factory _$$InputType_LnUrlPayImplCopyWith( + _$InputType_LnUrlPayImpl value, $Res Function(_$InputType_LnUrlPayImpl) then) = + __$$InputType_LnUrlPayImplCopyWithImpl<$Res>; @useResult $Res call({LnUrlPayRequestData data}); } /// @nodoc -class __$$InputType_LnUrlPayCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$Res, _$InputType_LnUrlPay> - implements _$$InputType_LnUrlPayCopyWith<$Res> { - __$$InputType_LnUrlPayCopyWithImpl(_$InputType_LnUrlPay _value, $Res Function(_$InputType_LnUrlPay) _then) +class __$$InputType_LnUrlPayImplCopyWithImpl<$Res> + extends _$InputTypeCopyWithImpl<$Res, _$InputType_LnUrlPayImpl> + implements _$$InputType_LnUrlPayImplCopyWith<$Res> { + __$$InputType_LnUrlPayImplCopyWithImpl( + _$InputType_LnUrlPayImpl _value, $Res Function(_$InputType_LnUrlPayImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -2143,7 +2154,7 @@ class __$$InputType_LnUrlPayCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$ $Res call({ Object? data = null, }) { - return _then(_$InputType_LnUrlPay( + return _then(_$InputType_LnUrlPayImpl( data: null == data ? _value.data : data // ignore: cast_nullable_to_non_nullable @@ -2154,8 +2165,8 @@ class __$$InputType_LnUrlPayCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$ /// @nodoc -class _$InputType_LnUrlPay implements InputType_LnUrlPay { - const _$InputType_LnUrlPay({required this.data}); +class _$InputType_LnUrlPayImpl implements InputType_LnUrlPay { + const _$InputType_LnUrlPayImpl({required this.data}); @override final LnUrlPayRequestData data; @@ -2169,7 +2180,7 @@ class _$InputType_LnUrlPay implements InputType_LnUrlPay { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$InputType_LnUrlPay && + other is _$InputType_LnUrlPayImpl && (identical(other.data, data) || other.data == data)); } @@ -2179,8 +2190,8 @@ class _$InputType_LnUrlPay implements InputType_LnUrlPay { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$InputType_LnUrlPayCopyWith<_$InputType_LnUrlPay> get copyWith => - __$$InputType_LnUrlPayCopyWithImpl<_$InputType_LnUrlPay>(this, _$identity); + _$$InputType_LnUrlPayImplCopyWith<_$InputType_LnUrlPayImpl> get copyWith => + __$$InputType_LnUrlPayImplCopyWithImpl<_$InputType_LnUrlPayImpl>(this, _$identity); @override @optionalTypeArgs @@ -2282,28 +2293,29 @@ class _$InputType_LnUrlPay implements InputType_LnUrlPay { } abstract class InputType_LnUrlPay implements InputType { - const factory InputType_LnUrlPay({required final LnUrlPayRequestData data}) = _$InputType_LnUrlPay; + const factory InputType_LnUrlPay({required final LnUrlPayRequestData data}) = _$InputType_LnUrlPayImpl; LnUrlPayRequestData get data; @JsonKey(ignore: true) - _$$InputType_LnUrlPayCopyWith<_$InputType_LnUrlPay> get copyWith => throw _privateConstructorUsedError; + _$$InputType_LnUrlPayImplCopyWith<_$InputType_LnUrlPayImpl> get copyWith => + throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$InputType_LnUrlWithdrawCopyWith<$Res> { - factory _$$InputType_LnUrlWithdrawCopyWith( - _$InputType_LnUrlWithdraw value, $Res Function(_$InputType_LnUrlWithdraw) then) = - __$$InputType_LnUrlWithdrawCopyWithImpl<$Res>; +abstract class _$$InputType_LnUrlWithdrawImplCopyWith<$Res> { + factory _$$InputType_LnUrlWithdrawImplCopyWith( + _$InputType_LnUrlWithdrawImpl value, $Res Function(_$InputType_LnUrlWithdrawImpl) then) = + __$$InputType_LnUrlWithdrawImplCopyWithImpl<$Res>; @useResult $Res call({LnUrlWithdrawRequestData data}); } /// @nodoc -class __$$InputType_LnUrlWithdrawCopyWithImpl<$Res> - extends _$InputTypeCopyWithImpl<$Res, _$InputType_LnUrlWithdraw> - implements _$$InputType_LnUrlWithdrawCopyWith<$Res> { - __$$InputType_LnUrlWithdrawCopyWithImpl( - _$InputType_LnUrlWithdraw _value, $Res Function(_$InputType_LnUrlWithdraw) _then) +class __$$InputType_LnUrlWithdrawImplCopyWithImpl<$Res> + extends _$InputTypeCopyWithImpl<$Res, _$InputType_LnUrlWithdrawImpl> + implements _$$InputType_LnUrlWithdrawImplCopyWith<$Res> { + __$$InputType_LnUrlWithdrawImplCopyWithImpl( + _$InputType_LnUrlWithdrawImpl _value, $Res Function(_$InputType_LnUrlWithdrawImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -2311,7 +2323,7 @@ class __$$InputType_LnUrlWithdrawCopyWithImpl<$Res> $Res call({ Object? data = null, }) { - return _then(_$InputType_LnUrlWithdraw( + return _then(_$InputType_LnUrlWithdrawImpl( data: null == data ? _value.data : data // ignore: cast_nullable_to_non_nullable @@ -2322,8 +2334,8 @@ class __$$InputType_LnUrlWithdrawCopyWithImpl<$Res> /// @nodoc -class _$InputType_LnUrlWithdraw implements InputType_LnUrlWithdraw { - const _$InputType_LnUrlWithdraw({required this.data}); +class _$InputType_LnUrlWithdrawImpl implements InputType_LnUrlWithdraw { + const _$InputType_LnUrlWithdrawImpl({required this.data}); @override final LnUrlWithdrawRequestData data; @@ -2337,7 +2349,7 @@ class _$InputType_LnUrlWithdraw implements InputType_LnUrlWithdraw { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$InputType_LnUrlWithdraw && + other is _$InputType_LnUrlWithdrawImpl && (identical(other.data, data) || other.data == data)); } @@ -2347,8 +2359,8 @@ class _$InputType_LnUrlWithdraw implements InputType_LnUrlWithdraw { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$InputType_LnUrlWithdrawCopyWith<_$InputType_LnUrlWithdraw> get copyWith => - __$$InputType_LnUrlWithdrawCopyWithImpl<_$InputType_LnUrlWithdraw>(this, _$identity); + _$$InputType_LnUrlWithdrawImplCopyWith<_$InputType_LnUrlWithdrawImpl> get copyWith => + __$$InputType_LnUrlWithdrawImplCopyWithImpl<_$InputType_LnUrlWithdrawImpl>(this, _$identity); @override @optionalTypeArgs @@ -2451,28 +2463,29 @@ class _$InputType_LnUrlWithdraw implements InputType_LnUrlWithdraw { abstract class InputType_LnUrlWithdraw implements InputType { const factory InputType_LnUrlWithdraw({required final LnUrlWithdrawRequestData data}) = - _$InputType_LnUrlWithdraw; + _$InputType_LnUrlWithdrawImpl; LnUrlWithdrawRequestData get data; @JsonKey(ignore: true) - _$$InputType_LnUrlWithdrawCopyWith<_$InputType_LnUrlWithdraw> get copyWith => + _$$InputType_LnUrlWithdrawImplCopyWith<_$InputType_LnUrlWithdrawImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$InputType_LnUrlAuthCopyWith<$Res> { - factory _$$InputType_LnUrlAuthCopyWith( - _$InputType_LnUrlAuth value, $Res Function(_$InputType_LnUrlAuth) then) = - __$$InputType_LnUrlAuthCopyWithImpl<$Res>; +abstract class _$$InputType_LnUrlAuthImplCopyWith<$Res> { + factory _$$InputType_LnUrlAuthImplCopyWith( + _$InputType_LnUrlAuthImpl value, $Res Function(_$InputType_LnUrlAuthImpl) then) = + __$$InputType_LnUrlAuthImplCopyWithImpl<$Res>; @useResult $Res call({LnUrlAuthRequestData data}); } /// @nodoc -class __$$InputType_LnUrlAuthCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$Res, _$InputType_LnUrlAuth> - implements _$$InputType_LnUrlAuthCopyWith<$Res> { - __$$InputType_LnUrlAuthCopyWithImpl( - _$InputType_LnUrlAuth _value, $Res Function(_$InputType_LnUrlAuth) _then) +class __$$InputType_LnUrlAuthImplCopyWithImpl<$Res> + extends _$InputTypeCopyWithImpl<$Res, _$InputType_LnUrlAuthImpl> + implements _$$InputType_LnUrlAuthImplCopyWith<$Res> { + __$$InputType_LnUrlAuthImplCopyWithImpl( + _$InputType_LnUrlAuthImpl _value, $Res Function(_$InputType_LnUrlAuthImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -2480,7 +2493,7 @@ class __$$InputType_LnUrlAuthCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl< $Res call({ Object? data = null, }) { - return _then(_$InputType_LnUrlAuth( + return _then(_$InputType_LnUrlAuthImpl( data: null == data ? _value.data : data // ignore: cast_nullable_to_non_nullable @@ -2491,8 +2504,8 @@ class __$$InputType_LnUrlAuthCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl< /// @nodoc -class _$InputType_LnUrlAuth implements InputType_LnUrlAuth { - const _$InputType_LnUrlAuth({required this.data}); +class _$InputType_LnUrlAuthImpl implements InputType_LnUrlAuth { + const _$InputType_LnUrlAuthImpl({required this.data}); @override final LnUrlAuthRequestData data; @@ -2506,7 +2519,7 @@ class _$InputType_LnUrlAuth implements InputType_LnUrlAuth { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$InputType_LnUrlAuth && + other is _$InputType_LnUrlAuthImpl && (identical(other.data, data) || other.data == data)); } @@ -2516,8 +2529,8 @@ class _$InputType_LnUrlAuth implements InputType_LnUrlAuth { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$InputType_LnUrlAuthCopyWith<_$InputType_LnUrlAuth> get copyWith => - __$$InputType_LnUrlAuthCopyWithImpl<_$InputType_LnUrlAuth>(this, _$identity); + _$$InputType_LnUrlAuthImplCopyWith<_$InputType_LnUrlAuthImpl> get copyWith => + __$$InputType_LnUrlAuthImplCopyWithImpl<_$InputType_LnUrlAuthImpl>(this, _$identity); @override @optionalTypeArgs @@ -2619,27 +2632,29 @@ class _$InputType_LnUrlAuth implements InputType_LnUrlAuth { } abstract class InputType_LnUrlAuth implements InputType { - const factory InputType_LnUrlAuth({required final LnUrlAuthRequestData data}) = _$InputType_LnUrlAuth; + const factory InputType_LnUrlAuth({required final LnUrlAuthRequestData data}) = _$InputType_LnUrlAuthImpl; LnUrlAuthRequestData get data; @JsonKey(ignore: true) - _$$InputType_LnUrlAuthCopyWith<_$InputType_LnUrlAuth> get copyWith => throw _privateConstructorUsedError; + _$$InputType_LnUrlAuthImplCopyWith<_$InputType_LnUrlAuthImpl> get copyWith => + throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$InputType_LnUrlErrorCopyWith<$Res> { - factory _$$InputType_LnUrlErrorCopyWith( - _$InputType_LnUrlError value, $Res Function(_$InputType_LnUrlError) then) = - __$$InputType_LnUrlErrorCopyWithImpl<$Res>; +abstract class _$$InputType_LnUrlErrorImplCopyWith<$Res> { + factory _$$InputType_LnUrlErrorImplCopyWith( + _$InputType_LnUrlErrorImpl value, $Res Function(_$InputType_LnUrlErrorImpl) then) = + __$$InputType_LnUrlErrorImplCopyWithImpl<$Res>; @useResult $Res call({LnUrlErrorData data}); } /// @nodoc -class __$$InputType_LnUrlErrorCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl<$Res, _$InputType_LnUrlError> - implements _$$InputType_LnUrlErrorCopyWith<$Res> { - __$$InputType_LnUrlErrorCopyWithImpl( - _$InputType_LnUrlError _value, $Res Function(_$InputType_LnUrlError) _then) +class __$$InputType_LnUrlErrorImplCopyWithImpl<$Res> + extends _$InputTypeCopyWithImpl<$Res, _$InputType_LnUrlErrorImpl> + implements _$$InputType_LnUrlErrorImplCopyWith<$Res> { + __$$InputType_LnUrlErrorImplCopyWithImpl( + _$InputType_LnUrlErrorImpl _value, $Res Function(_$InputType_LnUrlErrorImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -2647,7 +2662,7 @@ class __$$InputType_LnUrlErrorCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl $Res call({ Object? data = null, }) { - return _then(_$InputType_LnUrlError( + return _then(_$InputType_LnUrlErrorImpl( data: null == data ? _value.data : data // ignore: cast_nullable_to_non_nullable @@ -2658,8 +2673,8 @@ class __$$InputType_LnUrlErrorCopyWithImpl<$Res> extends _$InputTypeCopyWithImpl /// @nodoc -class _$InputType_LnUrlError implements InputType_LnUrlError { - const _$InputType_LnUrlError({required this.data}); +class _$InputType_LnUrlErrorImpl implements InputType_LnUrlError { + const _$InputType_LnUrlErrorImpl({required this.data}); @override final LnUrlErrorData data; @@ -2673,7 +2688,7 @@ class _$InputType_LnUrlError implements InputType_LnUrlError { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$InputType_LnUrlError && + other is _$InputType_LnUrlErrorImpl && (identical(other.data, data) || other.data == data)); } @@ -2683,8 +2698,8 @@ class _$InputType_LnUrlError implements InputType_LnUrlError { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$InputType_LnUrlErrorCopyWith<_$InputType_LnUrlError> get copyWith => - __$$InputType_LnUrlErrorCopyWithImpl<_$InputType_LnUrlError>(this, _$identity); + _$$InputType_LnUrlErrorImplCopyWith<_$InputType_LnUrlErrorImpl> get copyWith => + __$$InputType_LnUrlErrorImplCopyWithImpl<_$InputType_LnUrlErrorImpl>(this, _$identity); @override @optionalTypeArgs @@ -2786,11 +2801,12 @@ class _$InputType_LnUrlError implements InputType_LnUrlError { } abstract class InputType_LnUrlError implements InputType { - const factory InputType_LnUrlError({required final LnUrlErrorData data}) = _$InputType_LnUrlError; + const factory InputType_LnUrlError({required final LnUrlErrorData data}) = _$InputType_LnUrlErrorImpl; LnUrlErrorData get data; @JsonKey(ignore: true) - _$$InputType_LnUrlErrorCopyWith<_$InputType_LnUrlError> get copyWith => throw _privateConstructorUsedError; + _$$InputType_LnUrlErrorImplCopyWith<_$InputType_LnUrlErrorImpl> get copyWith => + throw _privateConstructorUsedError; } /// @nodoc @@ -2853,25 +2869,25 @@ class _$LnUrlCallbackStatusCopyWithImpl<$Res, $Val extends LnUrlCallbackStatus> } /// @nodoc -abstract class _$$LnUrlCallbackStatus_OkCopyWith<$Res> { - factory _$$LnUrlCallbackStatus_OkCopyWith( - _$LnUrlCallbackStatus_Ok value, $Res Function(_$LnUrlCallbackStatus_Ok) then) = - __$$LnUrlCallbackStatus_OkCopyWithImpl<$Res>; +abstract class _$$LnUrlCallbackStatus_OkImplCopyWith<$Res> { + factory _$$LnUrlCallbackStatus_OkImplCopyWith( + _$LnUrlCallbackStatus_OkImpl value, $Res Function(_$LnUrlCallbackStatus_OkImpl) then) = + __$$LnUrlCallbackStatus_OkImplCopyWithImpl<$Res>; } /// @nodoc -class __$$LnUrlCallbackStatus_OkCopyWithImpl<$Res> - extends _$LnUrlCallbackStatusCopyWithImpl<$Res, _$LnUrlCallbackStatus_Ok> - implements _$$LnUrlCallbackStatus_OkCopyWith<$Res> { - __$$LnUrlCallbackStatus_OkCopyWithImpl( - _$LnUrlCallbackStatus_Ok _value, $Res Function(_$LnUrlCallbackStatus_Ok) _then) +class __$$LnUrlCallbackStatus_OkImplCopyWithImpl<$Res> + extends _$LnUrlCallbackStatusCopyWithImpl<$Res, _$LnUrlCallbackStatus_OkImpl> + implements _$$LnUrlCallbackStatus_OkImplCopyWith<$Res> { + __$$LnUrlCallbackStatus_OkImplCopyWithImpl( + _$LnUrlCallbackStatus_OkImpl _value, $Res Function(_$LnUrlCallbackStatus_OkImpl) _then) : super(_value, _then); } /// @nodoc -class _$LnUrlCallbackStatus_Ok implements LnUrlCallbackStatus_Ok { - const _$LnUrlCallbackStatus_Ok(); +class _$LnUrlCallbackStatus_OkImpl implements LnUrlCallbackStatus_Ok { + const _$LnUrlCallbackStatus_OkImpl(); @override String toString() { @@ -2880,7 +2896,8 @@ class _$LnUrlCallbackStatus_Ok implements LnUrlCallbackStatus_Ok { @override bool operator ==(dynamic other) { - return identical(this, other) || (other.runtimeType == runtimeType && other is _$LnUrlCallbackStatus_Ok); + return identical(this, other) || + (other.runtimeType == runtimeType && other is _$LnUrlCallbackStatus_OkImpl); } @override @@ -2950,24 +2967,24 @@ class _$LnUrlCallbackStatus_Ok implements LnUrlCallbackStatus_Ok { } abstract class LnUrlCallbackStatus_Ok implements LnUrlCallbackStatus { - const factory LnUrlCallbackStatus_Ok() = _$LnUrlCallbackStatus_Ok; + const factory LnUrlCallbackStatus_Ok() = _$LnUrlCallbackStatus_OkImpl; } /// @nodoc -abstract class _$$LnUrlCallbackStatus_ErrorStatusCopyWith<$Res> { - factory _$$LnUrlCallbackStatus_ErrorStatusCopyWith( - _$LnUrlCallbackStatus_ErrorStatus value, $Res Function(_$LnUrlCallbackStatus_ErrorStatus) then) = - __$$LnUrlCallbackStatus_ErrorStatusCopyWithImpl<$Res>; +abstract class _$$LnUrlCallbackStatus_ErrorStatusImplCopyWith<$Res> { + factory _$$LnUrlCallbackStatus_ErrorStatusImplCopyWith(_$LnUrlCallbackStatus_ErrorStatusImpl value, + $Res Function(_$LnUrlCallbackStatus_ErrorStatusImpl) then) = + __$$LnUrlCallbackStatus_ErrorStatusImplCopyWithImpl<$Res>; @useResult $Res call({LnUrlErrorData data}); } /// @nodoc -class __$$LnUrlCallbackStatus_ErrorStatusCopyWithImpl<$Res> - extends _$LnUrlCallbackStatusCopyWithImpl<$Res, _$LnUrlCallbackStatus_ErrorStatus> - implements _$$LnUrlCallbackStatus_ErrorStatusCopyWith<$Res> { - __$$LnUrlCallbackStatus_ErrorStatusCopyWithImpl( - _$LnUrlCallbackStatus_ErrorStatus _value, $Res Function(_$LnUrlCallbackStatus_ErrorStatus) _then) +class __$$LnUrlCallbackStatus_ErrorStatusImplCopyWithImpl<$Res> + extends _$LnUrlCallbackStatusCopyWithImpl<$Res, _$LnUrlCallbackStatus_ErrorStatusImpl> + implements _$$LnUrlCallbackStatus_ErrorStatusImplCopyWith<$Res> { + __$$LnUrlCallbackStatus_ErrorStatusImplCopyWithImpl(_$LnUrlCallbackStatus_ErrorStatusImpl _value, + $Res Function(_$LnUrlCallbackStatus_ErrorStatusImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -2975,7 +2992,7 @@ class __$$LnUrlCallbackStatus_ErrorStatusCopyWithImpl<$Res> $Res call({ Object? data = null, }) { - return _then(_$LnUrlCallbackStatus_ErrorStatus( + return _then(_$LnUrlCallbackStatus_ErrorStatusImpl( data: null == data ? _value.data : data // ignore: cast_nullable_to_non_nullable @@ -2986,8 +3003,8 @@ class __$$LnUrlCallbackStatus_ErrorStatusCopyWithImpl<$Res> /// @nodoc -class _$LnUrlCallbackStatus_ErrorStatus implements LnUrlCallbackStatus_ErrorStatus { - const _$LnUrlCallbackStatus_ErrorStatus({required this.data}); +class _$LnUrlCallbackStatus_ErrorStatusImpl implements LnUrlCallbackStatus_ErrorStatus { + const _$LnUrlCallbackStatus_ErrorStatusImpl({required this.data}); @override final LnUrlErrorData data; @@ -3001,7 +3018,7 @@ class _$LnUrlCallbackStatus_ErrorStatus implements LnUrlCallbackStatus_ErrorStat bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$LnUrlCallbackStatus_ErrorStatus && + other is _$LnUrlCallbackStatus_ErrorStatusImpl && (identical(other.data, data) || other.data == data)); } @@ -3011,8 +3028,9 @@ class _$LnUrlCallbackStatus_ErrorStatus implements LnUrlCallbackStatus_ErrorStat @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$LnUrlCallbackStatus_ErrorStatusCopyWith<_$LnUrlCallbackStatus_ErrorStatus> get copyWith => - __$$LnUrlCallbackStatus_ErrorStatusCopyWithImpl<_$LnUrlCallbackStatus_ErrorStatus>(this, _$identity); + _$$LnUrlCallbackStatus_ErrorStatusImplCopyWith<_$LnUrlCallbackStatus_ErrorStatusImpl> get copyWith => + __$$LnUrlCallbackStatus_ErrorStatusImplCopyWithImpl<_$LnUrlCallbackStatus_ErrorStatusImpl>( + this, _$identity); @override @optionalTypeArgs @@ -3079,11 +3097,11 @@ class _$LnUrlCallbackStatus_ErrorStatus implements LnUrlCallbackStatus_ErrorStat abstract class LnUrlCallbackStatus_ErrorStatus implements LnUrlCallbackStatus { const factory LnUrlCallbackStatus_ErrorStatus({required final LnUrlErrorData data}) = - _$LnUrlCallbackStatus_ErrorStatus; + _$LnUrlCallbackStatus_ErrorStatusImpl; LnUrlErrorData get data; @JsonKey(ignore: true) - _$$LnUrlCallbackStatus_ErrorStatusCopyWith<_$LnUrlCallbackStatus_ErrorStatus> get copyWith => + _$$LnUrlCallbackStatus_ErrorStatusImplCopyWith<_$LnUrlCallbackStatus_ErrorStatusImpl> get copyWith => throw _privateConstructorUsedError; } @@ -3148,10 +3166,10 @@ class _$LnUrlPayResultCopyWithImpl<$Res, $Val extends LnUrlPayResult> } /// @nodoc -abstract class _$$LnUrlPayResult_EndpointSuccessCopyWith<$Res> { - factory _$$LnUrlPayResult_EndpointSuccessCopyWith( - _$LnUrlPayResult_EndpointSuccess value, $Res Function(_$LnUrlPayResult_EndpointSuccess) then) = - __$$LnUrlPayResult_EndpointSuccessCopyWithImpl<$Res>; +abstract class _$$LnUrlPayResult_EndpointSuccessImplCopyWith<$Res> { + factory _$$LnUrlPayResult_EndpointSuccessImplCopyWith(_$LnUrlPayResult_EndpointSuccessImpl value, + $Res Function(_$LnUrlPayResult_EndpointSuccessImpl) then) = + __$$LnUrlPayResult_EndpointSuccessImplCopyWithImpl<$Res>; @useResult $Res call({SuccessActionProcessed? data}); @@ -3159,11 +3177,11 @@ abstract class _$$LnUrlPayResult_EndpointSuccessCopyWith<$Res> { } /// @nodoc -class __$$LnUrlPayResult_EndpointSuccessCopyWithImpl<$Res> - extends _$LnUrlPayResultCopyWithImpl<$Res, _$LnUrlPayResult_EndpointSuccess> - implements _$$LnUrlPayResult_EndpointSuccessCopyWith<$Res> { - __$$LnUrlPayResult_EndpointSuccessCopyWithImpl( - _$LnUrlPayResult_EndpointSuccess _value, $Res Function(_$LnUrlPayResult_EndpointSuccess) _then) +class __$$LnUrlPayResult_EndpointSuccessImplCopyWithImpl<$Res> + extends _$LnUrlPayResultCopyWithImpl<$Res, _$LnUrlPayResult_EndpointSuccessImpl> + implements _$$LnUrlPayResult_EndpointSuccessImplCopyWith<$Res> { + __$$LnUrlPayResult_EndpointSuccessImplCopyWithImpl( + _$LnUrlPayResult_EndpointSuccessImpl _value, $Res Function(_$LnUrlPayResult_EndpointSuccessImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -3171,7 +3189,7 @@ class __$$LnUrlPayResult_EndpointSuccessCopyWithImpl<$Res> $Res call({ Object? data = freezed, }) { - return _then(_$LnUrlPayResult_EndpointSuccess( + return _then(_$LnUrlPayResult_EndpointSuccessImpl( data: freezed == data ? _value.data : data // ignore: cast_nullable_to_non_nullable @@ -3194,8 +3212,8 @@ class __$$LnUrlPayResult_EndpointSuccessCopyWithImpl<$Res> /// @nodoc -class _$LnUrlPayResult_EndpointSuccess implements LnUrlPayResult_EndpointSuccess { - const _$LnUrlPayResult_EndpointSuccess({this.data}); +class _$LnUrlPayResult_EndpointSuccessImpl implements LnUrlPayResult_EndpointSuccess { + const _$LnUrlPayResult_EndpointSuccessImpl({this.data}); @override final SuccessActionProcessed? data; @@ -3209,7 +3227,7 @@ class _$LnUrlPayResult_EndpointSuccess implements LnUrlPayResult_EndpointSuccess bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$LnUrlPayResult_EndpointSuccess && + other is _$LnUrlPayResult_EndpointSuccessImpl && (identical(other.data, data) || other.data == data)); } @@ -3219,8 +3237,9 @@ class _$LnUrlPayResult_EndpointSuccess implements LnUrlPayResult_EndpointSuccess @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$LnUrlPayResult_EndpointSuccessCopyWith<_$LnUrlPayResult_EndpointSuccess> get copyWith => - __$$LnUrlPayResult_EndpointSuccessCopyWithImpl<_$LnUrlPayResult_EndpointSuccess>(this, _$identity); + _$$LnUrlPayResult_EndpointSuccessImplCopyWith<_$LnUrlPayResult_EndpointSuccessImpl> get copyWith => + __$$LnUrlPayResult_EndpointSuccessImplCopyWithImpl<_$LnUrlPayResult_EndpointSuccessImpl>( + this, _$identity); @override @optionalTypeArgs @@ -3287,30 +3306,30 @@ class _$LnUrlPayResult_EndpointSuccess implements LnUrlPayResult_EndpointSuccess abstract class LnUrlPayResult_EndpointSuccess implements LnUrlPayResult { const factory LnUrlPayResult_EndpointSuccess({final SuccessActionProcessed? data}) = - _$LnUrlPayResult_EndpointSuccess; + _$LnUrlPayResult_EndpointSuccessImpl; @override SuccessActionProcessed? get data; @JsonKey(ignore: true) - _$$LnUrlPayResult_EndpointSuccessCopyWith<_$LnUrlPayResult_EndpointSuccess> get copyWith => + _$$LnUrlPayResult_EndpointSuccessImplCopyWith<_$LnUrlPayResult_EndpointSuccessImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$LnUrlPayResult_EndpointErrorCopyWith<$Res> { - factory _$$LnUrlPayResult_EndpointErrorCopyWith( - _$LnUrlPayResult_EndpointError value, $Res Function(_$LnUrlPayResult_EndpointError) then) = - __$$LnUrlPayResult_EndpointErrorCopyWithImpl<$Res>; +abstract class _$$LnUrlPayResult_EndpointErrorImplCopyWith<$Res> { + factory _$$LnUrlPayResult_EndpointErrorImplCopyWith( + _$LnUrlPayResult_EndpointErrorImpl value, $Res Function(_$LnUrlPayResult_EndpointErrorImpl) then) = + __$$LnUrlPayResult_EndpointErrorImplCopyWithImpl<$Res>; @useResult $Res call({LnUrlErrorData data}); } /// @nodoc -class __$$LnUrlPayResult_EndpointErrorCopyWithImpl<$Res> - extends _$LnUrlPayResultCopyWithImpl<$Res, _$LnUrlPayResult_EndpointError> - implements _$$LnUrlPayResult_EndpointErrorCopyWith<$Res> { - __$$LnUrlPayResult_EndpointErrorCopyWithImpl( - _$LnUrlPayResult_EndpointError _value, $Res Function(_$LnUrlPayResult_EndpointError) _then) +class __$$LnUrlPayResult_EndpointErrorImplCopyWithImpl<$Res> + extends _$LnUrlPayResultCopyWithImpl<$Res, _$LnUrlPayResult_EndpointErrorImpl> + implements _$$LnUrlPayResult_EndpointErrorImplCopyWith<$Res> { + __$$LnUrlPayResult_EndpointErrorImplCopyWithImpl( + _$LnUrlPayResult_EndpointErrorImpl _value, $Res Function(_$LnUrlPayResult_EndpointErrorImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -3318,7 +3337,7 @@ class __$$LnUrlPayResult_EndpointErrorCopyWithImpl<$Res> $Res call({ Object? data = null, }) { - return _then(_$LnUrlPayResult_EndpointError( + return _then(_$LnUrlPayResult_EndpointErrorImpl( data: null == data ? _value.data : data // ignore: cast_nullable_to_non_nullable @@ -3329,8 +3348,8 @@ class __$$LnUrlPayResult_EndpointErrorCopyWithImpl<$Res> /// @nodoc -class _$LnUrlPayResult_EndpointError implements LnUrlPayResult_EndpointError { - const _$LnUrlPayResult_EndpointError({required this.data}); +class _$LnUrlPayResult_EndpointErrorImpl implements LnUrlPayResult_EndpointError { + const _$LnUrlPayResult_EndpointErrorImpl({required this.data}); @override final LnUrlErrorData data; @@ -3344,7 +3363,7 @@ class _$LnUrlPayResult_EndpointError implements LnUrlPayResult_EndpointError { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$LnUrlPayResult_EndpointError && + other is _$LnUrlPayResult_EndpointErrorImpl && (identical(other.data, data) || other.data == data)); } @@ -3354,8 +3373,8 @@ class _$LnUrlPayResult_EndpointError implements LnUrlPayResult_EndpointError { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$LnUrlPayResult_EndpointErrorCopyWith<_$LnUrlPayResult_EndpointError> get copyWith => - __$$LnUrlPayResult_EndpointErrorCopyWithImpl<_$LnUrlPayResult_EndpointError>(this, _$identity); + _$$LnUrlPayResult_EndpointErrorImplCopyWith<_$LnUrlPayResult_EndpointErrorImpl> get copyWith => + __$$LnUrlPayResult_EndpointErrorImplCopyWithImpl<_$LnUrlPayResult_EndpointErrorImpl>(this, _$identity); @override @optionalTypeArgs @@ -3422,12 +3441,12 @@ class _$LnUrlPayResult_EndpointError implements LnUrlPayResult_EndpointError { abstract class LnUrlPayResult_EndpointError implements LnUrlPayResult { const factory LnUrlPayResult_EndpointError({required final LnUrlErrorData data}) = - _$LnUrlPayResult_EndpointError; + _$LnUrlPayResult_EndpointErrorImpl; @override LnUrlErrorData get data; @JsonKey(ignore: true) - _$$LnUrlPayResult_EndpointErrorCopyWith<_$LnUrlPayResult_EndpointError> get copyWith => + _$$LnUrlPayResult_EndpointErrorImplCopyWith<_$LnUrlPayResult_EndpointErrorImpl> get copyWith => throw _privateConstructorUsedError; } @@ -3492,20 +3511,20 @@ class _$LnUrlWithdrawResultCopyWithImpl<$Res, $Val extends LnUrlWithdrawResult> } /// @nodoc -abstract class _$$LnUrlWithdrawResult_OkCopyWith<$Res> { - factory _$$LnUrlWithdrawResult_OkCopyWith( - _$LnUrlWithdrawResult_Ok value, $Res Function(_$LnUrlWithdrawResult_Ok) then) = - __$$LnUrlWithdrawResult_OkCopyWithImpl<$Res>; +abstract class _$$LnUrlWithdrawResult_OkImplCopyWith<$Res> { + factory _$$LnUrlWithdrawResult_OkImplCopyWith( + _$LnUrlWithdrawResult_OkImpl value, $Res Function(_$LnUrlWithdrawResult_OkImpl) then) = + __$$LnUrlWithdrawResult_OkImplCopyWithImpl<$Res>; @useResult $Res call({LnUrlWithdrawSuccessData data}); } /// @nodoc -class __$$LnUrlWithdrawResult_OkCopyWithImpl<$Res> - extends _$LnUrlWithdrawResultCopyWithImpl<$Res, _$LnUrlWithdrawResult_Ok> - implements _$$LnUrlWithdrawResult_OkCopyWith<$Res> { - __$$LnUrlWithdrawResult_OkCopyWithImpl( - _$LnUrlWithdrawResult_Ok _value, $Res Function(_$LnUrlWithdrawResult_Ok) _then) +class __$$LnUrlWithdrawResult_OkImplCopyWithImpl<$Res> + extends _$LnUrlWithdrawResultCopyWithImpl<$Res, _$LnUrlWithdrawResult_OkImpl> + implements _$$LnUrlWithdrawResult_OkImplCopyWith<$Res> { + __$$LnUrlWithdrawResult_OkImplCopyWithImpl( + _$LnUrlWithdrawResult_OkImpl _value, $Res Function(_$LnUrlWithdrawResult_OkImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -3513,7 +3532,7 @@ class __$$LnUrlWithdrawResult_OkCopyWithImpl<$Res> $Res call({ Object? data = null, }) { - return _then(_$LnUrlWithdrawResult_Ok( + return _then(_$LnUrlWithdrawResult_OkImpl( data: null == data ? _value.data : data // ignore: cast_nullable_to_non_nullable @@ -3524,8 +3543,8 @@ class __$$LnUrlWithdrawResult_OkCopyWithImpl<$Res> /// @nodoc -class _$LnUrlWithdrawResult_Ok implements LnUrlWithdrawResult_Ok { - const _$LnUrlWithdrawResult_Ok({required this.data}); +class _$LnUrlWithdrawResult_OkImpl implements LnUrlWithdrawResult_Ok { + const _$LnUrlWithdrawResult_OkImpl({required this.data}); @override final LnUrlWithdrawSuccessData data; @@ -3539,7 +3558,7 @@ class _$LnUrlWithdrawResult_Ok implements LnUrlWithdrawResult_Ok { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$LnUrlWithdrawResult_Ok && + other is _$LnUrlWithdrawResult_OkImpl && (identical(other.data, data) || other.data == data)); } @@ -3549,8 +3568,8 @@ class _$LnUrlWithdrawResult_Ok implements LnUrlWithdrawResult_Ok { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$LnUrlWithdrawResult_OkCopyWith<_$LnUrlWithdrawResult_Ok> get copyWith => - __$$LnUrlWithdrawResult_OkCopyWithImpl<_$LnUrlWithdrawResult_Ok>(this, _$identity); + _$$LnUrlWithdrawResult_OkImplCopyWith<_$LnUrlWithdrawResult_OkImpl> get copyWith => + __$$LnUrlWithdrawResult_OkImplCopyWithImpl<_$LnUrlWithdrawResult_OkImpl>(this, _$identity); @override @optionalTypeArgs @@ -3617,30 +3636,30 @@ class _$LnUrlWithdrawResult_Ok implements LnUrlWithdrawResult_Ok { abstract class LnUrlWithdrawResult_Ok implements LnUrlWithdrawResult { const factory LnUrlWithdrawResult_Ok({required final LnUrlWithdrawSuccessData data}) = - _$LnUrlWithdrawResult_Ok; + _$LnUrlWithdrawResult_OkImpl; @override LnUrlWithdrawSuccessData get data; @JsonKey(ignore: true) - _$$LnUrlWithdrawResult_OkCopyWith<_$LnUrlWithdrawResult_Ok> get copyWith => + _$$LnUrlWithdrawResult_OkImplCopyWith<_$LnUrlWithdrawResult_OkImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$LnUrlWithdrawResult_ErrorStatusCopyWith<$Res> { - factory _$$LnUrlWithdrawResult_ErrorStatusCopyWith( - _$LnUrlWithdrawResult_ErrorStatus value, $Res Function(_$LnUrlWithdrawResult_ErrorStatus) then) = - __$$LnUrlWithdrawResult_ErrorStatusCopyWithImpl<$Res>; +abstract class _$$LnUrlWithdrawResult_ErrorStatusImplCopyWith<$Res> { + factory _$$LnUrlWithdrawResult_ErrorStatusImplCopyWith(_$LnUrlWithdrawResult_ErrorStatusImpl value, + $Res Function(_$LnUrlWithdrawResult_ErrorStatusImpl) then) = + __$$LnUrlWithdrawResult_ErrorStatusImplCopyWithImpl<$Res>; @useResult $Res call({LnUrlErrorData data}); } /// @nodoc -class __$$LnUrlWithdrawResult_ErrorStatusCopyWithImpl<$Res> - extends _$LnUrlWithdrawResultCopyWithImpl<$Res, _$LnUrlWithdrawResult_ErrorStatus> - implements _$$LnUrlWithdrawResult_ErrorStatusCopyWith<$Res> { - __$$LnUrlWithdrawResult_ErrorStatusCopyWithImpl( - _$LnUrlWithdrawResult_ErrorStatus _value, $Res Function(_$LnUrlWithdrawResult_ErrorStatus) _then) +class __$$LnUrlWithdrawResult_ErrorStatusImplCopyWithImpl<$Res> + extends _$LnUrlWithdrawResultCopyWithImpl<$Res, _$LnUrlWithdrawResult_ErrorStatusImpl> + implements _$$LnUrlWithdrawResult_ErrorStatusImplCopyWith<$Res> { + __$$LnUrlWithdrawResult_ErrorStatusImplCopyWithImpl(_$LnUrlWithdrawResult_ErrorStatusImpl _value, + $Res Function(_$LnUrlWithdrawResult_ErrorStatusImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -3648,7 +3667,7 @@ class __$$LnUrlWithdrawResult_ErrorStatusCopyWithImpl<$Res> $Res call({ Object? data = null, }) { - return _then(_$LnUrlWithdrawResult_ErrorStatus( + return _then(_$LnUrlWithdrawResult_ErrorStatusImpl( data: null == data ? _value.data : data // ignore: cast_nullable_to_non_nullable @@ -3659,8 +3678,8 @@ class __$$LnUrlWithdrawResult_ErrorStatusCopyWithImpl<$Res> /// @nodoc -class _$LnUrlWithdrawResult_ErrorStatus implements LnUrlWithdrawResult_ErrorStatus { - const _$LnUrlWithdrawResult_ErrorStatus({required this.data}); +class _$LnUrlWithdrawResult_ErrorStatusImpl implements LnUrlWithdrawResult_ErrorStatus { + const _$LnUrlWithdrawResult_ErrorStatusImpl({required this.data}); @override final LnUrlErrorData data; @@ -3674,7 +3693,7 @@ class _$LnUrlWithdrawResult_ErrorStatus implements LnUrlWithdrawResult_ErrorStat bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$LnUrlWithdrawResult_ErrorStatus && + other is _$LnUrlWithdrawResult_ErrorStatusImpl && (identical(other.data, data) || other.data == data)); } @@ -3684,8 +3703,9 @@ class _$LnUrlWithdrawResult_ErrorStatus implements LnUrlWithdrawResult_ErrorStat @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$LnUrlWithdrawResult_ErrorStatusCopyWith<_$LnUrlWithdrawResult_ErrorStatus> get copyWith => - __$$LnUrlWithdrawResult_ErrorStatusCopyWithImpl<_$LnUrlWithdrawResult_ErrorStatus>(this, _$identity); + _$$LnUrlWithdrawResult_ErrorStatusImplCopyWith<_$LnUrlWithdrawResult_ErrorStatusImpl> get copyWith => + __$$LnUrlWithdrawResult_ErrorStatusImplCopyWithImpl<_$LnUrlWithdrawResult_ErrorStatusImpl>( + this, _$identity); @override @optionalTypeArgs @@ -3752,12 +3772,12 @@ class _$LnUrlWithdrawResult_ErrorStatus implements LnUrlWithdrawResult_ErrorStat abstract class LnUrlWithdrawResult_ErrorStatus implements LnUrlWithdrawResult { const factory LnUrlWithdrawResult_ErrorStatus({required final LnUrlErrorData data}) = - _$LnUrlWithdrawResult_ErrorStatus; + _$LnUrlWithdrawResult_ErrorStatusImpl; @override LnUrlErrorData get data; @JsonKey(ignore: true) - _$$LnUrlWithdrawResult_ErrorStatusCopyWith<_$LnUrlWithdrawResult_ErrorStatus> get copyWith => + _$$LnUrlWithdrawResult_ErrorStatusImplCopyWith<_$LnUrlWithdrawResult_ErrorStatusImpl> get copyWith => throw _privateConstructorUsedError; } @@ -3833,21 +3853,21 @@ class _$NodeConfigCopyWithImpl<$Res, $Val extends NodeConfig> implements $NodeCo } /// @nodoc -abstract class _$$NodeConfig_GreenlightCopyWith<$Res> implements $NodeConfigCopyWith<$Res> { - factory _$$NodeConfig_GreenlightCopyWith( - _$NodeConfig_Greenlight value, $Res Function(_$NodeConfig_Greenlight) then) = - __$$NodeConfig_GreenlightCopyWithImpl<$Res>; +abstract class _$$NodeConfig_GreenlightImplCopyWith<$Res> implements $NodeConfigCopyWith<$Res> { + factory _$$NodeConfig_GreenlightImplCopyWith( + _$NodeConfig_GreenlightImpl value, $Res Function(_$NodeConfig_GreenlightImpl) then) = + __$$NodeConfig_GreenlightImplCopyWithImpl<$Res>; @override @useResult $Res call({GreenlightNodeConfig config}); } /// @nodoc -class __$$NodeConfig_GreenlightCopyWithImpl<$Res> - extends _$NodeConfigCopyWithImpl<$Res, _$NodeConfig_Greenlight> - implements _$$NodeConfig_GreenlightCopyWith<$Res> { - __$$NodeConfig_GreenlightCopyWithImpl( - _$NodeConfig_Greenlight _value, $Res Function(_$NodeConfig_Greenlight) _then) +class __$$NodeConfig_GreenlightImplCopyWithImpl<$Res> + extends _$NodeConfigCopyWithImpl<$Res, _$NodeConfig_GreenlightImpl> + implements _$$NodeConfig_GreenlightImplCopyWith<$Res> { + __$$NodeConfig_GreenlightImplCopyWithImpl( + _$NodeConfig_GreenlightImpl _value, $Res Function(_$NodeConfig_GreenlightImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -3855,7 +3875,7 @@ class __$$NodeConfig_GreenlightCopyWithImpl<$Res> $Res call({ Object? config = null, }) { - return _then(_$NodeConfig_Greenlight( + return _then(_$NodeConfig_GreenlightImpl( config: null == config ? _value.config : config // ignore: cast_nullable_to_non_nullable @@ -3866,8 +3886,8 @@ class __$$NodeConfig_GreenlightCopyWithImpl<$Res> /// @nodoc -class _$NodeConfig_Greenlight implements NodeConfig_Greenlight { - const _$NodeConfig_Greenlight({required this.config}); +class _$NodeConfig_GreenlightImpl implements NodeConfig_Greenlight { + const _$NodeConfig_GreenlightImpl({required this.config}); @override final GreenlightNodeConfig config; @@ -3881,7 +3901,7 @@ class _$NodeConfig_Greenlight implements NodeConfig_Greenlight { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$NodeConfig_Greenlight && + other is _$NodeConfig_GreenlightImpl && (identical(other.config, config) || other.config == config)); } @@ -3891,8 +3911,8 @@ class _$NodeConfig_Greenlight implements NodeConfig_Greenlight { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$NodeConfig_GreenlightCopyWith<_$NodeConfig_Greenlight> get copyWith => - __$$NodeConfig_GreenlightCopyWithImpl<_$NodeConfig_Greenlight>(this, _$identity); + _$$NodeConfig_GreenlightImplCopyWith<_$NodeConfig_GreenlightImpl> get copyWith => + __$$NodeConfig_GreenlightImplCopyWithImpl<_$NodeConfig_GreenlightImpl>(this, _$identity); @override @optionalTypeArgs @@ -3952,13 +3972,14 @@ class _$NodeConfig_Greenlight implements NodeConfig_Greenlight { } abstract class NodeConfig_Greenlight implements NodeConfig { - const factory NodeConfig_Greenlight({required final GreenlightNodeConfig config}) = _$NodeConfig_Greenlight; + const factory NodeConfig_Greenlight({required final GreenlightNodeConfig config}) = + _$NodeConfig_GreenlightImpl; @override GreenlightNodeConfig get config; @override @JsonKey(ignore: true) - _$$NodeConfig_GreenlightCopyWith<_$NodeConfig_Greenlight> get copyWith => + _$$NodeConfig_GreenlightImplCopyWith<_$NodeConfig_GreenlightImpl> get copyWith => throw _privateConstructorUsedError; } @@ -4023,17 +4044,20 @@ class _$PaymentDetailsCopyWithImpl<$Res, $Val extends PaymentDetails> } /// @nodoc -abstract class _$$PaymentDetails_LnCopyWith<$Res> { - factory _$$PaymentDetails_LnCopyWith(_$PaymentDetails_Ln value, $Res Function(_$PaymentDetails_Ln) then) = - __$$PaymentDetails_LnCopyWithImpl<$Res>; +abstract class _$$PaymentDetails_LnImplCopyWith<$Res> { + factory _$$PaymentDetails_LnImplCopyWith( + _$PaymentDetails_LnImpl value, $Res Function(_$PaymentDetails_LnImpl) then) = + __$$PaymentDetails_LnImplCopyWithImpl<$Res>; @useResult $Res call({LnPaymentDetails data}); } /// @nodoc -class __$$PaymentDetails_LnCopyWithImpl<$Res> extends _$PaymentDetailsCopyWithImpl<$Res, _$PaymentDetails_Ln> - implements _$$PaymentDetails_LnCopyWith<$Res> { - __$$PaymentDetails_LnCopyWithImpl(_$PaymentDetails_Ln _value, $Res Function(_$PaymentDetails_Ln) _then) +class __$$PaymentDetails_LnImplCopyWithImpl<$Res> + extends _$PaymentDetailsCopyWithImpl<$Res, _$PaymentDetails_LnImpl> + implements _$$PaymentDetails_LnImplCopyWith<$Res> { + __$$PaymentDetails_LnImplCopyWithImpl( + _$PaymentDetails_LnImpl _value, $Res Function(_$PaymentDetails_LnImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -4041,7 +4065,7 @@ class __$$PaymentDetails_LnCopyWithImpl<$Res> extends _$PaymentDetailsCopyWithIm $Res call({ Object? data = null, }) { - return _then(_$PaymentDetails_Ln( + return _then(_$PaymentDetails_LnImpl( data: null == data ? _value.data : data // ignore: cast_nullable_to_non_nullable @@ -4052,8 +4076,8 @@ class __$$PaymentDetails_LnCopyWithImpl<$Res> extends _$PaymentDetailsCopyWithIm /// @nodoc -class _$PaymentDetails_Ln implements PaymentDetails_Ln { - const _$PaymentDetails_Ln({required this.data}); +class _$PaymentDetails_LnImpl implements PaymentDetails_Ln { + const _$PaymentDetails_LnImpl({required this.data}); @override final LnPaymentDetails data; @@ -4067,7 +4091,7 @@ class _$PaymentDetails_Ln implements PaymentDetails_Ln { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$PaymentDetails_Ln && + other is _$PaymentDetails_LnImpl && (identical(other.data, data) || other.data == data)); } @@ -4077,8 +4101,8 @@ class _$PaymentDetails_Ln implements PaymentDetails_Ln { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$PaymentDetails_LnCopyWith<_$PaymentDetails_Ln> get copyWith => - __$$PaymentDetails_LnCopyWithImpl<_$PaymentDetails_Ln>(this, _$identity); + _$$PaymentDetails_LnImplCopyWith<_$PaymentDetails_LnImpl> get copyWith => + __$$PaymentDetails_LnImplCopyWithImpl<_$PaymentDetails_LnImpl>(this, _$identity); @override @optionalTypeArgs @@ -4144,29 +4168,30 @@ class _$PaymentDetails_Ln implements PaymentDetails_Ln { } abstract class PaymentDetails_Ln implements PaymentDetails { - const factory PaymentDetails_Ln({required final LnPaymentDetails data}) = _$PaymentDetails_Ln; + const factory PaymentDetails_Ln({required final LnPaymentDetails data}) = _$PaymentDetails_LnImpl; @override LnPaymentDetails get data; @JsonKey(ignore: true) - _$$PaymentDetails_LnCopyWith<_$PaymentDetails_Ln> get copyWith => throw _privateConstructorUsedError; + _$$PaymentDetails_LnImplCopyWith<_$PaymentDetails_LnImpl> get copyWith => + throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$PaymentDetails_ClosedChannelCopyWith<$Res> { - factory _$$PaymentDetails_ClosedChannelCopyWith( - _$PaymentDetails_ClosedChannel value, $Res Function(_$PaymentDetails_ClosedChannel) then) = - __$$PaymentDetails_ClosedChannelCopyWithImpl<$Res>; +abstract class _$$PaymentDetails_ClosedChannelImplCopyWith<$Res> { + factory _$$PaymentDetails_ClosedChannelImplCopyWith( + _$PaymentDetails_ClosedChannelImpl value, $Res Function(_$PaymentDetails_ClosedChannelImpl) then) = + __$$PaymentDetails_ClosedChannelImplCopyWithImpl<$Res>; @useResult $Res call({ClosedChannelPaymentDetails data}); } /// @nodoc -class __$$PaymentDetails_ClosedChannelCopyWithImpl<$Res> - extends _$PaymentDetailsCopyWithImpl<$Res, _$PaymentDetails_ClosedChannel> - implements _$$PaymentDetails_ClosedChannelCopyWith<$Res> { - __$$PaymentDetails_ClosedChannelCopyWithImpl( - _$PaymentDetails_ClosedChannel _value, $Res Function(_$PaymentDetails_ClosedChannel) _then) +class __$$PaymentDetails_ClosedChannelImplCopyWithImpl<$Res> + extends _$PaymentDetailsCopyWithImpl<$Res, _$PaymentDetails_ClosedChannelImpl> + implements _$$PaymentDetails_ClosedChannelImplCopyWith<$Res> { + __$$PaymentDetails_ClosedChannelImplCopyWithImpl( + _$PaymentDetails_ClosedChannelImpl _value, $Res Function(_$PaymentDetails_ClosedChannelImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -4174,7 +4199,7 @@ class __$$PaymentDetails_ClosedChannelCopyWithImpl<$Res> $Res call({ Object? data = null, }) { - return _then(_$PaymentDetails_ClosedChannel( + return _then(_$PaymentDetails_ClosedChannelImpl( data: null == data ? _value.data : data // ignore: cast_nullable_to_non_nullable @@ -4185,8 +4210,8 @@ class __$$PaymentDetails_ClosedChannelCopyWithImpl<$Res> /// @nodoc -class _$PaymentDetails_ClosedChannel implements PaymentDetails_ClosedChannel { - const _$PaymentDetails_ClosedChannel({required this.data}); +class _$PaymentDetails_ClosedChannelImpl implements PaymentDetails_ClosedChannel { + const _$PaymentDetails_ClosedChannelImpl({required this.data}); @override final ClosedChannelPaymentDetails data; @@ -4200,7 +4225,7 @@ class _$PaymentDetails_ClosedChannel implements PaymentDetails_ClosedChannel { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$PaymentDetails_ClosedChannel && + other is _$PaymentDetails_ClosedChannelImpl && (identical(other.data, data) || other.data == data)); } @@ -4210,8 +4235,8 @@ class _$PaymentDetails_ClosedChannel implements PaymentDetails_ClosedChannel { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$PaymentDetails_ClosedChannelCopyWith<_$PaymentDetails_ClosedChannel> get copyWith => - __$$PaymentDetails_ClosedChannelCopyWithImpl<_$PaymentDetails_ClosedChannel>(this, _$identity); + _$$PaymentDetails_ClosedChannelImplCopyWith<_$PaymentDetails_ClosedChannelImpl> get copyWith => + __$$PaymentDetails_ClosedChannelImplCopyWithImpl<_$PaymentDetails_ClosedChannelImpl>(this, _$identity); @override @optionalTypeArgs @@ -4278,12 +4303,12 @@ class _$PaymentDetails_ClosedChannel implements PaymentDetails_ClosedChannel { abstract class PaymentDetails_ClosedChannel implements PaymentDetails { const factory PaymentDetails_ClosedChannel({required final ClosedChannelPaymentDetails data}) = - _$PaymentDetails_ClosedChannel; + _$PaymentDetails_ClosedChannelImpl; @override ClosedChannelPaymentDetails get data; @JsonKey(ignore: true) - _$$PaymentDetails_ClosedChannelCopyWith<_$PaymentDetails_ClosedChannel> get copyWith => + _$$PaymentDetails_ClosedChannelImplCopyWith<_$PaymentDetails_ClosedChannelImpl> get copyWith => throw _privateConstructorUsedError; } @@ -4355,20 +4380,20 @@ class _$SuccessActionProcessedCopyWithImpl<$Res, $Val extends SuccessActionProce } /// @nodoc -abstract class _$$SuccessActionProcessed_AesCopyWith<$Res> { - factory _$$SuccessActionProcessed_AesCopyWith( - _$SuccessActionProcessed_Aes value, $Res Function(_$SuccessActionProcessed_Aes) then) = - __$$SuccessActionProcessed_AesCopyWithImpl<$Res>; +abstract class _$$SuccessActionProcessed_AesImplCopyWith<$Res> { + factory _$$SuccessActionProcessed_AesImplCopyWith( + _$SuccessActionProcessed_AesImpl value, $Res Function(_$SuccessActionProcessed_AesImpl) then) = + __$$SuccessActionProcessed_AesImplCopyWithImpl<$Res>; @useResult $Res call({AesSuccessActionDataDecrypted data}); } /// @nodoc -class __$$SuccessActionProcessed_AesCopyWithImpl<$Res> - extends _$SuccessActionProcessedCopyWithImpl<$Res, _$SuccessActionProcessed_Aes> - implements _$$SuccessActionProcessed_AesCopyWith<$Res> { - __$$SuccessActionProcessed_AesCopyWithImpl( - _$SuccessActionProcessed_Aes _value, $Res Function(_$SuccessActionProcessed_Aes) _then) +class __$$SuccessActionProcessed_AesImplCopyWithImpl<$Res> + extends _$SuccessActionProcessedCopyWithImpl<$Res, _$SuccessActionProcessed_AesImpl> + implements _$$SuccessActionProcessed_AesImplCopyWith<$Res> { + __$$SuccessActionProcessed_AesImplCopyWithImpl( + _$SuccessActionProcessed_AesImpl _value, $Res Function(_$SuccessActionProcessed_AesImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -4376,7 +4401,7 @@ class __$$SuccessActionProcessed_AesCopyWithImpl<$Res> $Res call({ Object? data = null, }) { - return _then(_$SuccessActionProcessed_Aes( + return _then(_$SuccessActionProcessed_AesImpl( data: null == data ? _value.data : data // ignore: cast_nullable_to_non_nullable @@ -4387,8 +4412,8 @@ class __$$SuccessActionProcessed_AesCopyWithImpl<$Res> /// @nodoc -class _$SuccessActionProcessed_Aes implements SuccessActionProcessed_Aes { - const _$SuccessActionProcessed_Aes({required this.data}); +class _$SuccessActionProcessed_AesImpl implements SuccessActionProcessed_Aes { + const _$SuccessActionProcessed_AesImpl({required this.data}); @override final AesSuccessActionDataDecrypted data; @@ -4402,7 +4427,7 @@ class _$SuccessActionProcessed_Aes implements SuccessActionProcessed_Aes { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$SuccessActionProcessed_Aes && + other is _$SuccessActionProcessed_AesImpl && (identical(other.data, data) || other.data == data)); } @@ -4412,8 +4437,8 @@ class _$SuccessActionProcessed_Aes implements SuccessActionProcessed_Aes { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$SuccessActionProcessed_AesCopyWith<_$SuccessActionProcessed_Aes> get copyWith => - __$$SuccessActionProcessed_AesCopyWithImpl<_$SuccessActionProcessed_Aes>(this, _$identity); + _$$SuccessActionProcessed_AesImplCopyWith<_$SuccessActionProcessed_AesImpl> get copyWith => + __$$SuccessActionProcessed_AesImplCopyWithImpl<_$SuccessActionProcessed_AesImpl>(this, _$identity); @override @optionalTypeArgs @@ -4486,30 +4511,30 @@ class _$SuccessActionProcessed_Aes implements SuccessActionProcessed_Aes { abstract class SuccessActionProcessed_Aes implements SuccessActionProcessed { const factory SuccessActionProcessed_Aes({required final AesSuccessActionDataDecrypted data}) = - _$SuccessActionProcessed_Aes; + _$SuccessActionProcessed_AesImpl; @override AesSuccessActionDataDecrypted get data; @JsonKey(ignore: true) - _$$SuccessActionProcessed_AesCopyWith<_$SuccessActionProcessed_Aes> get copyWith => + _$$SuccessActionProcessed_AesImplCopyWith<_$SuccessActionProcessed_AesImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$SuccessActionProcessed_MessageCopyWith<$Res> { - factory _$$SuccessActionProcessed_MessageCopyWith( - _$SuccessActionProcessed_Message value, $Res Function(_$SuccessActionProcessed_Message) then) = - __$$SuccessActionProcessed_MessageCopyWithImpl<$Res>; +abstract class _$$SuccessActionProcessed_MessageImplCopyWith<$Res> { + factory _$$SuccessActionProcessed_MessageImplCopyWith(_$SuccessActionProcessed_MessageImpl value, + $Res Function(_$SuccessActionProcessed_MessageImpl) then) = + __$$SuccessActionProcessed_MessageImplCopyWithImpl<$Res>; @useResult $Res call({MessageSuccessActionData data}); } /// @nodoc -class __$$SuccessActionProcessed_MessageCopyWithImpl<$Res> - extends _$SuccessActionProcessedCopyWithImpl<$Res, _$SuccessActionProcessed_Message> - implements _$$SuccessActionProcessed_MessageCopyWith<$Res> { - __$$SuccessActionProcessed_MessageCopyWithImpl( - _$SuccessActionProcessed_Message _value, $Res Function(_$SuccessActionProcessed_Message) _then) +class __$$SuccessActionProcessed_MessageImplCopyWithImpl<$Res> + extends _$SuccessActionProcessedCopyWithImpl<$Res, _$SuccessActionProcessed_MessageImpl> + implements _$$SuccessActionProcessed_MessageImplCopyWith<$Res> { + __$$SuccessActionProcessed_MessageImplCopyWithImpl( + _$SuccessActionProcessed_MessageImpl _value, $Res Function(_$SuccessActionProcessed_MessageImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -4517,7 +4542,7 @@ class __$$SuccessActionProcessed_MessageCopyWithImpl<$Res> $Res call({ Object? data = null, }) { - return _then(_$SuccessActionProcessed_Message( + return _then(_$SuccessActionProcessed_MessageImpl( data: null == data ? _value.data : data // ignore: cast_nullable_to_non_nullable @@ -4528,8 +4553,8 @@ class __$$SuccessActionProcessed_MessageCopyWithImpl<$Res> /// @nodoc -class _$SuccessActionProcessed_Message implements SuccessActionProcessed_Message { - const _$SuccessActionProcessed_Message({required this.data}); +class _$SuccessActionProcessed_MessageImpl implements SuccessActionProcessed_Message { + const _$SuccessActionProcessed_MessageImpl({required this.data}); @override final MessageSuccessActionData data; @@ -4543,7 +4568,7 @@ class _$SuccessActionProcessed_Message implements SuccessActionProcessed_Message bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$SuccessActionProcessed_Message && + other is _$SuccessActionProcessed_MessageImpl && (identical(other.data, data) || other.data == data)); } @@ -4553,8 +4578,9 @@ class _$SuccessActionProcessed_Message implements SuccessActionProcessed_Message @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$SuccessActionProcessed_MessageCopyWith<_$SuccessActionProcessed_Message> get copyWith => - __$$SuccessActionProcessed_MessageCopyWithImpl<_$SuccessActionProcessed_Message>(this, _$identity); + _$$SuccessActionProcessed_MessageImplCopyWith<_$SuccessActionProcessed_MessageImpl> get copyWith => + __$$SuccessActionProcessed_MessageImplCopyWithImpl<_$SuccessActionProcessed_MessageImpl>( + this, _$identity); @override @optionalTypeArgs @@ -4627,30 +4653,30 @@ class _$SuccessActionProcessed_Message implements SuccessActionProcessed_Message abstract class SuccessActionProcessed_Message implements SuccessActionProcessed { const factory SuccessActionProcessed_Message({required final MessageSuccessActionData data}) = - _$SuccessActionProcessed_Message; + _$SuccessActionProcessed_MessageImpl; @override MessageSuccessActionData get data; @JsonKey(ignore: true) - _$$SuccessActionProcessed_MessageCopyWith<_$SuccessActionProcessed_Message> get copyWith => + _$$SuccessActionProcessed_MessageImplCopyWith<_$SuccessActionProcessed_MessageImpl> get copyWith => throw _privateConstructorUsedError; } /// @nodoc -abstract class _$$SuccessActionProcessed_UrlCopyWith<$Res> { - factory _$$SuccessActionProcessed_UrlCopyWith( - _$SuccessActionProcessed_Url value, $Res Function(_$SuccessActionProcessed_Url) then) = - __$$SuccessActionProcessed_UrlCopyWithImpl<$Res>; +abstract class _$$SuccessActionProcessed_UrlImplCopyWith<$Res> { + factory _$$SuccessActionProcessed_UrlImplCopyWith( + _$SuccessActionProcessed_UrlImpl value, $Res Function(_$SuccessActionProcessed_UrlImpl) then) = + __$$SuccessActionProcessed_UrlImplCopyWithImpl<$Res>; @useResult $Res call({UrlSuccessActionData data}); } /// @nodoc -class __$$SuccessActionProcessed_UrlCopyWithImpl<$Res> - extends _$SuccessActionProcessedCopyWithImpl<$Res, _$SuccessActionProcessed_Url> - implements _$$SuccessActionProcessed_UrlCopyWith<$Res> { - __$$SuccessActionProcessed_UrlCopyWithImpl( - _$SuccessActionProcessed_Url _value, $Res Function(_$SuccessActionProcessed_Url) _then) +class __$$SuccessActionProcessed_UrlImplCopyWithImpl<$Res> + extends _$SuccessActionProcessedCopyWithImpl<$Res, _$SuccessActionProcessed_UrlImpl> + implements _$$SuccessActionProcessed_UrlImplCopyWith<$Res> { + __$$SuccessActionProcessed_UrlImplCopyWithImpl( + _$SuccessActionProcessed_UrlImpl _value, $Res Function(_$SuccessActionProcessed_UrlImpl) _then) : super(_value, _then); @pragma('vm:prefer-inline') @@ -4658,7 +4684,7 @@ class __$$SuccessActionProcessed_UrlCopyWithImpl<$Res> $Res call({ Object? data = null, }) { - return _then(_$SuccessActionProcessed_Url( + return _then(_$SuccessActionProcessed_UrlImpl( data: null == data ? _value.data : data // ignore: cast_nullable_to_non_nullable @@ -4669,8 +4695,8 @@ class __$$SuccessActionProcessed_UrlCopyWithImpl<$Res> /// @nodoc -class _$SuccessActionProcessed_Url implements SuccessActionProcessed_Url { - const _$SuccessActionProcessed_Url({required this.data}); +class _$SuccessActionProcessed_UrlImpl implements SuccessActionProcessed_Url { + const _$SuccessActionProcessed_UrlImpl({required this.data}); @override final UrlSuccessActionData data; @@ -4684,7 +4710,7 @@ class _$SuccessActionProcessed_Url implements SuccessActionProcessed_Url { bool operator ==(dynamic other) { return identical(this, other) || (other.runtimeType == runtimeType && - other is _$SuccessActionProcessed_Url && + other is _$SuccessActionProcessed_UrlImpl && (identical(other.data, data) || other.data == data)); } @@ -4694,8 +4720,8 @@ class _$SuccessActionProcessed_Url implements SuccessActionProcessed_Url { @JsonKey(ignore: true) @override @pragma('vm:prefer-inline') - _$$SuccessActionProcessed_UrlCopyWith<_$SuccessActionProcessed_Url> get copyWith => - __$$SuccessActionProcessed_UrlCopyWithImpl<_$SuccessActionProcessed_Url>(this, _$identity); + _$$SuccessActionProcessed_UrlImplCopyWith<_$SuccessActionProcessed_UrlImpl> get copyWith => + __$$SuccessActionProcessed_UrlImplCopyWithImpl<_$SuccessActionProcessed_UrlImpl>(this, _$identity); @override @optionalTypeArgs @@ -4768,11 +4794,11 @@ class _$SuccessActionProcessed_Url implements SuccessActionProcessed_Url { abstract class SuccessActionProcessed_Url implements SuccessActionProcessed { const factory SuccessActionProcessed_Url({required final UrlSuccessActionData data}) = - _$SuccessActionProcessed_Url; + _$SuccessActionProcessed_UrlImpl; @override UrlSuccessActionData get data; @JsonKey(ignore: true) - _$$SuccessActionProcessed_UrlCopyWith<_$SuccessActionProcessed_Url> get copyWith => + _$$SuccessActionProcessed_UrlImplCopyWith<_$SuccessActionProcessed_UrlImpl> get copyWith => throw _privateConstructorUsedError; } diff --git a/libs/sdk-flutter/makefile b/libs/sdk-flutter/makefile index 1c265fe2a..0aa8a94f3 100644 --- a/libs/sdk-flutter/makefile +++ b/libs/sdk-flutter/makefile @@ -5,7 +5,8 @@ OS_NAME=$(shell uname | tr '[:upper:]' '[:lower:]') .PHONY: init init: cargo install cargo-ndk - cargo install flutter_rust_bridge_codegen --version 1.75.2 + cargo install cargo-expand + cargo install flutter_rust_bridge_codegen --version 1.80.1 flutter pub get ## all: Compile iOS, Android diff --git a/libs/sdk-flutter/pubspec.lock b/libs/sdk-flutter/pubspec.lock index 3b0fbae45..e49aae08f 100644 --- a/libs/sdk-flutter/pubspec.lock +++ b/libs/sdk-flutter/pubspec.lock @@ -5,18 +5,18 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 url: "https://pub.dev" source: hosted - version: "61.0.0" + version: "64.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" url: "https://pub.dev" source: hosted - version: "5.13.0" + version: "6.2.0" archive: dependency: transitive description: @@ -37,10 +37,10 @@ packages: dependency: transitive description: name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.0" boolean_selector: dependency: transitive description: @@ -53,10 +53,10 @@ packages: dependency: transitive description: name: build - sha256: "3fbda25365741f8251b39f3917fb3c8e286a96fd068a5a242e11c2012d495777" + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.4.1" build_cli_annotations: dependency: transitive description: @@ -77,34 +77,34 @@ packages: dependency: transitive description: name: build_daemon - sha256: "757153e5d9cd88253cb13f28c2fb55a537dc31fefd98137549895b5beb7c6169" + sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "4.0.0" build_resolvers: dependency: transitive description: name: build_resolvers - sha256: "0713a05b0386bd97f9e63e78108805a4feca5898a4b821d6610857f10c91e975" + sha256: "64e12b0521812d1684b1917bc80945625391cb9bdd4312536b1d69dcb6133ed8" url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.1" build_runner: dependency: "direct dev" description: name: build_runner - sha256: b0a8a7b8a76c493e85f1b84bffa0588859a06197863dba8c9036b15581fd9727 + sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b" url: "https://pub.dev" source: hosted - version: "2.3.3" + version: "2.4.6" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: "0671ad4162ed510b70d0eb4ad6354c249f8429cab4ae7a4cec86bbc2886eb76e" + sha256: c9e32d21dd6626b5c163d48b037ce906bbe428bc23ab77bcd77bb21e593b6185 url: "https://pub.dev" source: hosted - version: "7.2.7+1" + version: "7.2.11" built_collection: dependency: transitive description: @@ -125,10 +125,10 @@ packages: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" checked_yaml: dependency: transitive description: @@ -165,18 +165,10 @@ packages: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 url: "https://pub.dev" source: hosted - version: "1.17.0" - colorize: - dependency: transitive - description: - name: colorize - sha256: "584746cd6ba1cba0633b6720f494fe6f9601c4170f0666c1579d2aa2a61071ba" - url: "https://pub.dev" - source: hosted - version: "3.0.0" + version: "1.17.2" convert: dependency: transitive description: @@ -197,10 +189,10 @@ packages: dependency: transitive description: name: dart_style - sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" + sha256: abd7625e16f51f554ea244d090292945ec4d4be7bfbaf2ec8cccea568919d334 url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.3" fake_async: dependency: transitive description: @@ -213,18 +205,18 @@ packages: dependency: "direct main" description: name: ffi - sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99 + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.1.0" ffigen: dependency: "direct dev" description: name: ffigen - sha256: "4bbf1fa19723a90578e991b9a95afca43bea856809890a26609618fa29087427" + sha256: d3e76c2ad48a4e7f93a29a162006f00eba46ce7c08194a77bb5c5e97d1b5ff0a url: "https://pub.dev" source: hosted - version: "7.2.11" + version: "8.0.2" file: dependency: transitive description: @@ -250,18 +242,18 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 + sha256: ad76540d21c066228ee3f9d1dad64a9f7e46530e8bb7c85011a88bc1fd874bc5 url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "3.0.0" flutter_rust_bridge: dependency: "direct main" description: name: flutter_rust_bridge - sha256: "8dcfeff9dcf0db9c76578c8805a337c0e5e21b4d96887eb1007b6fe141e15ea9" + sha256: ff90d5ddd0cda6d94ed048cc9c4a4d993d1a4bb11605d60a1282fc1bbf173c77 url: "https://pub.dev" source: hosted - version: "1.75.2" + version: "1.80.1" flutter_test: dependency: "direct dev" description: flutter @@ -271,10 +263,10 @@ packages: dependency: "direct main" description: name: freezed - sha256: "2df89855fe181baae3b6d714dc3c4317acf4fccd495a6f36e5e00f24144c6c3b" + sha256: "21bf2825311de65501d22e563e3d7605dff57fb5e6da982db785ae5372ff018a" url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.4.5" freezed_annotation: dependency: "direct main" description: @@ -311,10 +303,10 @@ packages: dependency: transitive description: name: http - sha256: "5895291c13fa8a3bd82e76d5627f69e0d85ca6a30dcac95c4ea19a5d555879c2" + sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" url: "https://pub.dev" source: hosted - version: "0.13.6" + version: "1.1.0" http_multi_server: dependency: transitive description: @@ -343,10 +335,10 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" json_annotation: dependency: transitive description: @@ -359,10 +351,10 @@ packages: dependency: transitive description: name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" + sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "3.0.0" logging: dependency: transitive description: @@ -375,26 +367,26 @@ packages: dependency: transitive description: name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" url: "https://pub.dev" source: hosted - version: "0.12.13" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.2.0" + version: "0.5.0" meta: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" mime: dependency: transitive description: @@ -415,18 +407,18 @@ packages: dependency: transitive description: name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" url: "https://pub.dev" source: hosted - version: "1.8.2" + version: "1.8.3" petitparser: dependency: transitive description: name: petitparser - sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4" + sha256: eeb2d1428ee7f4170e2bd498827296a18d4e7fc462b71727d111c0ac7707cfa6 url: "https://pub.dev" source: hosted - version: "5.1.0" + version: "6.0.1" pointycastle: dependency: transitive description: @@ -463,10 +455,10 @@ packages: dependency: transitive description: name: puppeteer - sha256: dd49117259867d0ce0de33ddd95628fb70cff94581a6432c08272447b8dd1d27 + sha256: f35d26a1a37048c7c46e8aed8a2c51caa1e06f937d2302f6681ff350a5588982 url: "https://pub.dev" source: hosted - version: "2.24.0" + version: "3.5.0" quiver: dependency: transitive description: @@ -516,18 +508,18 @@ packages: dependency: transitive description: name: source_gen - sha256: "373f96cf5a8744bc9816c1ff41cf5391bbdbe3d7a96fe98c622b6738a8a7bd33" + sha256: fc0da689e5302edb6177fdd964efcb7f58912f43c28c2047a808f5bfff643d16 url: "https://pub.dev" source: hosted - version: "1.3.2" + version: "1.4.0" source_span: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" stack_trace: dependency: transitive description: @@ -572,10 +564,10 @@ packages: dependency: transitive description: name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" url: "https://pub.dev" source: hosted - version: "0.4.16" + version: "0.6.0" timing: dependency: transitive description: @@ -620,10 +612,18 @@ packages: dependency: transitive description: name: watcher - sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" + url: "https://pub.dev" + source: hosted + version: "1.1.0" + web: + dependency: transitive + description: + name: web + sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "0.1.4-beta" web_socket_channel: dependency: transitive description: @@ -649,5 +649,5 @@ packages: source: hosted version: "2.1.1" sdks: - dart: ">=2.19.6 <3.0.0" - flutter: ">=3.7.12" + dart: ">=3.1.0 <4.0.0" + flutter: ">=3.10.0" diff --git a/libs/sdk-flutter/pubspec.yaml b/libs/sdk-flutter/pubspec.yaml index 449b27ac4..d16ad7483 100644 --- a/libs/sdk-flutter/pubspec.yaml +++ b/libs/sdk-flutter/pubspec.yaml @@ -1,31 +1,31 @@ name: breez_sdk description: A new flutter plugin project. -version: 0.2.7 +version: 0.2.8 publish_to: none environment: - sdk: ">=2.19.6 <3.0.0" - flutter: ">=3.7.12" + sdk: '>=3.0.0 <4.0.0' + flutter: ">=3.10.0" dependencies: flutter: sdk: flutter ### flutter_rust_bridge_codegen dependencies - ffi: ^2.0.2 - flutter_rust_bridge: 1.75.2 - freezed: ^2.3.5 - freezed_annotation: ^2.2.0 + ffi: ^2.1.0 + flutter_rust_bridge: 1.80.1 # breez-sdk requirement + freezed: ^2.4.5 + freezed_annotation: ^2.4.1 ### rxdart: ^0.27.7 dev_dependencies: flutter_test: sdk: flutter - flutter_lints: ^2.0.2 + flutter_lints: ^3.0.0 # The following dependencies are required by flutter_rust_bridge_codegen to # be defined under dev_dependencies to generate Dart files - build_runner: <2.4.0 # Requires Flutter 3.10 - ffigen: <8.0.0-dev.0 # Requires Flutter 3.10 + build_runner: ^2.4.6 + ffigen: <9.0.0 # flutter_rust_bridge requirement # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec diff --git a/libs/sdk-flutter/test/breez_sdk_test.dart b/libs/sdk-flutter/test/breez_sdk_test.dart index 3860088de..60206f6f4 100644 --- a/libs/sdk-flutter/test/breez_sdk_test.dart +++ b/libs/sdk-flutter/test/breez_sdk_test.dart @@ -5,15 +5,14 @@ void main() { const MethodChannel channel = MethodChannel('breez_sdk'); TestWidgetsFlutterBinding.ensureInitialized(); + final binding = TestDefaultBinaryMessengerBinding.instance; setUp(() { - channel.setMockMethodCallHandler((MethodCall methodCall) async { - return '42'; - }); + binding.defaultBinaryMessenger.setMockMethodCallHandler(channel, (message) async => '42'); }); tearDown(() { - channel.setMockMethodCallHandler(null); + binding.defaultBinaryMessenger.setMockMethodCallHandler(channel, (message) => null); }); test('getPlatformVersion', () async {}); diff --git a/tools/sdk-cli/Cargo.lock b/tools/sdk-cli/Cargo.lock index 421ef13da..6ffcfa953 100644 --- a/tools/sdk-cli/Cargo.lock +++ b/tools/sdk-cli/Cargo.lock @@ -80,9 +80,9 @@ dependencies = [ [[package]] name = "allo-isolate" -version = "0.1.17" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9980a41e4f88ed39a4dc1f263f94c89ddf6c4b3c725643ecddbcb07d6f41ad3c" +checksum = "f56b7997817c178b853573e8bdfb6c3afe02810b43f17d766d6703560074b0c3" dependencies = [ "anyhow", "atomic", @@ -1020,9 +1020,9 @@ dependencies = [ [[package]] name = "flutter_rust_bridge" -version = "1.77.1" +version = "1.80.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8525ccd3a804ab5ae55ab9883e56caf2e38ae307539685e3042bcf6fc494b4ce" +checksum = "fd0305ebc9f097d9826530a55fc2acd63222e912c663f7adce3ab641ecc0f346" dependencies = [ "allo-isolate", "anyhow", @@ -1222,7 +1222,7 @@ dependencies = [ "async-trait", "base64 0.21.2", "bech32", - "bitcoin 0.29.2", + "bitcoin 0.30.1", "bytes", "chacha20poly1305", "cln-grpc", From c2a3e8e9049b4c4ae2accae69e613339f9f9c0c6 Mon Sep 17 00:00:00 2001 From: ruben beck Date: Thu, 26 Oct 2023 13:07:07 +0200 Subject: [PATCH 24/48] ignore .env and .envrc --- .gitignore | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 06e6f72e6..c63232a6a 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,7 @@ libs/sdk-react-native/ios/bindings-swift/** !.vscode/settings.json !.vscode/extensions.json libs/sdk-flutter/ios/bindings-swift/ + +#Direnv +.env +.envrc From f244e1925a1871b1fe153b914011e2201d6e0e28 Mon Sep 17 00:00:00 2001 From: ok300 <106775972+ok300@users.noreply.github.com> Date: Thu, 26 Oct 2023 13:29:02 +0200 Subject: [PATCH 25/48] Add Default trait, util constructor for Request args --- libs/sdk-core/src/breez_services.rs | 38 +++------------ libs/sdk-core/src/models.rs | 46 ++++++++++++++++-- libs/sdk-core/src/persist/transactions.rs | 59 ++++------------------- tools/sdk-cli/src/command_handlers.rs | 16 ++---- 4 files changed, 63 insertions(+), 96 deletions(-) diff --git a/libs/sdk-core/src/breez_services.rs b/libs/sdk-core/src/breez_services.rs index 48e5da435..7a2fb11e0 100644 --- a/libs/sdk-core/src/breez_services.rs +++ b/libs/sdk-core/src/breez_services.rs @@ -356,11 +356,8 @@ impl BreezServices { .receive_payment(ReceivePaymentRequest { amount_msat: req.amount_msat, description: req.description.unwrap_or_default(), - preimage: None, - opening_fee_params: None, use_description_hash: Some(false), - expiry: None, - cltv: None, + ..Default::default() }) .await .map_err(|_| anyhow!("Failed to receive payment"))? @@ -2050,14 +2047,7 @@ pub(crate) mod tests { assert_eq!(fetched_state, dummy_node_state); let all = breez_services - .list_payments(ListPaymentsRequest { - filters: None, - from_timestamp: None, - to_timestamp: None, - include_failures: None, - offset: None, - limit: None, - }) + .list_payments(ListPaymentsRequest::default()) .await?; let mut cloned = all.clone(); @@ -2068,11 +2058,7 @@ pub(crate) mod tests { let received = breez_services .list_payments(ListPaymentsRequest { filters: Some(vec![PaymentTypeFilter::Received]), - from_timestamp: None, - to_timestamp: None, - include_failures: None, - offset: None, - limit: None, + ..Default::default() }) .await?; assert_eq!(received, vec![cloned[1].clone(), cloned[0].clone()]); @@ -2083,11 +2069,7 @@ pub(crate) mod tests { PaymentTypeFilter::Sent, PaymentTypeFilter::ClosedChannels, ]), - from_timestamp: None, - to_timestamp: None, - include_failures: None, - offset: None, - limit: None, + ..Default::default() }) .await?; assert_eq!(sent, vec![cloned[2].clone()]); @@ -2131,11 +2113,8 @@ pub(crate) mod tests { .receive_payment(ReceivePaymentRequest { amount_msat: 3_000_000, description: "should populate lsp hints".to_string(), - preimage: None, - opening_fee_params: None, use_description_hash: Some(false), - expiry: None, - cltv: None, + ..Default::default() }) .await? .ln_invoice; @@ -2189,10 +2168,9 @@ pub(crate) mod tests { let breez_services = breez_services().await?; breez_services.sync().await?; let moonpay_url = breez_services - .buy_bitcoin(BuyBitcoinRequest { - provider: BuyBitcoinProvider::Moonpay, - opening_fee_params: None, - }) + .buy_bitcoin(BuyBitcoinRequest::from_provider( + BuyBitcoinProvider::Moonpay, + )) .await? .url; let parsed = Url::parse(&moonpay_url)?; diff --git a/libs/sdk-core/src/models.rs b/libs/sdk-core/src/models.rs index a4b09fdb8..f066148d8 100644 --- a/libs/sdk-core/src/models.rs +++ b/libs/sdk-core/src/models.rs @@ -657,6 +657,7 @@ pub struct Payment { } /// Represents a list payments request. +#[derive(Default)] pub struct ListPaymentsRequest { pub filters: Option>, pub from_timestamp: Option, @@ -724,13 +725,13 @@ pub struct ClosedChannelPaymentDetails { pub closing_txid: Option, } -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct ReverseSwapFeesRequest { pub send_amount_sat: Option, } /// Represents a receive payment request. -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct ReceivePaymentRequest { /// The amount in satoshis for this payment request pub amount_msat: u64, @@ -750,6 +751,16 @@ pub struct ReceivePaymentRequest { pub cltv: Option, } +impl ReceivePaymentRequest { + pub fn from_amount_and_description(amount_msat: u64, description: String) -> Self { + ReceivePaymentRequest { + amount_msat, + description, + ..Default::default() + } + } +} + /// Represents a receive payment response. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct ReceivePaymentResponse { @@ -763,10 +774,19 @@ pub struct ReceivePaymentResponse { pub struct SendPaymentRequest { /// The bolt11 invoice pub bolt11: String, - /// The amount to pay in millisatoshis + /// The amount to pay in millisatoshis. Should only be set when `bolt11` is a zero-amount invoice. pub amount_msat: Option, } +impl SendPaymentRequest { + pub fn from_bolt11(bolt11: String) -> Self { + SendPaymentRequest { + bolt11, + amount_msat: None, + } + } +} + /// Represents a send spontaneous payment request. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct SendSpontaneousPaymentRequest { @@ -797,13 +817,22 @@ pub struct OpenChannelFeeRequest { pub expiry: Option, } +impl OpenChannelFeeRequest { + pub fn from_amount(amount_msat: u64) -> Self { + OpenChannelFeeRequest { + amount_msat, + expiry: None, + } + } +} + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct OpenChannelFeeResponse { pub fee_msat: u64, pub used_fee_params: Option, } -#[derive(Clone, Debug, Serialize, Deserialize)] +#[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct ReceiveOnchainRequest { pub opening_fee_params: Option, } @@ -814,6 +843,15 @@ pub struct BuyBitcoinRequest { pub opening_fee_params: Option, } +impl BuyBitcoinRequest { + pub fn from_provider(provider: BuyBitcoinProvider) -> Self { + BuyBitcoinRequest { + provider, + opening_fee_params: None, + } + } +} + #[derive(Clone, Debug, Serialize, Deserialize)] pub struct BuyBitcoinResponse { pub url: String, diff --git a/libs/sdk-core/src/persist/transactions.rs b/libs/sdk-core/src/persist/transactions.rs index 69ed24077..94a6b4de5 100644 --- a/libs/sdk-core/src/persist/transactions.rs +++ b/libs/sdk-core/src/persist/transactions.rs @@ -474,14 +474,7 @@ fn test_ln_transactions() -> Result<(), Box> { )?; // retrieve all - let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: None, - from_timestamp: None, - to_timestamp: None, - include_failures: None, - offset: None, - limit: None, - })?; + let retrieve_txs = storage.list_payments(ListPaymentsRequest::default())?; assert_eq!(retrieve_txs.len(), 2); assert_eq!(retrieve_txs, txs); @@ -491,11 +484,7 @@ fn test_ln_transactions() -> Result<(), Box> { PaymentTypeFilter::Sent, PaymentTypeFilter::ClosedChannels, ]), - from_timestamp: None, - to_timestamp: None, - include_failures: None, - offset: None, - limit: None, + ..Default::default() })?; assert_eq!(retrieve_txs.len(), 1); assert_eq!(retrieve_txs[0], txs[0]); @@ -509,11 +498,7 @@ fn test_ln_transactions() -> Result<(), Box> { //test only received let retrieve_txs = storage.list_payments(ListPaymentsRequest { filters: Some(vec![PaymentTypeFilter::Received]), - from_timestamp: None, - to_timestamp: None, - include_failures: None, - offset: None, - limit: None, + ..Default::default() })?; assert_eq!(retrieve_txs.len(), 1); assert_eq!(retrieve_txs[0], txs[1]); @@ -522,36 +507,18 @@ fn test_ln_transactions() -> Result<(), Box> { assert_eq!(max_ts, 2000); storage.insert_or_update_payments(&txs)?; - let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: None, - from_timestamp: None, - to_timestamp: None, - include_failures: None, - offset: None, - limit: None, - })?; + let retrieve_txs = storage.list_payments(ListPaymentsRequest::default())?; assert_eq!(retrieve_txs.len(), 2); assert_eq!(retrieve_txs, txs); storage.insert_open_channel_payment_info("123", 150)?; - let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: None, - from_timestamp: None, - to_timestamp: None, - include_failures: None, - offset: None, - limit: None, - })?; + let retrieve_txs = storage.list_payments(ListPaymentsRequest::default())?; assert_eq!(retrieve_txs[0].fee_msat, 50); // test all with failures let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: None, - from_timestamp: None, - to_timestamp: None, include_failures: Some(true), - offset: None, - limit: None, + ..Default::default() })?; assert_eq!(retrieve_txs.len(), 3); @@ -561,33 +528,25 @@ fn test_ln_transactions() -> Result<(), Box> { PaymentTypeFilter::Sent, PaymentTypeFilter::ClosedChannels, ]), - from_timestamp: None, - to_timestamp: None, include_failures: Some(true), - offset: None, - limit: None, + ..Default::default() })?; assert_eq!(retrieve_txs.len(), 2); // test limit let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: None, - from_timestamp: None, - to_timestamp: None, include_failures: Some(false), - offset: None, limit: Some(1), + ..Default::default() })?; assert_eq!(retrieve_txs.len(), 1); // test offset let retrieve_txs = storage.list_payments(ListPaymentsRequest { - filters: None, - from_timestamp: None, - to_timestamp: None, include_failures: Some(false), offset: Some(1), limit: Some(1), + ..Default::default() })?; assert_eq!(retrieve_txs.len(), 1); assert_eq!(retrieve_txs[0].id, payment_hash_with_lnurl_withdraw); diff --git a/tools/sdk-cli/src/command_handlers.rs b/tools/sdk-cli/src/command_handlers.rs index 46f4a98f3..b9f57b92f 100644 --- a/tools/sdk-cli/src/command_handlers.rs +++ b/tools/sdk-cli/src/command_handlers.rs @@ -132,11 +132,10 @@ pub(crate) async fn handle_command( .receive_payment(ReceivePaymentRequest { amount_msat, description, - preimage: None, - opening_fee_params: None, use_description_hash, expiry, cltv, + ..Default::default() }) .await?; let mut result = serde_json::to_string(&recv_payment_response)?; @@ -150,9 +149,7 @@ pub(crate) async fn handle_command( sat_per_vbyte, } => { let pair_info = sdk()? - .fetch_reverse_swap_fees(ReverseSwapFeesRequest { - send_amount_sat: None, - }) + .fetch_reverse_swap_fees(ReverseSwapFeesRequest::default()) .await .map_err(|e| anyhow!("Failed to fetch reverse swap fee infos: {e}"))?; @@ -297,9 +294,7 @@ pub(crate) async fn handle_command( } Commands::ReceiveOnchain {} => serde_json::to_string_pretty( &sdk()? - .receive_onchain(ReceiveOnchainRequest { - opening_fee_params: None, - }) + .receive_onchain(ReceiveOnchainRequest::default()) .await?, ) .map_err(|e| e.into()), @@ -437,10 +432,7 @@ pub(crate) async fn handle_command( } Commands::BuyBitcoin { provider } => { let res = sdk()? - .buy_bitcoin(BuyBitcoinRequest { - provider: provider.clone(), - opening_fee_params: None, - }) + .buy_bitcoin(BuyBitcoinRequest::from_provider(provider.clone())) .await?; Ok(format!("Here your {:?} url: {}", provider, res.url)) } From 3359e6488d7f74863b9ea6b7e57408776395a614 Mon Sep 17 00:00:00 2001 From: ok300 <106775972+ok300@users.noreply.github.com> Date: Thu, 26 Oct 2023 13:41:27 +0200 Subject: [PATCH 26/48] Bump Greenlight dependency --- libs/Cargo.lock | 35 ++++++++++++++++++++++------------- libs/sdk-core/Cargo.toml | 2 +- tools/sdk-cli/Cargo.lock | 4 ++-- 3 files changed, 25 insertions(+), 16 deletions(-) diff --git a/libs/Cargo.lock b/libs/Cargo.lock index d64870308..66a1c9c04 100644 --- a/libs/Cargo.lock +++ b/libs/Cargo.lock @@ -4,9 +4,9 @@ version = 3 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "a76fd60b23679b7d19bd066031410fb7e458ccc5e958eb5c325888ce4baedc97" dependencies = [ "gimli", ] @@ -328,15 +328,15 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "233d376d6d185f2a3093e58f283f60f880315b6c60075b01f36b3b85154564ca" dependencies = [ "addr2line", "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.6.2", "object", "rustc-demangle", ] @@ -538,7 +538,7 @@ dependencies = [ "lightning 0.0.115", "lightning-invoice 0.23.0", "log", - "miniz_oxide", + "miniz_oxide 0.7.1", "mockito", "once_cell", "openssl", @@ -573,7 +573,7 @@ dependencies = [ "breez-sdk-core", "camino", "flutter_rust_bridge", - "lightning-invoice 0.23.0", + "lightning-invoice 0.24.0", "log", "once_cell", "thiserror", @@ -1293,20 +1293,20 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.0" +version = "0.27.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" +checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" [[package]] name = "gl-client" version = "0.1.9" -source = "git+https://github.com/Blockstream/greenlight.git?rev=28f41bb835659cb3d2e60cd612548f5b22027bb1#28f41bb835659cb3d2e60cd612548f5b22027bb1" +source = "git+https://github.com/Blockstream/greenlight.git?rev=c7ff67eb062c021105f5601df3ac8699ecbeb51c#c7ff67eb062c021105f5601df3ac8699ecbeb51c" dependencies = [ "anyhow", "async-trait", "base64 0.21.2", "bech32", - "bitcoin 0.30.1", + "bitcoin 0.29.2", "bytes", "chacha20poly1305", "cln-grpc", @@ -1932,6 +1932,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" +[[package]] +name = "miniz_oxide" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa" +dependencies = [ + "adler", +] + [[package]] name = "miniz_oxide" version = "0.7.1" @@ -2080,9 +2089,9 @@ dependencies = [ [[package]] name = "object" -version = "0.32.1" +version = "0.30.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +checksum = "03b4680b86d9cfafba8fc491dc9b6df26b68cf40e9e6cd73909194759a63c385" dependencies = [ "memchr", ] diff --git a/libs/sdk-core/Cargo.toml b/libs/sdk-core/Cargo.toml index 4c6386620..4ad6b5c49 100644 --- a/libs/sdk-core/Cargo.toml +++ b/libs/sdk-core/Cargo.toml @@ -18,7 +18,7 @@ bip21 = "0.2" bitcoin = "0.29.2" gl-client = { git = "https://github.com/Blockstream/greenlight.git", features = [ "permissive", -], rev = "28f41bb835659cb3d2e60cd612548f5b22027bb1" } +], rev = "c7ff67eb062c021105f5601df3ac8699ecbeb51c" } zbase32 = "0.1.2" base64 = "0.13.0" chrono = "0.4" diff --git a/tools/sdk-cli/Cargo.lock b/tools/sdk-cli/Cargo.lock index 6ffcfa953..9e7636d66 100644 --- a/tools/sdk-cli/Cargo.lock +++ b/tools/sdk-cli/Cargo.lock @@ -1216,13 +1216,13 @@ checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4" [[package]] name = "gl-client" version = "0.1.9" -source = "git+https://github.com/Blockstream/greenlight.git?rev=28f41bb835659cb3d2e60cd612548f5b22027bb1#28f41bb835659cb3d2e60cd612548f5b22027bb1" +source = "git+https://github.com/Blockstream/greenlight.git?rev=c7ff67eb062c021105f5601df3ac8699ecbeb51c#c7ff67eb062c021105f5601df3ac8699ecbeb51c" dependencies = [ "anyhow", "async-trait", "base64 0.21.2", "bech32", - "bitcoin 0.30.1", + "bitcoin 0.29.2", "bytes", "chacha20poly1305", "cln-grpc", From cc7bafb5a28e6d7cf59faacee2f4f813961b4f54 Mon Sep 17 00:00:00 2001 From: ok300 <106775972+ok300@users.noreply.github.com> Date: Fri, 27 Oct 2023 17:50:12 +0200 Subject: [PATCH 27/48] Removed from..() constructors --- libs/sdk-core/src/breez_services.rs | 7 ++--- libs/sdk-core/src/models.rs | 37 --------------------------- tools/sdk-cli/src/command_handlers.rs | 5 +++- 3 files changed, 8 insertions(+), 41 deletions(-) diff --git a/libs/sdk-core/src/breez_services.rs b/libs/sdk-core/src/breez_services.rs index 7a2fb11e0..443459baf 100644 --- a/libs/sdk-core/src/breez_services.rs +++ b/libs/sdk-core/src/breez_services.rs @@ -2168,9 +2168,10 @@ pub(crate) mod tests { let breez_services = breez_services().await?; breez_services.sync().await?; let moonpay_url = breez_services - .buy_bitcoin(BuyBitcoinRequest::from_provider( - BuyBitcoinProvider::Moonpay, - )) + .buy_bitcoin(BuyBitcoinRequest { + provider: BuyBitcoinProvider::Moonpay, + opening_fee_params: None, + }) .await? .url; let parsed = Url::parse(&moonpay_url)?; diff --git a/libs/sdk-core/src/models.rs b/libs/sdk-core/src/models.rs index f066148d8..61276c68c 100644 --- a/libs/sdk-core/src/models.rs +++ b/libs/sdk-core/src/models.rs @@ -751,16 +751,6 @@ pub struct ReceivePaymentRequest { pub cltv: Option, } -impl ReceivePaymentRequest { - pub fn from_amount_and_description(amount_msat: u64, description: String) -> Self { - ReceivePaymentRequest { - amount_msat, - description, - ..Default::default() - } - } -} - /// Represents a receive payment response. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct ReceivePaymentResponse { @@ -778,15 +768,6 @@ pub struct SendPaymentRequest { pub amount_msat: Option, } -impl SendPaymentRequest { - pub fn from_bolt11(bolt11: String) -> Self { - SendPaymentRequest { - bolt11, - amount_msat: None, - } - } -} - /// Represents a send spontaneous payment request. #[derive(Clone, Debug, Serialize, Deserialize)] pub struct SendSpontaneousPaymentRequest { @@ -817,15 +798,6 @@ pub struct OpenChannelFeeRequest { pub expiry: Option, } -impl OpenChannelFeeRequest { - pub fn from_amount(amount_msat: u64) -> Self { - OpenChannelFeeRequest { - amount_msat, - expiry: None, - } - } -} - #[derive(Clone, Debug, Serialize, Deserialize)] pub struct OpenChannelFeeResponse { pub fee_msat: u64, @@ -843,15 +815,6 @@ pub struct BuyBitcoinRequest { pub opening_fee_params: Option, } -impl BuyBitcoinRequest { - pub fn from_provider(provider: BuyBitcoinProvider) -> Self { - BuyBitcoinRequest { - provider, - opening_fee_params: None, - } - } -} - #[derive(Clone, Debug, Serialize, Deserialize)] pub struct BuyBitcoinResponse { pub url: String, diff --git a/tools/sdk-cli/src/command_handlers.rs b/tools/sdk-cli/src/command_handlers.rs index b9f57b92f..6c7f1c796 100644 --- a/tools/sdk-cli/src/command_handlers.rs +++ b/tools/sdk-cli/src/command_handlers.rs @@ -432,7 +432,10 @@ pub(crate) async fn handle_command( } Commands::BuyBitcoin { provider } => { let res = sdk()? - .buy_bitcoin(BuyBitcoinRequest::from_provider(provider.clone())) + .buy_bitcoin(BuyBitcoinRequest { + provider: provider.clone(), + opening_fee_params: None, + }) .await?; Ok(format!("Here your {:?} url: {}", provider, res.url)) } From dd057e7a84cf52c6ad17baf6a5552a8f3b1a3c22 Mon Sep 17 00:00:00 2001 From: Ross Savage Date: Sat, 28 Oct 2023 23:31:06 +0200 Subject: [PATCH 28/48] Rerun RN codegen to generate functions to convert enum sequences --- .../main/java/com/breezsdk/BreezSDKMapper.kt | 200 +++++++++++- .../sdk-react-native/ios/BreezSDKMapper.swift | 308 +++++++++++++++++- 2 files changed, 506 insertions(+), 2 deletions(-) diff --git a/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt b/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt index 51ba5f0ae..a0d567859 100644 --- a/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt +++ b/libs/sdk-react-native/android/src/main/java/com/breezsdk/BreezSDKMapper.kt @@ -3211,22 +3211,77 @@ fun readableMapOf(breezEvent: BreezEvent): ReadableMap? { return map } +fun asBreezEventList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is ReadableMap -> list.add(asBreezEvent(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asBuyBitcoinProvider(type: String): BuyBitcoinProvider { return BuyBitcoinProvider.valueOf(type.uppercase()) } +fun asBuyBitcoinProviderList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is String -> list.add(asBuyBitcoinProvider(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asChannelState(type: String): ChannelState { return ChannelState.valueOf(type.uppercase()) } +fun asChannelStateList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is String -> list.add(asChannelState(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asEnvironmentType(type: String): EnvironmentType { return EnvironmentType.valueOf(type.uppercase()) } +fun asEnvironmentTypeList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is String -> list.add(asEnvironmentType(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asFeeratePreset(type: String): FeeratePreset { return FeeratePreset.valueOf(type.uppercase()) } +fun asFeeratePresetList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is String -> list.add(asFeeratePreset(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asInputType(inputType: ReadableMap): InputType? { val type = inputType.getString("type") @@ -3296,6 +3351,17 @@ fun readableMapOf(inputType: InputType): ReadableMap? { return map } +fun asInputTypeList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is ReadableMap -> list.add(asInputType(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asLnUrlCallbackStatus(lnUrlCallbackStatus: ReadableMap): LnUrlCallbackStatus? { val type = lnUrlCallbackStatus.getString("type") @@ -3322,6 +3388,17 @@ fun readableMapOf(lnUrlCallbackStatus: LnUrlCallbackStatus): ReadableMap? { return map } +fun asLnUrlCallbackStatusList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is ReadableMap -> list.add(asLnUrlCallbackStatus(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asLnUrlPayResult(lnUrlPayResult: ReadableMap): LnUrlPayResult? { val type = lnUrlPayResult.getString("type") @@ -3357,6 +3434,17 @@ fun readableMapOf(lnUrlPayResult: LnUrlPayResult): ReadableMap? { return map } +fun asLnUrlPayResultList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is ReadableMap -> list.add(asLnUrlPayResult(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asLnUrlWithdrawResult(lnUrlWithdrawResult: ReadableMap): LnUrlWithdrawResult? { val type = lnUrlWithdrawResult.getString("type") @@ -3384,10 +3472,32 @@ fun readableMapOf(lnUrlWithdrawResult: LnUrlWithdrawResult): ReadableMap? { return map } +fun asLnUrlWithdrawResultList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is ReadableMap -> list.add(asLnUrlWithdrawResult(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asNetwork(type: String): Network { return Network.valueOf(type.uppercase()) } +fun asNetworkList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is String -> list.add(asNetwork(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asNodeConfig(nodeConfig: ReadableMap): NodeConfig? { val type = nodeConfig.getString("type") @@ -3408,6 +3518,17 @@ fun readableMapOf(nodeConfig: NodeConfig): ReadableMap? { return map } +fun asNodeConfigList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is ReadableMap -> list.add(asNodeConfig(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asPaymentDetails(paymentDetails: ReadableMap): PaymentDetails? { val type = paymentDetails.getString("type") @@ -3435,22 +3556,77 @@ fun readableMapOf(paymentDetails: PaymentDetails): ReadableMap? { return map } +fun asPaymentDetailsList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is ReadableMap -> list.add(asPaymentDetails(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asPaymentStatus(type: String): PaymentStatus { return PaymentStatus.valueOf(type.uppercase()) } +fun asPaymentStatusList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is String -> list.add(asPaymentStatus(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asPaymentType(type: String): PaymentType { return PaymentType.valueOf(type.uppercase()) } +fun asPaymentTypeList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is String -> list.add(asPaymentType(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asPaymentTypeFilter(type: String): PaymentTypeFilter { return PaymentTypeFilter.valueOf(type.uppercase()) } +fun asPaymentTypeFilterList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is String -> list.add(asPaymentTypeFilter(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asReverseSwapStatus(type: String): ReverseSwapStatus { return ReverseSwapStatus.valueOf(type.uppercase()) } +fun asReverseSwapStatusList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is String -> list.add(asReverseSwapStatus(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asSuccessActionProcessed(successActionProcessed: ReadableMap): SuccessActionProcessed? { val type = successActionProcessed.getString("type") @@ -3485,10 +3661,32 @@ fun readableMapOf(successActionProcessed: SuccessActionProcessed): ReadableMap? return map } +fun asSuccessActionProcessedList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is ReadableMap -> list.add(asSuccessActionProcessed(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun asSwapStatus(type: String): SwapStatus { return SwapStatus.valueOf(type.uppercase()) } +fun asSwapStatusList(arr: ReadableArray): List { + val list = ArrayList() + for (value in arr.toArrayList()) { + when (value) { + is String -> list.add(asSwapStatus(value)!!) + else -> throw IllegalArgumentException("Unexpected type ${value::class.java.name}") + } + } + return list +} + fun readableMapOf(vararg values: Pair): ReadableMap { val map = Arguments.createMap() for ((key, value) in values) { @@ -3527,7 +3725,7 @@ fun pushToArray( is LspInformation -> array.pushMap(readableMapOf(value)) is OpeningFeeParams -> array.pushMap(readableMapOf(value)) is Payment -> array.pushMap(readableMapOf(value)) - is PaymentTypeFilter -> array.pushMap(readableMapOf(value)) + is PaymentTypeFilter -> array.pushString(value.name.lowercase()) is Rate -> array.pushMap(readableMapOf(value)) is ReverseSwapInfo -> array.pushMap(readableMapOf(value)) is RouteHint -> array.pushMap(readableMapOf(value)) diff --git a/libs/sdk-react-native/ios/BreezSDKMapper.swift b/libs/sdk-react-native/ios/BreezSDKMapper.swift index 7c92c42d6..9345f1508 100644 --- a/libs/sdk-react-native/ios/BreezSDKMapper.swift +++ b/libs/sdk-react-native/ios/BreezSDKMapper.swift @@ -659,7 +659,7 @@ class BreezSDKMapper { static func asListPaymentsRequest(listPaymentsRequest: [String: Any?]) throws -> ListPaymentsRequest { var filters: [PaymentTypeFilter]? if let filtersTmp = listPaymentsRequest["filters"] as? [String] { - filters = filtersTmp + filters = try asPaymentTypeFilterList(arr: filtersTmp) } let fromTimestamp = listPaymentsRequest["fromTimestamp"] as? Int64 @@ -2872,6 +2872,23 @@ class BreezSDKMapper { } } + static func arrayOf(breezEventList: [BreezEvent]) -> [Any] { + return breezEventList.map { v -> [String: Any?] in dictionaryOf(breezEvent: v) } + } + + static func asBreezEventList(arr: [Any]) throws -> [BreezEvent] { + var list = [BreezEvent]() + for value in arr { + if let val = value as? [String: Any?] { + var breezEvent = try asBreezEvent(breezEvent: val) + list.append(breezEvent) + } else { + throw NSError(domain: "Unexpected type BreezEvent", code: 0) + } + } + return list + } + static func asBuyBitcoinProvider(buyBitcoinProvider: String) throws -> BuyBitcoinProvider { switch buyBitcoinProvider { case "moonpay": @@ -2888,6 +2905,23 @@ class BreezSDKMapper { } } + static func arrayOf(buyBitcoinProviderList: [BuyBitcoinProvider]) -> [String] { + return buyBitcoinProviderList.map { v -> String in valueOf(buyBitcoinProvider: v) } + } + + static func asBuyBitcoinProviderList(arr: [Any]) throws -> [BuyBitcoinProvider] { + var list = [BuyBitcoinProvider]() + for value in arr { + if let val = value as? String { + var buyBitcoinProvider = try asBuyBitcoinProvider(buyBitcoinProvider: val) + list.append(buyBitcoinProvider) + } else { + throw NSError(domain: "Unexpected type BuyBitcoinProvider", code: 0) + } + } + return list + } + static func asChannelState(channelState: String) throws -> ChannelState { switch channelState { case "pendingOpen": @@ -2922,6 +2956,23 @@ class BreezSDKMapper { } } + static func arrayOf(channelStateList: [ChannelState]) -> [String] { + return channelStateList.map { v -> String in valueOf(channelState: v) } + } + + static func asChannelStateList(arr: [Any]) throws -> [ChannelState] { + var list = [ChannelState]() + for value in arr { + if let val = value as? String { + var channelState = try asChannelState(channelState: val) + list.append(channelState) + } else { + throw NSError(domain: "Unexpected type ChannelState", code: 0) + } + } + return list + } + static func asEnvironmentType(environmentType: String) throws -> EnvironmentType { switch environmentType { case "production": @@ -2944,6 +2995,23 @@ class BreezSDKMapper { } } + static func arrayOf(environmentTypeList: [EnvironmentType]) -> [String] { + return environmentTypeList.map { v -> String in valueOf(environmentType: v) } + } + + static func asEnvironmentTypeList(arr: [Any]) throws -> [EnvironmentType] { + var list = [EnvironmentType]() + for value in arr { + if let val = value as? String { + var environmentType = try asEnvironmentType(environmentType: val) + list.append(environmentType) + } else { + throw NSError(domain: "Unexpected type EnvironmentType", code: 0) + } + } + return list + } + static func asFeeratePreset(feeratePreset: String) throws -> FeeratePreset { switch feeratePreset { case "regular": @@ -2972,6 +3040,23 @@ class BreezSDKMapper { } } + static func arrayOf(feeratePresetList: [FeeratePreset]) -> [String] { + return feeratePresetList.map { v -> String in valueOf(feeratePreset: v) } + } + + static func asFeeratePresetList(arr: [Any]) throws -> [FeeratePreset] { + var list = [FeeratePreset]() + for value in arr { + if let val = value as? String { + var feeratePreset = try asFeeratePreset(feeratePreset: val) + list.append(feeratePreset) + } else { + throw NSError(domain: "Unexpected type FeeratePreset", code: 0) + } + } + return list + } + static func asInputType(inputType: [String: Any?]) throws -> InputType { let type = inputType["type"] as! String if type == "bitcoinAddress" { @@ -3090,6 +3175,23 @@ class BreezSDKMapper { } } + static func arrayOf(inputTypeList: [InputType]) -> [Any] { + return inputTypeList.map { v -> [String: Any?] in dictionaryOf(inputType: v) } + } + + static func asInputTypeList(arr: [Any]) throws -> [InputType] { + var list = [InputType]() + for value in arr { + if let val = value as? [String: Any?] { + var inputType = try asInputType(inputType: val) + list.append(inputType) + } else { + throw NSError(domain: "Unexpected type InputType", code: 0) + } + } + return list + } + static func asLnUrlCallbackStatus(lnUrlCallbackStatus: [String: Any?]) throws -> LnUrlCallbackStatus { let type = lnUrlCallbackStatus["type"] as! String if type == "ok" { @@ -3122,6 +3224,23 @@ class BreezSDKMapper { } } + static func arrayOf(lnUrlCallbackStatusList: [LnUrlCallbackStatus]) -> [Any] { + return lnUrlCallbackStatusList.map { v -> [String: Any?] in dictionaryOf(lnUrlCallbackStatus: v) } + } + + static func asLnUrlCallbackStatusList(arr: [Any]) throws -> [LnUrlCallbackStatus] { + var list = [LnUrlCallbackStatus]() + for value in arr { + if let val = value as? [String: Any?] { + var lnUrlCallbackStatus = try asLnUrlCallbackStatus(lnUrlCallbackStatus: val) + list.append(lnUrlCallbackStatus) + } else { + throw NSError(domain: "Unexpected type LnUrlCallbackStatus", code: 0) + } + } + return list + } + static func asLnUrlPayResult(lnUrlPayResult: [String: Any?]) throws -> LnUrlPayResult { let type = lnUrlPayResult["type"] as! String if type == "endpointSuccess" { @@ -3162,6 +3281,23 @@ class BreezSDKMapper { } } + static func arrayOf(lnUrlPayResultList: [LnUrlPayResult]) -> [Any] { + return lnUrlPayResultList.map { v -> [String: Any?] in dictionaryOf(lnUrlPayResult: v) } + } + + static func asLnUrlPayResultList(arr: [Any]) throws -> [LnUrlPayResult] { + var list = [LnUrlPayResult]() + for value in arr { + if let val = value as? [String: Any?] { + var lnUrlPayResult = try asLnUrlPayResult(lnUrlPayResult: val) + list.append(lnUrlPayResult) + } else { + throw NSError(domain: "Unexpected type LnUrlPayResult", code: 0) + } + } + return list + } + static func asLnUrlWithdrawResult(lnUrlWithdrawResult: [String: Any?]) throws -> LnUrlWithdrawResult { let type = lnUrlWithdrawResult["type"] as! String if type == "ok" { @@ -3200,6 +3336,23 @@ class BreezSDKMapper { } } + static func arrayOf(lnUrlWithdrawResultList: [LnUrlWithdrawResult]) -> [Any] { + return lnUrlWithdrawResultList.map { v -> [String: Any?] in dictionaryOf(lnUrlWithdrawResult: v) } + } + + static func asLnUrlWithdrawResultList(arr: [Any]) throws -> [LnUrlWithdrawResult] { + var list = [LnUrlWithdrawResult]() + for value in arr { + if let val = value as? [String: Any?] { + var lnUrlWithdrawResult = try asLnUrlWithdrawResult(lnUrlWithdrawResult: val) + list.append(lnUrlWithdrawResult) + } else { + throw NSError(domain: "Unexpected type LnUrlWithdrawResult", code: 0) + } + } + return list + } + static func asNetwork(network: String) throws -> Network { switch network { case "bitcoin": @@ -3234,6 +3387,23 @@ class BreezSDKMapper { } } + static func arrayOf(networkList: [Network]) -> [String] { + return networkList.map { v -> String in valueOf(network: v) } + } + + static func asNetworkList(arr: [Any]) throws -> [Network] { + var list = [Network]() + for value in arr { + if let val = value as? String { + var network = try asNetwork(network: val) + list.append(network) + } else { + throw NSError(domain: "Unexpected type Network", code: 0) + } + } + return list + } + static func asNodeConfig(nodeConfig: [String: Any?]) throws -> NodeConfig { let type = nodeConfig["type"] as! String if type == "greenlight" { @@ -3258,6 +3428,23 @@ class BreezSDKMapper { } } + static func arrayOf(nodeConfigList: [NodeConfig]) -> [Any] { + return nodeConfigList.map { v -> [String: Any?] in dictionaryOf(nodeConfig: v) } + } + + static func asNodeConfigList(arr: [Any]) throws -> [NodeConfig] { + var list = [NodeConfig]() + for value in arr { + if let val = value as? [String: Any?] { + var nodeConfig = try asNodeConfig(nodeConfig: val) + list.append(nodeConfig) + } else { + throw NSError(domain: "Unexpected type NodeConfig", code: 0) + } + } + return list + } + static func asPaymentDetails(paymentDetails: [String: Any?]) throws -> PaymentDetails { let type = paymentDetails["type"] as! String if type == "ln" { @@ -3296,6 +3483,23 @@ class BreezSDKMapper { } } + static func arrayOf(paymentDetailsList: [PaymentDetails]) -> [Any] { + return paymentDetailsList.map { v -> [String: Any?] in dictionaryOf(paymentDetails: v) } + } + + static func asPaymentDetailsList(arr: [Any]) throws -> [PaymentDetails] { + var list = [PaymentDetails]() + for value in arr { + if let val = value as? [String: Any?] { + var paymentDetails = try asPaymentDetails(paymentDetails: val) + list.append(paymentDetails) + } else { + throw NSError(domain: "Unexpected type PaymentDetails", code: 0) + } + } + return list + } + static func asPaymentStatus(paymentStatus: String) throws -> PaymentStatus { switch paymentStatus { case "pending": @@ -3324,6 +3528,23 @@ class BreezSDKMapper { } } + static func arrayOf(paymentStatusList: [PaymentStatus]) -> [String] { + return paymentStatusList.map { v -> String in valueOf(paymentStatus: v) } + } + + static func asPaymentStatusList(arr: [Any]) throws -> [PaymentStatus] { + var list = [PaymentStatus]() + for value in arr { + if let val = value as? String { + var paymentStatus = try asPaymentStatus(paymentStatus: val) + list.append(paymentStatus) + } else { + throw NSError(domain: "Unexpected type PaymentStatus", code: 0) + } + } + return list + } + static func asPaymentType(paymentType: String) throws -> PaymentType { switch paymentType { case "sent": @@ -3352,6 +3573,23 @@ class BreezSDKMapper { } } + static func arrayOf(paymentTypeList: [PaymentType]) -> [String] { + return paymentTypeList.map { v -> String in valueOf(paymentType: v) } + } + + static func asPaymentTypeList(arr: [Any]) throws -> [PaymentType] { + var list = [PaymentType]() + for value in arr { + if let val = value as? String { + var paymentType = try asPaymentType(paymentType: val) + list.append(paymentType) + } else { + throw NSError(domain: "Unexpected type PaymentType", code: 0) + } + } + return list + } + static func asPaymentTypeFilter(paymentTypeFilter: String) throws -> PaymentTypeFilter { switch paymentTypeFilter { case "sent": @@ -3380,6 +3618,23 @@ class BreezSDKMapper { } } + static func arrayOf(paymentTypeFilterList: [PaymentTypeFilter]) -> [String] { + return paymentTypeFilterList.map { v -> String in valueOf(paymentTypeFilter: v) } + } + + static func asPaymentTypeFilterList(arr: [Any]) throws -> [PaymentTypeFilter] { + var list = [PaymentTypeFilter]() + for value in arr { + if let val = value as? String { + var paymentTypeFilter = try asPaymentTypeFilter(paymentTypeFilter: val) + list.append(paymentTypeFilter) + } else { + throw NSError(domain: "Unexpected type PaymentTypeFilter", code: 0) + } + } + return list + } + static func asReverseSwapStatus(reverseSwapStatus: String) throws -> ReverseSwapStatus { switch reverseSwapStatus { case "initial": @@ -3420,6 +3675,23 @@ class BreezSDKMapper { } } + static func arrayOf(reverseSwapStatusList: [ReverseSwapStatus]) -> [String] { + return reverseSwapStatusList.map { v -> String in valueOf(reverseSwapStatus: v) } + } + + static func asReverseSwapStatusList(arr: [Any]) throws -> [ReverseSwapStatus] { + var list = [ReverseSwapStatus]() + for value in arr { + if let val = value as? String { + var reverseSwapStatus = try asReverseSwapStatus(reverseSwapStatus: val) + list.append(reverseSwapStatus) + } else { + throw NSError(domain: "Unexpected type ReverseSwapStatus", code: 0) + } + } + return list + } + static func asSuccessActionProcessed(successActionProcessed: [String: Any?]) throws -> SuccessActionProcessed { let type = successActionProcessed["type"] as! String if type == "aes" { @@ -3472,6 +3744,23 @@ class BreezSDKMapper { } } + static func arrayOf(successActionProcessedList: [SuccessActionProcessed]) -> [Any] { + return successActionProcessedList.map { v -> [String: Any?] in dictionaryOf(successActionProcessed: v) } + } + + static func asSuccessActionProcessedList(arr: [Any]) throws -> [SuccessActionProcessed] { + var list = [SuccessActionProcessed]() + for value in arr { + if let val = value as? [String: Any?] { + var successActionProcessed = try asSuccessActionProcessed(successActionProcessed: val) + list.append(successActionProcessed) + } else { + throw NSError(domain: "Unexpected type SuccessActionProcessed", code: 0) + } + } + return list + } + static func asSwapStatus(swapStatus: String) throws -> SwapStatus { switch swapStatus { case "initial": @@ -3493,4 +3782,21 @@ class BreezSDKMapper { return "expired" } } + + static func arrayOf(swapStatusList: [SwapStatus]) -> [String] { + return swapStatusList.map { v -> String in valueOf(swapStatus: v) } + } + + static func asSwapStatusList(arr: [Any]) throws -> [SwapStatus] { + var list = [SwapStatus]() + for value in arr { + if let val = value as? String { + var swapStatus = try asSwapStatus(swapStatus: val) + list.append(swapStatus) + } else { + throw NSError(domain: "Unexpected type SwapStatus", code: 0) + } + } + return list + } } From 857b72d90ed3b003e0add8bb6c7201f9b7e58dc9 Mon Sep 17 00:00:00 2001 From: Jesse de Wit Date: Sat, 28 Oct 2023 12:47:52 +0200 Subject: [PATCH 29/48] check git status --- .github/workflows/main.yml | 94 ++++++++++++++++++++++++++- .github/workflows/publish-flutter.yml | 2 +- 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 219389fc0..2eef97745 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -174,4 +174,96 @@ jobs: cargo clippy -- -D warnings -A clippy::uninlined-format-args cargo clippy --tests -- -D warnings -A clippy::uninlined-format-args cd ../tools/sdk-cli - cargo clippy -- -D warnings \ No newline at end of file + cargo clippy -- -D warnings + + react-native: + name: Check react native + runs-on: macOS-latest + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Install rust + run: | + rustup set auto-self-update disable + rustup toolchain install stable --profile minimal + + - uses: Swatinem/rust-cache@v2 + with: + workspaces: | + libs -> target + + - name: Install Protoc + uses: arduino/setup-protoc@v2 + with: + version: "23.4" + repo-token: ${{ secrets.GITHUB_TOKEN }} + + - name: React native codegen + working-directory: libs/sdk-react-native + run: | + yarn global add tslint typescript + brew install kotlin ktlint swiftformat + make react-native-codegen + + - name: Check git status + env: + GIT_PAGER: cat + run: | + status=$(git status --porcelain) + if [[ -n "$status" ]]; then + echo "Git status has changes" + echo "$status" + git diff + exit 1 + else + echo "No changes in git status" + fi + + flutter: + name: Check flutter + runs-on: macOS-latest + steps: + - name: Checkout repo + uses: actions/checkout@v3 + + - name: Install rust + run: | + rustup set auto-self-update disable + rustup toolchain install stable --profile minimal + + - uses: Swatinem/rust-cache@v2 + with: + workspaces: | + libs -> target + + - name: Install Protoc + uses: arduino/setup-protoc@v2 + with: + version: "23.4" + repo-token: ${{ secrets.GITHUB_TOKEN }} + + - uses: subosito/flutter-action@v2 + with: + flutter-version: '3.13.8' + channel: 'stable' + + - name: Flutter bridge codegen + working-directory: libs/sdk-flutter + run: | + make init + make flutter_rust_bridge + + - name: Check git status + env: + GIT_PAGER: cat + run: | + status=$(git status --porcelain) + if [[ -n "$status" ]]; then + echo "Git status has changes" + echo "$status" + git diff + exit 1 + else + echo "No changes in git status" + fi \ No newline at end of file diff --git a/.github/workflows/publish-flutter.yml b/.github/workflows/publish-flutter.yml index 77ca83ca2..593a1e477 100644 --- a/.github/workflows/publish-flutter.yml +++ b/.github/workflows/publish-flutter.yml @@ -45,7 +45,7 @@ jobs: - uses: subosito/flutter-action@v2 with: - flutter-version: '3.7.12' + flutter-version: '3.13.8' channel: 'stable' - name: Copy package files From f36d73d20b3f9bf740efab5a9a200d89d4140b7c Mon Sep 17 00:00:00 2001 From: Jesse de Wit Date: Sat, 28 Oct 2023 15:40:10 +0200 Subject: [PATCH 30/48] generate flutter bridge --- libs/sdk-flutter/lib/bridge_generated.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/sdk-flutter/lib/bridge_generated.dart b/libs/sdk-flutter/lib/bridge_generated.dart index 5a53d6144..0503abac5 100644 --- a/libs/sdk-flutter/lib/bridge_generated.dart +++ b/libs/sdk-flutter/lib/bridge_generated.dart @@ -1422,7 +1422,7 @@ class SendPaymentRequest { /// The bolt11 invoice final String bolt11; - /// The amount to pay in millisatoshis + /// The amount to pay in millisatoshis. Should only be set when `bolt11` is a zero-amount invoice. final int? amountMsat; const SendPaymentRequest({ From 426e909f1f5ef6bcbaac9ef0cbfb935969715cc8 Mon Sep 17 00:00:00 2001 From: Jesse de Wit Date: Sun, 29 Oct 2023 12:10:05 +0100 Subject: [PATCH 31/48] CI: run flutter analysis --- .github/workflows/main.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2eef97745..c262022ba 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -266,4 +266,10 @@ jobs: exit 1 else echo "No changes in git status" - fi \ No newline at end of file + fi + + - name: dart-analyze + run: dart analyze --fatal-infos + + - name: dart-format + run: dart format -o none --set-exit-if-changed -l 110 . From 6e909fb01ee133136399efb7c5f39b1ff1b2d7a5 Mon Sep 17 00:00:00 2001 From: Ross Savage Date: Sun, 29 Oct 2023 20:46:30 +0100 Subject: [PATCH 32/48] Implement error codes --- libs/sdk-bindings/src/breez_sdk.udl | 101 ++- libs/sdk-bindings/src/uniffi_binding.rs | 89 ++- libs/sdk-core/src/backup.rs | 5 +- libs/sdk-core/src/binding.rs | 70 +- libs/sdk-core/src/breez_services.rs | 435 ++++++------ libs/sdk-core/src/chain.rs | 7 +- libs/sdk-core/src/crypt.rs | 6 +- libs/sdk-core/src/error.rs | 656 +++++++++++++++++- libs/sdk-core/src/fiat.rs | 15 +- .../src/greenlight/backup_transport.rs | 15 +- libs/sdk-core/src/greenlight/error.rs | 213 ++++++ libs/sdk-core/src/greenlight/mod.rs | 1 + libs/sdk-core/src/greenlight/node_api.rs | 154 ++-- libs/sdk-core/src/input_parser.rs | 50 +- libs/sdk-core/src/invoice.rs | 65 +- libs/sdk-core/src/lib.rs | 8 +- libs/sdk-core/src/lnurl/auth.rs | 50 +- libs/sdk-core/src/lnurl/error.rs | 87 +++ libs/sdk-core/src/lnurl/mod.rs | 24 +- libs/sdk-core/src/lnurl/pay.rs | 131 ++-- libs/sdk-core/src/lnurl/withdraw.rs | 37 +- libs/sdk-core/src/lsp.rs | 39 +- libs/sdk-core/src/lsps0/error.rs | 11 + libs/sdk-core/src/lsps0/transport.rs | 2 +- libs/sdk-core/src/models.rs | 150 ++-- libs/sdk-core/src/node_api.rs | 104 +++ libs/sdk-core/src/persist/cache.rs | 38 +- libs/sdk-core/src/persist/channels.rs | 9 +- libs/sdk-core/src/persist/db.rs | 14 +- libs/sdk-core/src/persist/error.rs | 25 + libs/sdk-core/src/persist/mod.rs | 1 + libs/sdk-core/src/persist/reverseswap.rs | 14 +- libs/sdk-core/src/persist/settings.rs | 16 +- libs/sdk-core/src/persist/swap.rs | 70 +- libs/sdk-core/src/persist/sync.rs | 49 +- libs/sdk-core/src/persist/transactions.rs | 55 +- libs/sdk-core/src/swap_in/error.rs | 32 + libs/sdk-core/src/swap_in/mod.rs | 2 + libs/sdk-core/src/{ => swap_in}/swap.rs | 53 +- libs/sdk-core/src/{ => swap_out}/boltzswap.rs | 41 +- libs/sdk-core/src/swap_out/error.rs | 90 +++ libs/sdk-core/src/swap_out/mod.rs | 3 + .../src/{ => swap_out}/reverseswap.rs | 41 +- libs/sdk-core/src/test_utils.rs | 127 ++-- libs/sdk-flutter/lib/bridge_generated.dart | 2 +- .../main/java/com/breezsdk/BreezSDKMapper.kt | 180 ++--- .../main/java/com/breezsdk/BreezSDKModule.kt | 179 +++-- libs/sdk-react-native/example/App.js | 1 + .../sdk-react-native/ios/BreezSDKMapper.swift | 190 ++--- libs/sdk-react-native/ios/RNBreezSDK.swift | 15 +- tools/sdk-cli/src/command_handlers.rs | 2 +- 51 files changed, 2592 insertions(+), 1182 deletions(-) create mode 100644 libs/sdk-core/src/greenlight/error.rs create mode 100644 libs/sdk-core/src/lnurl/error.rs create mode 100644 libs/sdk-core/src/node_api.rs create mode 100644 libs/sdk-core/src/persist/error.rs create mode 100644 libs/sdk-core/src/swap_in/error.rs create mode 100644 libs/sdk-core/src/swap_in/mod.rs rename libs/sdk-core/src/{ => swap_in}/swap.rs (97%) rename libs/sdk-core/src/{ => swap_out}/boltzswap.rs (89%) create mode 100644 libs/sdk-core/src/swap_out/error.rs create mode 100644 libs/sdk-core/src/swap_out/mod.rs rename libs/sdk-core/src/{ => swap_out}/reverseswap.rs (94%) diff --git a/libs/sdk-bindings/src/breez_sdk.udl b/libs/sdk-bindings/src/breez_sdk.udl index 170866871..29abf9b31 100644 --- a/libs/sdk-bindings/src/breez_sdk.udl +++ b/libs/sdk-bindings/src/breez_sdk.udl @@ -11,14 +11,81 @@ dictionary RouteHintHop { [Error] enum SdkError { "Generic", - "InitFailed", - "NotReady", - "LspConnectFailed", - "LspOpenChannelNotSupported", - "PersistenceFailure", - "ReceivePaymentFailed", - "SendPaymentFailed", - "CalculateOpenChannelFeesFailed", + "ServiceConnectivity", +}; + +[Error] +enum LnUrlAuthError { + "Generic", + "InvalidUri", + "ServiceConnectivity", +}; + +[Error] +enum LnUrlPayError { + "AesDecryptionFailed", + "AlreadyPaid", + "Generic", + "InvalidAmount", + "InvalidInvoice", + "InvalidUri", + "InvoiceExpired", + "PaymentFailed", + "PaymentTimeout", + "RouteNotFound", + "RouteTooExpensive", + "ServiceConnectivity", +}; + +[Error] +enum LnUrlWithdrawError { + "Generic", + "InvalidAmount", + "InvalidInvoice", + "InvalidUri", + "ServiceConnectivity", +}; + +[Error] +enum ReceiveOnchainError { + "Generic", + "ServiceConnectivity", + "SwapInProgress", +}; + +[Error] +enum ReceivePaymentError { + "Generic", + "InvalidAmount", + "InvalidInvoice", + "InvoiceExpired", + "InvoiceNoDescription", + "InvoicePreimageAlreadyExists", + "ServiceConnectivity", +}; + +[Error] +enum SendOnchainError { + "Generic", + "InvalidDestinationAddress", + "PaymentFailed", + "PaymentTimeout", + "ReverseSwapInProgress", + "ServiceConnectivity", +}; + +[Error] +enum SendPaymentError { + "AlreadyPaid", + "Generic", + "InvalidAmount", + "InvalidInvoice", + "InvoiceExpired", + "PaymentFailed", + "PaymentTimeout", + "RouteNotFound", + "RouteTooExpensive", + "ServiceConnectivity", }; enum EnvironmentType { @@ -606,22 +673,22 @@ interface BlockingBreezServices { [Throws=SdkError] void disconnect(); - [Throws=SdkError] + [Throws=SendPaymentError] SendPaymentResponse send_payment(SendPaymentRequest req); - [Throws=SdkError] + [Throws=SendPaymentError] SendPaymentResponse send_spontaneous_payment(SendSpontaneousPaymentRequest req); - [Throws=SdkError] + [Throws=ReceivePaymentError] ReceivePaymentResponse receive_payment(ReceivePaymentRequest req); - [Throws=SdkError] + [Throws=LnUrlPayError] LnUrlPayResult pay_lnurl(LnUrlPayRequest req); - [Throws=SdkError] + [Throws=LnUrlWithdrawError] LnUrlWithdrawResult withdraw_lnurl(LnUrlWithdrawRequest request); - [Throws=SdkError] + [Throws=LnUrlAuthError] LnUrlCallbackStatus lnurl_auth(LnUrlAuthRequestData req_data); [Throws=SdkError] @@ -675,7 +742,7 @@ interface BlockingBreezServices { [Throws=SdkError] void close_lsp_channels(); - [Throws=SdkError] + [Throws=ReceiveOnchainError] SwapInfo receive_onchain(ReceiveOnchainRequest req); [Throws=SdkError] @@ -696,7 +763,7 @@ interface BlockingBreezServices { [Throws=SdkError] sequence in_progress_reverse_swaps(); - [Throws=SdkError] + [Throws=SendOnchainError] SendOnchainResponse send_onchain(SendOnchainRequest req); [Throws=SdkError] @@ -708,7 +775,7 @@ interface BlockingBreezServices { [Throws=SdkError] RecommendedFees recommended_fees(); - [Throws=SdkError] + [Throws=ReceiveOnchainError] BuyBitcoinResponse buy_bitcoin(BuyBitcoinRequest req); [Throws=SdkError] diff --git a/libs/sdk-bindings/src/uniffi_binding.rs b/libs/sdk-bindings/src/uniffi_binding.rs index f0f43b55c..397294fcd 100644 --- a/libs/sdk-bindings/src/uniffi_binding.rs +++ b/libs/sdk-bindings/src/uniffi_binding.rs @@ -1,4 +1,4 @@ -use anyhow::{anyhow, Result}; +use anyhow::Result; use breez_sdk_core::{ error::*, mnemonic_to_seed as sdk_mnemonic_to_seed, parse as sdk_parse_input, parse_invoice as sdk_parse_invoice, AesSuccessActionDataDecrypted, BackupFailedData, @@ -96,10 +96,10 @@ pub fn connect( } /// If used, this must be called before `connect` -pub fn set_log_stream(log_stream: Box) -> Result<()> { - LOG_INIT - .set(true) - .map_err(|_| anyhow!("log stream already created"))?; +pub fn set_log_stream(log_stream: Box) -> SdkResult<()> { + LOG_INIT.set(true).map_err(|_| SdkError::Generic { + err: "Log stream already created".into(), + })?; BindingLogger::init(log_stream); Ok(()) } @@ -109,22 +109,28 @@ pub struct BlockingBreezServices { } impl BlockingBreezServices { - pub fn disconnect(&self) -> Result<()> { + pub fn disconnect(&self) -> SdkResult<()> { rt().block_on(self.breez_services.disconnect()) } - pub fn send_payment(&self, req: SendPaymentRequest) -> SdkResult { + pub fn send_payment( + &self, + req: SendPaymentRequest, + ) -> Result { rt().block_on(self.breez_services.send_payment(req)) } pub fn send_spontaneous_payment( &self, req: SendSpontaneousPaymentRequest, - ) -> SdkResult { + ) -> Result { rt().block_on(self.breez_services.send_spontaneous_payment(req)) } - pub fn receive_payment(&self, req: ReceivePaymentRequest) -> SdkResult { + pub fn receive_payment( + &self, + req: ReceivePaymentRequest, + ) -> Result { rt().block_on(self.breez_services.receive_payment(req)) } @@ -134,21 +140,18 @@ impl BlockingBreezServices { pub fn sign_message(&self, req: SignMessageRequest) -> SdkResult { rt().block_on(self.breez_services.sign_message(req)) - .map_err(|e| e.into()) } pub fn check_message(&self, req: CheckMessageRequest) -> SdkResult { rt().block_on(self.breez_services.check_message(req)) - .map_err(|e| e.into()) } pub fn backup_status(&self) -> SdkResult { - self.breez_services.backup_status().map_err(|e| e.into()) + self.breez_services.backup_status() } pub fn backup(&self) -> SdkResult<()> { rt().block_on(self.breez_services.backup()) - .map_err(|e| e.into()) } pub fn list_payments(&self, req: ListPaymentsRequest) -> SdkResult> { @@ -157,37 +160,36 @@ impl BlockingBreezServices { pub fn payment_by_hash(&self, hash: String) -> SdkResult> { rt().block_on(self.breez_services.payment_by_hash(hash)) - .map_err(|e| e.into()) } - pub fn pay_lnurl(&self, req: LnUrlPayRequest) -> SdkResult { + pub fn pay_lnurl(&self, req: LnUrlPayRequest) -> Result { rt().block_on(self.breez_services.lnurl_pay(req)) - .map_err(|e| e.into()) } - pub fn withdraw_lnurl(&self, req: LnUrlWithdrawRequest) -> SdkResult { + pub fn withdraw_lnurl( + &self, + req: LnUrlWithdrawRequest, + ) -> Result { rt().block_on(self.breez_services.lnurl_withdraw(req)) - .map_err(|e| e.into()) } - pub fn lnurl_auth(&self, req_data: LnUrlAuthRequestData) -> SdkResult { + pub fn lnurl_auth( + &self, + req_data: LnUrlAuthRequestData, + ) -> Result { rt().block_on(self.breez_services.lnurl_auth(req_data)) - .map_err(|e| e.into()) } pub fn sweep(&self, req: SweepRequest) -> SdkResult { rt().block_on(self.breez_services.sweep(req)) - .map_err(|e| e.into()) } pub fn fetch_fiat_rates(&self) -> SdkResult> { rt().block_on(self.breez_services.fetch_fiat_rates()) - .map_err(|e| e.into()) } pub fn list_fiat_currencies(&self) -> SdkResult> { rt().block_on(self.breez_services.list_fiat_currencies()) - .map_err(|e| e.into()) } pub fn list_lsps(&self) -> SdkResult> { @@ -200,7 +202,6 @@ impl BlockingBreezServices { pub fn fetch_lsp_info(&self, lsp_id: String) -> SdkResult> { rt().block_on(self.breez_services.fetch_lsp_info(lsp_id)) - .map_err(|e| e.into()) } pub fn lsp_id(&self) -> SdkResult> { @@ -209,7 +210,6 @@ impl BlockingBreezServices { pub fn lsp_info(&self) -> SdkResult { rt().block_on(self.breez_services.lsp_info()) - .map_err(|e: anyhow::Error| e.into()) } pub fn open_channel_fee( @@ -224,25 +224,24 @@ impl BlockingBreezServices { _ = self.breez_services.close_lsp_channels().await?; Ok(()) }) - .map_err(|e: anyhow::Error| e.into()) } /// Onchain receive swap API - pub fn receive_onchain(&self, req: ReceiveOnchainRequest) -> SdkResult { + pub fn receive_onchain( + &self, + req: ReceiveOnchainRequest, + ) -> Result { rt().block_on(self.breez_services.receive_onchain(req)) - .map_err(|e| e.into()) } /// Onchain receive swap API pub fn in_progress_swap(&self) -> SdkResult> { rt().block_on(self.breez_services.in_progress_swap()) - .map_err(|e| e.into()) } /// list non-completed expired swaps that should be refunded by calling [BreezServices::refund] pub fn list_refundables(&self) -> SdkResult> { rt().block_on(self.breez_services.list_refundables()) - .map_err(|e| e.into()) } // prepare a refund transaction for a failed/expired swap @@ -255,7 +254,6 @@ impl BlockingBreezServices { // construct and broadcast a refund transaction for a faile/expired swap pub fn refund(&self, req: RefundRequest) -> SdkResult { rt().block_on(self.breez_services.refund(req)) - .map_err(|e| e.into()) } pub fn fetch_reverse_swap_fees( @@ -263,56 +261,53 @@ impl BlockingBreezServices { req: ReverseSwapFeesRequest, ) -> SdkResult { rt().block_on(self.breez_services.fetch_reverse_swap_fees(req)) - .map_err(|e| e.into()) } pub fn in_progress_reverse_swaps(&self) -> SdkResult> { rt().block_on(self.breez_services.in_progress_reverse_swaps()) - .map_err(|e| e.into()) } - pub fn send_onchain(&self, req: SendOnchainRequest) -> SdkResult { + pub fn send_onchain( + &self, + req: SendOnchainRequest, + ) -> Result { rt().block_on(self.breez_services.send_onchain(req)) - .map_err(|e| e.into()) } - pub fn execute_dev_command(&self, command: String) -> Result { + pub fn execute_dev_command(&self, command: String) -> SdkResult { rt().block_on(self.breez_services.execute_dev_command(command)) } pub fn sync(&self) -> SdkResult<()> { rt().block_on(self.breez_services.sync()) - .map_err(|e| e.into()) } pub fn recommended_fees(&self) -> SdkResult { rt().block_on(self.breez_services.recommended_fees()) - .map_err(|e| e.into()) } - pub fn buy_bitcoin(&self, req: BuyBitcoinRequest) -> SdkResult { + pub fn buy_bitcoin( + &self, + req: BuyBitcoinRequest, + ) -> Result { rt().block_on(self.breez_services.buy_bitcoin(req)) } - pub fn prepare_sweep( - &self, - req: PrepareSweepRequest, - ) -> Result { + pub fn prepare_sweep(&self, req: PrepareSweepRequest) -> SdkResult { rt().block_on(self.breez_services.prepare_sweep(req)) - .map_err(|e| e.into()) } } pub fn parse_invoice(invoice: String) -> SdkResult { - sdk_parse_invoice(&invoice).map_err(|e| e.into()) + Ok(sdk_parse_invoice(&invoice)?) } pub fn parse_input(s: String) -> SdkResult { - rt().block_on(sdk_parse_input(&s)).map_err(|e| e.into()) + rt().block_on(async move { Ok(sdk_parse_input(&s).await?) }) } pub fn mnemonic_to_seed(phrase: String) -> SdkResult> { - sdk_mnemonic_to_seed(phrase).map_err(|e| e.into()) + Ok(sdk_mnemonic_to_seed(phrase)?) } fn rt() -> &'static tokio::runtime::Runtime { diff --git a/libs/sdk-core/src/backup.rs b/libs/sdk-core/src/backup.rs index 02c824010..2b7c1b682 100644 --- a/libs/sdk-core/src/backup.rs +++ b/libs/sdk-core/src/backup.rs @@ -1,5 +1,6 @@ use crate::{ breez_services::BackupFailedData, + error::SdkResult, persist::db::{HookEvent, SqliteStorage}, BreezEvent, Config, }; @@ -63,8 +64,8 @@ pub struct BackupState { /// BackupTransport is the interface for syncing the sdk state between multiple apps. #[tonic::async_trait] pub trait BackupTransport: Send + Sync { - async fn pull(&self) -> Result>; - async fn push(&self, version: Option, data: Vec) -> Result; + async fn pull(&self) -> SdkResult>; + async fn push(&self, version: Option, data: Vec) -> SdkResult; } pub(crate) struct BackupWatcher { diff --git a/libs/sdk-core/src/binding.rs b/libs/sdk-core/src/binding.rs index 06fa4b1f5..80ffbc165 100644 --- a/libs/sdk-core/src/binding.rs +++ b/libs/sdk-core/src/binding.rs @@ -21,7 +21,10 @@ use tokio::sync::Mutex; use crate::breez_services::{self, BreezEvent, BreezServices, EventListener}; use crate::chain::RecommendedFees; -use crate::error::SdkError; +use crate::error::{ + LnUrlAuthError, LnUrlPayError, LnUrlWithdrawError, ReceiveOnchainError, ReceivePaymentError, + SdkError, SendOnchainError, SendPaymentError, +}; use crate::fiat::{FiatCurrency, Rate}; use crate::input_parser::{self, InputType, LnUrlAuthRequestData}; use crate::invoice::{self, LNInvoice}; @@ -64,8 +67,8 @@ pub fn connect(config: Config, seed: Vec) -> Result<()> { *locked = Some(breez_services); Ok(()) } - Some(_) => Err(SdkError::InitFailed { - err: "static node services already set, please call disconnect() first".into(), + Some(_) => Err(SdkError::Generic { + err: "Static node services already set, please call disconnect() first".into(), }), } }) @@ -80,6 +83,7 @@ pub fn is_initialized() -> bool { /// See [BreezServices::sync] pub fn sync() -> Result<()> { block_on(async { get_breez_services().await?.sync().await }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::node_info] @@ -88,7 +92,7 @@ pub fn node_info() -> Result { get_breez_services() .await? .node_info() - .map_err(anyhow::Error::new) + .map_err(anyhow::Error::new::) }) } @@ -102,16 +106,19 @@ pub fn disconnect() -> Result<()> { Ok(()) }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::sign_message] pub fn sign_message(req: SignMessageRequest) -> Result { block_on(async { get_breez_services().await?.sign_message(req).await }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::check_message] pub fn check_message(req: CheckMessageRequest) -> Result { block_on(async { get_breez_services().await?.check_message(req).await }) + .map_err(anyhow::Error::new::) } /* Breez Services Helper API's */ @@ -132,7 +139,7 @@ pub fn default_config( /// See [BreezServices::static_backup] pub fn static_backup(req: StaticBackupRequest) -> Result { - BreezServices::static_backup(req).map_err(anyhow::Error::new) + BreezServices::static_backup(req).map_err(anyhow::Error::new::) } /* Stream API's */ @@ -141,7 +148,7 @@ pub fn static_backup(req: StaticBackupRequest) -> Result { pub fn breez_events_stream(s: StreamSink) -> Result<()> { NOTIFICATION_STREAM .set(s) - .map_err(|_| anyhow!("events stream already created"))?; + .map_err(|_| anyhow!("Events stream already created"))?; Ok(()) } @@ -149,7 +156,7 @@ pub fn breez_events_stream(s: StreamSink) -> Result<()> { pub fn breez_log_stream(s: StreamSink) -> Result<()> { LOG_INIT .set(true) - .map_err(|_| anyhow!("log stream already created"))?; + .map_err(|_| anyhow!("Log stream already created"))?; BindingLogger::init(s); Ok(()) } @@ -158,7 +165,8 @@ pub fn breez_log_stream(s: StreamSink) -> Result<()> { /// See [BreezServices::list_lsps] pub fn list_lsps() -> Result> { - block_on(async { get_breez_services().await?.list_lsps().await }).map_err(anyhow::Error::new) + block_on(async { get_breez_services().await?.list_lsps().await }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::connect_lsp] @@ -169,23 +177,26 @@ pub fn connect_lsp(lsp_id: String) -> Result<()> { /// See [BreezServices::lsp_id] pub fn lsp_id() -> Result> { - block_on(async { get_breez_services().await?.lsp_id().await }).map_err(anyhow::Error::new) + block_on(async { get_breez_services().await?.lsp_id().await }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::fetch_lsp_info] pub fn fetch_lsp_info(id: String) -> Result> { block_on(async { get_breez_services().await?.fetch_lsp_info(id).await }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::lsp_info] pub fn lsp_info() -> Result { block_on(async { get_breez_services().await?.lsp_info().await }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::close_lsp_channels] pub fn close_lsp_channels() -> Result<()> { block_on(async { - _ = get_breez_services().await?.close_lsp_channels().await; + _ = get_breez_services().await?.close_lsp_channels().await?; Ok(()) }) } @@ -195,17 +206,19 @@ pub fn close_lsp_channels() -> Result<()> { /// See [BreezServices::backup] pub fn backup() -> Result<()> { block_on(async { get_breez_services().await?.backup().await }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::backup_status] pub fn backup_status() -> Result { block_on(async { get_breez_services().await?.backup_status() }) + .map_err(anyhow::Error::new::) } /* Parse API's */ pub fn parse_invoice(invoice: String) -> Result { - invoice::parse_invoice(&invoice) + invoice::parse_invoice(&invoice).map_err(|e| anyhow::Error::new::(e.into())) } pub fn parse_input(input: String) -> Result { @@ -217,12 +230,13 @@ pub fn parse_input(input: String) -> Result { /// See [BreezServices::list_payments] pub fn list_payments(req: ListPaymentsRequest) -> Result> { block_on(async { get_breez_services().await?.list_payments(req).await }) - .map_err(anyhow::Error::new) + .map_err(anyhow::Error::new::) } /// See [BreezServices::list_payments] pub fn payment_by_hash(hash: String) -> Result> { block_on(async { get_breez_services().await?.payment_by_hash(hash).await }) + .map_err(anyhow::Error::new::) } /* Lightning Payment API's */ @@ -230,7 +244,7 @@ pub fn payment_by_hash(hash: String) -> Result> { /// See [BreezServices::send_payment] pub fn send_payment(req: SendPaymentRequest) -> Result { block_on(async { get_breez_services().await?.send_payment(req).await }) - .map_err(anyhow::Error::new::) + .map_err(anyhow::Error::new::) } /// See [BreezServices::send_spontaneous_payment] @@ -241,13 +255,13 @@ pub fn send_spontaneous_payment(req: SendSpontaneousPaymentRequest) -> Result) + .map_err(anyhow::Error::new::) } /// See [BreezServices::receive_payment] pub fn receive_payment(req: ReceivePaymentRequest) -> Result { block_on(async { get_breez_services().await?.receive_payment(req).await }) - .map_err(anyhow::Error::new) + .map_err(anyhow::Error::new::) } /* LNURL API's */ @@ -255,16 +269,19 @@ pub fn receive_payment(req: ReceivePaymentRequest) -> Result Result { block_on(async { get_breez_services().await?.lnurl_pay(req).await }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::lnurl_withdraw] pub fn lnurl_withdraw(req: LnUrlWithdrawRequest) -> Result { block_on(async { get_breez_services().await?.lnurl_withdraw(req).await }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::lnurl_auth] pub fn lnurl_auth(req_data: LnUrlAuthRequestData) -> Result { block_on(async { get_breez_services().await?.lnurl_auth(req_data).await }) + .map_err(anyhow::Error::new::) } /* Fiat Currency API's */ @@ -272,11 +289,13 @@ pub fn lnurl_auth(req_data: LnUrlAuthRequestData) -> Result /// See [BreezServices::fetch_fiat_rates] pub fn fetch_fiat_rates() -> Result> { block_on(async { get_breez_services().await?.fetch_fiat_rates().await }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::list_fiat_currencies] pub fn list_fiat_currencies() -> Result> { block_on(async { get_breez_services().await?.list_fiat_currencies().await }) + .map_err(anyhow::Error::new::) } /* On-Chain Swap API's */ @@ -284,27 +303,31 @@ pub fn list_fiat_currencies() -> Result> { /// See [BreezServices::send_onchain] pub fn send_onchain(req: SendOnchainRequest) -> Result { block_on(async { get_breez_services().await?.send_onchain(req).await }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::receive_onchain] pub fn receive_onchain(req: ReceiveOnchainRequest) -> Result { block_on(async { get_breez_services().await?.receive_onchain(req).await }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::buy_bitcoin] pub fn buy_bitcoin(req: BuyBitcoinRequest) -> Result { block_on(async { get_breez_services().await?.buy_bitcoin(req).await }) - .map_err(anyhow::Error::new) + .map_err(anyhow::Error::new::) } /// See [BreezServices::sweep] pub fn sweep(req: SweepRequest) -> Result { block_on(async { get_breez_services().await?.sweep(req).await }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::prepare_sweep] pub fn prepare_sweep(req: PrepareSweepRequest) -> Result { block_on(async { get_breez_services().await?.prepare_sweep(req).await }) + .map_err(anyhow::Error::new::) } /* Refundables API's */ @@ -312,6 +335,7 @@ pub fn prepare_sweep(req: PrepareSweepRequest) -> Result { /// See [BreezServices::list_refundables] pub fn list_refundables() -> Result> { block_on(async { get_breez_services().await?.list_refundables().await }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::prepare_refund] @@ -322,6 +346,7 @@ pub fn prepare_refund(req: PrepareRefundRequest) -> Result Result { block_on(async { get_breez_services().await?.refund(req).await }) + .map_err(anyhow::Error::new::) } /* In Progress Swap API's */ @@ -329,6 +354,7 @@ pub fn refund(req: RefundRequest) -> Result { /// See [BreezServices::in_progress_swap] pub fn in_progress_swap() -> Result> { block_on(async { get_breez_services().await?.in_progress_swap().await }) + .map_err(anyhow::Error::new::) } /// See [BreezServices::in_progress_reverse_swaps] @@ -339,6 +365,7 @@ pub fn in_progress_reverse_swaps() -> Result> { .in_progress_reverse_swaps() .await }) + .map_err(anyhow::Error::new::) } /* Swap Fee API's */ @@ -357,11 +384,13 @@ pub fn fetch_reverse_swap_fees(req: ReverseSwapFeesRequest) -> Result) } /// See [BreezServices::recommended_fees] pub fn recommended_fees() -> Result { block_on(async { get_breez_services().await?.recommended_fees().await }) + .map_err(anyhow::Error::new::) } /* CLI API's */ @@ -374,6 +403,7 @@ pub fn execute_command(command: String) -> Result { .execute_dev_command(command) .await }) + .map_err(anyhow::Error::new::) } /* Binding Related Logic */ @@ -416,10 +446,12 @@ impl log::Log for BindingLogger { fn flush(&self) {} } -async fn get_breez_services() -> Result> { +async fn get_breez_services() -> Result, SdkError> { match BREEZ_SERVICES_INSTANCE.lock().await.as_ref() { - None => Err(anyhow!("Node service was not initialized")), - Some(sdk) => anyhow::Ok(sdk.clone()), + None => Err(SdkError::Generic { + err: "Node service was not initialized".into(), + }), + Some(sdk) => Ok(sdk.clone()), } } diff --git a/libs/sdk-core/src/breez_services.rs b/libs/sdk-core/src/breez_services.rs index 443459baf..5291914dc 100644 --- a/libs/sdk-core/src/breez_services.rs +++ b/libs/sdk-core/src/breez_services.rs @@ -4,26 +4,30 @@ use std::str::FromStr; use std::sync::Arc; use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; -use anyhow::{anyhow, ensure, Result}; +use anyhow::{anyhow, Result}; use bip39::*; use bitcoin::hashes::hex::ToHex; use bitcoin::hashes::{sha256, Hash}; use bitcoin::util::bip32::ChildNumber; use chrono::Local; +use futures::TryFutureExt; use log::{LevelFilter, Metadata, Record}; use serde_json::json; use tokio::sync::{mpsc, watch, Mutex}; use tokio::time::sleep; use tonic::codegen::InterceptedService; +use tonic::metadata::errors::InvalidMetadataValue; use tonic::metadata::{Ascii, MetadataValue}; use tonic::service::Interceptor; -use tonic::transport::{Channel, Uri}; +use tonic::transport::{Channel, Endpoint, Uri}; use tonic::{Request, Status}; use crate::backup::{BackupRequest, BackupTransport, BackupWatcher}; -use crate::boltzswap::BoltzApi; use crate::chain::{ChainService, MempoolSpace, Outspend, RecommendedFees}; -use crate::error::{SdkError, SdkResult}; +use crate::error::{ + LnUrlAuthError, LnUrlPayError, LnUrlWithdrawError, ReceiveOnchainError, ReceivePaymentError, + SdkError, SdkResult, SendOnchainError, SendPaymentError, +}; use crate::fiat::{FiatCurrency, Rate}; use crate::greenlight::{GLBackupTransport, Greenlight}; use crate::grpc::channel_opener_client::ChannelOpenerClient; @@ -43,14 +47,16 @@ use crate::lnurl::withdraw::validate_lnurl_withdraw; use crate::lsp::LspInformation; use crate::models::{ parse_short_channel_id, ChannelState, ClosedChannelPaymentDetails, Config, EnvironmentType, - FiatAPI, LnUrlCallbackStatus, LspAPI, NodeAPI, NodeState, Payment, PaymentDetails, PaymentType, + FiatAPI, LnUrlCallbackStatus, LspAPI, NodeState, Payment, PaymentDetails, PaymentType, ReverseSwapPairInfo, ReverseSwapServiceAPI, SwapInfo, SwapperAPI, INVOICE_PAYMENT_FEE_EXPIRY_SECONDS, }; use crate::moonpay::MoonPayApi; +use crate::node_api::NodeAPI; use crate::persist::db::SqliteStorage; -use crate::reverseswap::BTCSendSwap; -use crate::swap::BTCReceiveSwap; +use crate::swap_in::swap::BTCReceiveSwap; +use crate::swap_out::boltzswap::BoltzApi; +use crate::swap_out::reverseswap::BTCSendSwap; use crate::BuyBitcoinProvider::Moonpay; use crate::*; @@ -192,12 +198,10 @@ impl BreezServices { /// /// It should be called only once when the app is started, regardless whether the app is sent to /// background and back. - async fn start(self: &Arc) -> SdkResult<()> { + async fn start(self: &Arc) -> Result<()> { let mut started = self.started.lock().await; if *started { - return Err(SdkError::InitFailed { - err: "BreezServices already started".into(), - }); + return Err(anyhow!("BreezServices already started")); } let start = Instant::now(); self.start_background_tasks().await?; @@ -208,12 +212,18 @@ impl BreezServices { } /// Trigger the stopping of BreezServices background threads for this instance. - pub async fn disconnect(&self) -> Result<()> { + pub async fn disconnect(&self) -> SdkResult<()> { let mut started = self.started.lock().await; if !*started { - return Err(anyhow::Error::msg("BreezServices is not running")); + return Err(SdkError::Generic { + err: "BreezServices is not running".into(), + }); } - self.shutdown_sender.send(()).map_err(anyhow::Error::msg)?; + self.shutdown_sender + .send(()) + .map_err(|e| SdkError::Generic { + err: format!("Shutdown failed: {e}"), + })?; *started = false; Ok(()) } @@ -222,7 +232,10 @@ impl BreezServices { /// /// Calling `send_payment` ensures that the payment is not already completed, if so it will result in an error. /// If the invoice doesn't specify an amount, the amount is taken from the `amount_msat` arg. - pub async fn send_payment(&self, req: SendPaymentRequest) -> SdkResult { + pub async fn send_payment( + &self, + req: SendPaymentRequest, + ) -> Result { self.start_node().await?; let parsed_invoice = parse_invoice(req.bolt11.as_str())?; let invoice_amount_msat = parsed_invoice.amount_msat.unwrap_or_default(); @@ -230,15 +243,15 @@ impl BreezServices { // Ensure amount is provided for zero invoice if provided_amount_msat == 0 && invoice_amount_msat == 0 { - return Err(SdkError::SendPaymentFailed { - err: "amount must be provided when paying a zero invoice".into(), + return Err(SendPaymentError::InvalidAmount { + err: "Amount must be provided when paying a zero invoice".into(), }); } // Ensure amount is not provided for invoice that contains amount if provided_amount_msat > 0 && invoice_amount_msat > 0 { - return Err(SdkError::SendPaymentFailed { - err: "amount should not be provided when paying a non zero invoice".into(), + return Err(SendPaymentError::InvalidAmount { + err: "Amount should not be provided when paying a non zero invoice".into(), }); } @@ -246,13 +259,12 @@ impl BreezServices { .persister .get_completed_payment_by_hash(&parsed_invoice.payment_hash)? { - Some(_) => Err(SdkError::SendPaymentFailed { - err: "Invoice already paid".into(), - }), + Some(_) => Err(SendPaymentError::AlreadyPaid), None => { let payment_res = self .node_api .send_payment(req.bolt11.clone(), req.amount_msat) + .map_err(Into::into) .await; let payment = self .on_payment_completed( @@ -270,11 +282,12 @@ impl BreezServices { pub async fn send_spontaneous_payment( &self, req: SendSpontaneousPaymentRequest, - ) -> SdkResult { + ) -> Result { self.start_node().await?; let payment_res = self .node_api .send_spontaneous_payment(req.node_id.clone(), req.amount_msat) + .map_err(Into::into) .await; let payment = self .on_payment_completed(req.node_id, None, payment_res) @@ -290,7 +303,7 @@ impl BreezServices { /// is made. /// /// This method will return an [anyhow::Error] when any validation check fails. - pub async fn lnurl_pay(&self, req: LnUrlPayRequest) -> Result { + pub async fn lnurl_pay(&self, req: LnUrlPayRequest) -> Result { match validate_lnurl_pay(req.amount_msat, req.comment, req.data.clone()).await? { ValidatedCallbackResponse::EndpointError { data: e } => { Ok(LnUrlPayResult::EndpointError { data: e }) @@ -303,7 +316,9 @@ impl BreezServices { let payment = self.send_payment(pay_req).await?.payment; let details = match &payment.details { PaymentDetails::ClosedChannel { .. } => { - return Err(anyhow!("Payment lookup found unexpected payment type")); + return Err(LnUrlPayError::Generic { + err: "Payment lookup found unexpected payment type".into(), + }); } PaymentDetails::Ln { data } => data, }; @@ -316,7 +331,11 @@ impl BreezServices { let preimage = sha256::Hash::from_str(&details.payment_preimage)?; let preimage_arr: [u8; 32] = preimage.into_inner(); - let decrypted = (data, &preimage_arr).try_into()?; + let decrypted = (data, &preimage_arr).try_into().map_err( + |e: anyhow::Error| LnUrlPayError::AesDecryptionFailed { + err: e.to_string(), + }, + )?; SuccessActionProcessed::Aes { data: decrypted } } SuccessAction::Message(data) => { @@ -351,7 +370,10 @@ impl BreezServices { /// This call will validate the given `amount_msat` against the parameters /// of the LNURL endpoint (`data`). If they match the endpoint requirements, the LNURL withdraw /// request is made. A successful result here means the endpoint started the payment. - pub async fn lnurl_withdraw(&self, req: LnUrlWithdrawRequest) -> Result { + pub async fn lnurl_withdraw( + &self, + req: LnUrlWithdrawRequest, + ) -> Result { let invoice = self .receive_payment(ReceivePaymentRequest { amount_msat: req.amount_msat, @@ -359,8 +381,7 @@ impl BreezServices { use_description_hash: Some(false), ..Default::default() }) - .await - .map_err(|_| anyhow!("Failed to receive payment"))? + .await? .ln_invoice; let lnurl_w_endpoint = req.data.callback.clone(); @@ -385,8 +406,11 @@ impl BreezServices { /// /// This call will sign `k1` of the LNURL endpoint (`req_data`) on `secp256k1` using `linkingPrivKey` and DER-encodes the signature. /// If they match the endpoint requirements, the LNURL auth request is made. A successful result here means the client signature is verified. - pub async fn lnurl_auth(&self, req_data: LnUrlAuthRequestData) -> Result { - perform_lnurl_auth(self.node_api.clone(), req_data).await + pub async fn lnurl_auth( + &self, + req_data: LnUrlAuthRequestData, + ) -> Result { + Ok(perform_lnurl_auth(self.node_api.clone(), req_data).await?) } /// Creates an bolt11 payment request. @@ -396,7 +420,7 @@ impl BreezServices { pub async fn receive_payment( &self, req: ReceivePaymentRequest, - ) -> SdkResult { + ) -> Result { self.payment_receiver.receive_payment(req).await } @@ -404,23 +428,21 @@ impl BreezServices { /// /// Fail if it could not be retrieved or if `None` was found. pub fn node_info(&self) -> SdkResult { - self.persister - .get_node_state()? - .ok_or(SdkError::PersistenceFailure { - err: "No node info found".into(), - }) + self.persister.get_node_state()?.ok_or(SdkError::Generic { + err: "Node info not found".into(), + }) } /// Sign given message with the private key of the node id. Returns a zbase /// encoded signature. - pub async fn sign_message(&self, req: SignMessageRequest) -> Result { + pub async fn sign_message(&self, req: SignMessageRequest) -> SdkResult { let signature = self.node_api.sign_message(&req.message).await?; Ok(SignMessageResponse { signature }) } /// Check whether given message was signed by the private key or the given /// pubkey and the signature (zbase encoded) is valid. - pub async fn check_message(&self, req: CheckMessageRequest) -> Result { + pub async fn check_message(&self, req: CheckMessageRequest) -> SdkResult { let is_valid = self .node_api .check_message(&req.message, &req.pubkey, &req.signature) @@ -429,7 +451,7 @@ impl BreezServices { } /// Retrieve the node up to date BackupStatus - pub fn backup_status(&self) -> Result { + pub fn backup_status(&self) -> SdkResult { let backup_time = self.persister.get_last_backup_time()?; let sync_request = self.persister.get_last_sync_request()?; Ok(BackupStatus { @@ -439,31 +461,33 @@ impl BreezServices { } /// Force running backup - pub async fn backup(&self) -> Result<()> { + pub async fn backup(&self) -> SdkResult<()> { let (on_complete, mut on_complete_receiver) = mpsc::channel::>(1); let req = BackupRequest::with(on_complete, true); self.backup_watcher.request_backup(req).await?; match on_complete_receiver.recv().await { - Some(res) => res, - None => Err(anyhow!("backup process failed to complete")), + Some(res) => res.map_err(|e| SdkError::Generic { + err: format!("Backup failed: {e}"), + }), + None => Err(SdkError::Generic { + err: "Backup process failed to complete".into(), + }), } } /// List payments matching the given filters, as retrieved from persistent storage pub async fn list_payments(&self, req: ListPaymentsRequest) -> SdkResult> { - self.persister.list_payments(req) + Ok(self.persister.list_payments(req)?) } /// Fetch a specific payment by its hash. - pub async fn payment_by_hash(&self, hash: String) -> Result> { - self.persister - .get_payment_by_hash(&hash) - .map_err(|err| anyhow!(err)) + pub async fn payment_by_hash(&self, hash: String) -> SdkResult> { + Ok(self.persister.get_payment_by_hash(&hash)?) } /// Sweep on-chain funds to the specified on-chain address, with the given feerate - pub async fn sweep(&self, req: SweepRequest) -> Result { + pub async fn sweep(&self, req: SweepRequest) -> SdkResult { self.start_node().await?; let txid = self .node_api @@ -473,28 +497,25 @@ impl BreezServices { Ok(SweepResponse { txid }) } - pub async fn prepare_sweep(&self, req: PrepareSweepRequest) -> Result { + pub async fn prepare_sweep(&self, req: PrepareSweepRequest) -> SdkResult { self.start_node().await?; let response = self.node_api.prepare_sweep(req).await?; Ok(response) } /// Fetch live rates of fiat currencies - pub async fn fetch_fiat_rates(&self) -> Result> { + pub async fn fetch_fiat_rates(&self) -> SdkResult> { self.fiat_api.fetch_fiat_rates().await } /// List all supported fiat currencies for which there is a known exchange rate. - pub async fn list_fiat_currencies(&self) -> Result> { + pub async fn list_fiat_currencies(&self) -> SdkResult> { self.fiat_api.list_fiat_currencies().await } /// List available LSPs that can be selected by the user pub async fn list_lsps(&self) -> SdkResult> { - self.lsp_api - .list_lsps(self.node_info()?.id) - .await - .map_err(|e| SdkError::LspConnectFailed { err: e.to_string() }) + self.lsp_api.list_lsps(self.node_info()?.id).await } /// Select the LSP to be used and provide inbound liquidity @@ -505,7 +526,7 @@ impl BreezServices { self.sync().await?; Ok(()) } - false => Err(SdkError::LspConnectFailed { + false => Err(SdkError::Generic { err: format!("Unknown LSP: {lsp_id}"), }), } @@ -513,12 +534,12 @@ impl BreezServices { /// Get the current LSP's ID pub async fn lsp_id(&self) -> SdkResult> { - self.persister.get_lsp_id() + Ok(self.persister.get_lsp_id()?) } /// Convenience method to look up [LspInformation] for a given LSP ID - pub async fn fetch_lsp_info(&self, id: String) -> Result> { - get_lsp_by_id(self.persister.clone(), self.lsp_api.clone(), id.as_str()).await + pub async fn fetch_lsp_info(&self, id: String) -> SdkResult> { + Ok(get_lsp_by_id(self.persister.clone(), self.lsp_api.clone(), id.as_str()).await?) } /// Gets the fees required to open a channel for a given amount. @@ -530,8 +551,8 @@ impl BreezServices { req: OpenChannelFeeRequest, ) -> SdkResult { // get the node state to fetch the current inbound liquidity. - let node_state = self.persister.get_node_state()?.ok_or(SdkError::NotReady { - err: "Failed to read node state".to_string(), + let node_state = self.persister.get_node_state()?.ok_or(SdkError::Generic { + err: "Node info not found".into(), })?; // In case we have enough inbound liquidity we return zero fee. @@ -557,7 +578,7 @@ impl BreezServices { /// Close all channels with the current LSP. /// /// Should be called when the user wants to close all the channels. - pub async fn close_lsp_channels(&self) -> Result> { + pub async fn close_lsp_channels(&self) -> SdkResult> { self.start_node().await?; let lsp = self.lsp_info().await?; let tx_ids = self.node_api.close_peer_channels(lsp.pubkey).await?; @@ -576,12 +597,15 @@ impl BreezServices { /// /// The returned [SwapInfo] contains the created swap details. The channel opening fees are /// available at [SwapInfo::channel_opening_fees]. - pub async fn receive_onchain(&self, req: ReceiveOnchainRequest) -> Result { + pub async fn receive_onchain( + &self, + req: ReceiveOnchainRequest, + ) -> Result { if let Some(in_progress) = self.in_progress_swap().await? { - return Err(anyhow!(format!( - "Swap in progress was detected for address {}.Use in_progress_swap method to get the current swap state", - in_progress.bitcoin_address - ))); + return Err(ReceiveOnchainError::SwapInProgress{ err:format!( + "A swap was detected for address {}. Use in_progress_swap method to get the current swap state", + in_progress.bitcoin_address + )}); } let channel_opening_fees = match req.opening_fee_params { Some(fee_params) => fee_params, @@ -601,7 +625,7 @@ impl BreezServices { /// Returns an optional in-progress [SwapInfo]. /// A [SwapInfo] is in-progress if it is waiting for confirmation to be redeemed and complete the swap. - pub async fn in_progress_swap(&self) -> Result> { + pub async fn in_progress_swap(&self) -> SdkResult> { let tip = self.chain_service.current_tip().await?; self.btc_receive_swapper.execute_pending_swaps(tip).await?; let in_progress = self.btc_receive_swapper.list_in_progress().await?; @@ -625,13 +649,22 @@ impl BreezServices { pub async fn fetch_reverse_swap_fees( &self, req: ReverseSwapFeesRequest, - ) -> Result { + ) -> SdkResult { let mut res = self.btc_send_swapper.fetch_reverse_swap_fees().await?; if let Some(send_amount_sat) = req.send_amount_sat { - ensure!(send_amount_sat <= res.max, "Send amount is too high"); - ensure!(send_amount_sat >= res.min, "Send amount is too low"); - + ensure_sdk!( + send_amount_sat <= res.max, + SdkError::Generic { + err: "Send amount is too high".into() + } + ); + ensure_sdk!( + send_amount_sat >= res.min, + SdkError::Generic { + err: "Send amount is too low".into() + } + ); let service_fee_sat = ((send_amount_sat as f64) * res.fees_percentage / 100.0) as u64; res.total_estimated_fees = Some(service_fee_sat + res.fees_lockup + res.fees_claim); } @@ -640,11 +673,14 @@ impl BreezServices { } /// Creates a reverse swap and attempts to pay the HODL invoice - pub async fn send_onchain(&self, req: SendOnchainRequest) -> Result { - ensure!(self.in_progress_reverse_swaps().await?.is_empty(), - "There already is at least one Reverse Swap in progress. You can only start a new one after after the ongoing ones finish. \ - Use the in_progress_reverse_swaps method to get an overview of currently ongoing reverse swaps." - ); + pub async fn send_onchain( + &self, + req: SendOnchainRequest, + ) -> Result { + ensure_sdk!(self.in_progress_reverse_swaps().await?.is_empty(), SendOnchainError::ReverseSwapInProgress { err: + "You can only start a new one after after the ongoing ones finish. \ + Use the in_progress_reverse_swaps method to get an overview of currently ongoing reverse swaps".into(), + }); let full_rsi = self.btc_send_swapper.create_reverse_swap(req).await?; let rsi = self @@ -659,7 +695,7 @@ impl BreezServices { } /// Returns the blocking [ReverseSwapInfo]s that are in progress - pub async fn in_progress_reverse_swaps(&self) -> Result> { + pub async fn in_progress_reverse_swaps(&self) -> SdkResult> { let full_rsis = self.btc_send_swapper.list_blocking().await?; let mut rsis = vec![]; @@ -675,8 +711,8 @@ impl BreezServices { } /// list non-completed expired swaps that should be refunded by calling [BreezServices::refund] - pub async fn list_refundables(&self) -> Result> { - self.btc_receive_swapper.list_refundables() + pub async fn list_refundables(&self) -> SdkResult> { + Ok(self.btc_receive_swapper.list_refundables()?) } /// Prepares a refund transaction for a failed/expired swap. @@ -690,14 +726,14 @@ impl BreezServices { /// Construct and broadcast a refund transaction for a failed/expired swap /// /// Returns the txid of the refund transaction. - pub async fn refund(&self, req: RefundRequest) -> Result { - self.btc_receive_swapper.refund_swap(req).await + pub async fn refund(&self, req: RefundRequest) -> SdkResult { + Ok(self.btc_receive_swapper.refund_swap(req).await?) } /// Execute a command directly on the NodeAPI interface. /// Mainly used to debugging. - pub async fn execute_dev_command(&self, command: String) -> Result { - self.node_api.execute_command(command).await + pub async fn execute_dev_command(&self, command: String) -> SdkResult { + Ok(self.node_api.execute_command(command).await?) } /// This method sync the local state with the remote node state. @@ -705,8 +741,8 @@ impl BreezServices { /// * node state - General information about the node and its liquidity status /// * channels - The list of channels and their status /// * payments - The incoming/outgoing payments - pub async fn sync(&self) -> Result<()> { - self.do_sync(false).await + pub async fn sync(&self) -> SdkResult<()> { + Ok(self.do_sync(false).await?) } async fn do_sync(&self, balance_changed: bool) -> Result<()> { @@ -764,7 +800,7 @@ impl BreezServices { } /// Connects to the selected LSP, if any - async fn connect_lsp_peer(&self) -> Result<()> { + async fn connect_lsp_peer(&self) -> SdkResult<()> { if let Ok(lsp_info) = self.lsp_info().await { let node_id = lsp_info.pubkey; let address = lsp_info.host; @@ -776,7 +812,9 @@ impl BreezServices { self.node_api .connect_peer(node_id.clone(), address.clone()) .await - .map_err(anyhow::Error::msg)?; + .map_err(|e| SdkError::ServiceConnectivity { + err: format!("(LSP: {node_id}) Failed to connect: {e}"), + })?; } debug!("connected to lsp {}@{}", node_id.clone(), address.clone()); } @@ -787,8 +825,8 @@ impl BreezServices { &self, node_id: String, invoice: Option, - payment_res: Result, - ) -> SdkResult { + payment_res: Result, + ) -> Result { self.do_sync(payment_res.is_ok()).await?; match payment_res { @@ -798,7 +836,7 @@ impl BreezServices { .await?; Ok(p) } - None => Err(SdkError::SendPaymentFailed { + None => Err(SendPaymentError::Generic { err: "Payment not found".into(), }), }, @@ -811,7 +849,7 @@ impl BreezServices { }, }) .await?; - Err(SdkError::SendPaymentFailed { err: e.to_string() }) + Err(e) } } } @@ -842,17 +880,17 @@ impl BreezServices { } /// Convenience method to look up LSP info based on current LSP ID - pub async fn lsp_info(&self) -> Result { - get_lsp(self.persister.clone(), self.lsp_api.clone()).await + pub async fn lsp_info(&self) -> SdkResult { + Ok(get_lsp(self.persister.clone(), self.lsp_api.clone()).await?) } pub(crate) async fn start_node(&self) -> Result<()> { - self.node_api.start().await + Ok(self.node_api.start().await?) } /// Get the recommended fees for onchain transactions - pub async fn recommended_fees(&self) -> Result { - self.chain_service.recommended_fees().await + pub async fn recommended_fees(&self) -> SdkResult { + Ok(self.chain_service.recommended_fees().await?) } /// Get the full default config for a specific environment type @@ -881,7 +919,10 @@ impl BreezServices { /// /// A user-selected [OpeningFeeParams] can be optionally set in the argument. If set, and the /// operation requires a new channel, the SDK will try to use the given fee params. - pub async fn buy_bitcoin(&self, req: BuyBitcoinRequest) -> SdkResult { + pub async fn buy_bitcoin( + &self, + req: BuyBitcoinRequest, + ) -> Result { let swap_info = self .receive_onchain(ReceiveOnchainRequest { opening_fee_params: req.opening_fee_params, @@ -953,28 +994,22 @@ impl BreezServices { }); } - async fn start_backup_watcher(self: &Arc) -> SdkResult<()> { + async fn start_backup_watcher(self: &Arc) -> Result<()> { self.backup_watcher .start(self.shutdown_receiver.clone()) .await - .map_err(|e| SdkError::InitFailed { - err: format!("Failed to start backup watcher: {e}"), - })?; + .map_err(|e| anyhow!("Failed to start backup watcher: {e}"))?; // Restore backup state and request backup on start if needed let force_backup = self .persister .get_last_sync_version() - .map_err(|e| SdkError::InitFailed { - err: format!("Failed to read last sync version: {e}"), - })? + .map_err(|e| anyhow!("Failed to read last sync version: {e}"))? .is_none(); self.backup_watcher .request_backup(BackupRequest::new(force_backup)) .await - .map_err(|e| SdkError::InitFailed { - err: format!("Failed to request backup: {e}"), - }) + .map_err(|e| anyhow!("Failed to request backup: {e}")) } async fn track_backup_events(self: &Arc) { @@ -1162,15 +1197,13 @@ impl BreezServices { /// An error is thrown if the log file cannot be created in the working directory. /// /// An error is thrown if a global logger is already configured. - pub fn init_logging(log_dir: &str, app_logger: Option>) -> SdkResult<()> { + pub fn init_logging(log_dir: &str, app_logger: Option>) -> Result<()> { let target_log_file = Box::new( OpenOptions::new() .create(true) .append(true) .open(format!("{log_dir}/sdk.log")) - .map_err(|_| SdkError::InitFailed { - err: "Can't create log file".into(), - })?, + .map_err(|e| anyhow!("Can't create log file: {e}"))?, ); let logger = env_logger::Builder::new() .target(env_logger::Target::Pipe(target_log_file)) @@ -1209,9 +1242,8 @@ impl BreezServices { log_listener: app_logger, }; - log::set_boxed_logger(Box::new(global_logger)).map_err(|e| SdkError::InitFailed { - err: format!("Failed to set global logger: {e}"), - })?; + log::set_boxed_logger(Box::new(global_logger)) + .map_err(|e| anyhow!("Failed to set global logger: {e}"))?; log::set_max_level(LevelFilter::Trace); Ok(()) @@ -1429,7 +1461,7 @@ impl BreezServicesBuilder { event_listener: Option>, ) -> SdkResult> { if self.node_api.is_none() && self.seed.is_none() { - return Err(SdkError::InitFailed { + return Err(SdkError::Generic { err: "Either node_api or both credentials and seed should be provided".into(), }); } @@ -1455,8 +1487,8 @@ impl BreezServicesBuilder { persister.clone(), ) .await - .map_err(|e| SdkError::InitFailed { - err: format!("Failed to connect to Greenlight: {e}"), + .map_err(|e| SdkError::ServiceConnectivity { + err: format!("(Greenlight) Failed to connect: {e}"), })?; let gl_arc = Arc::new(greenlight); node_api = Some(gl_arc.clone()); @@ -1466,7 +1498,7 @@ impl BreezServicesBuilder { } if backup_transport.is_none() { - return Err(SdkError::InitFailed { + return Err(SdkError::Generic { err: "State synchronizer should be provided".into(), }); } @@ -1475,33 +1507,17 @@ impl BreezServicesBuilder { let unwrapped_backup_transport = backup_transport.unwrap(); // create the backup encryption key and then the backup watcher - let backup_encryption_key = unwrapped_node_api - .derive_bip32_key(vec![ - ChildNumber::from_hardened_idx(139).map_err(|e| SdkError::InitFailed { - err: format!( - "Failed to get necessary child number to derive backup encryption key: {e}" - ), - })?, - ChildNumber::from(0), - ]) - .map_err(|e| SdkError::InitFailed { - err: format!("Failed to derive backup encryption key: {e}"), - })?; + let backup_encryption_key = unwrapped_node_api.derive_bip32_key(vec![ + ChildNumber::from_hardened_idx(139)?, + ChildNumber::from(0), + ])?; // We calculate the legacy key as a fallback for the case where the backup is still // encrypted with the old key. - let legacy_backup_encryption_key = unwrapped_node_api - .legacy_derive_bip32_key(vec![ - ChildNumber::from_hardened_idx(139).map_err(|e| SdkError::InitFailed { - err: format!( - "Failed to get necessary child number to derive backup encryption key: {e}" - ), - })?, - ChildNumber::from(0), - ]) - .map_err(|e| SdkError::InitFailed { - err: format!("Failed to derive backup encryption key: {e}"), - })?; + let legacy_backup_encryption_key = unwrapped_node_api.legacy_derive_bip32_key(vec![ + ChildNumber::from_hardened_idx(139)?, + ChildNumber::from(0), + ])?; let backup_watcher = BackupWatcher::new( self.config.clone(), unwrapped_backup_transport.clone(), @@ -1598,12 +1614,30 @@ impl BreezServer { pub(crate) async fn get_channel_opener_client( &self, - ) -> Result>> { + ) -> SdkResult>> { let s = self.server_url.clone(); - let channel = Channel::from_shared(s)?.connect().await?; + let channel = Channel::from_shared(s) + .map_err(|e| SdkError::ServiceConnectivity { + err: format!("(Breez: {}) {e}", self.server_url.clone()), + })? + .connect() + .await + .map_err(|e| SdkError::ServiceConnectivity { + err: format!( + "(Breez: {}) Failed to connect: {e}", + self.server_url.clone() + ), + })?; let api_key_metadata: Option> = match &self.api_key { - Some(key) => Some(format!("Bearer {key}").parse()?), + Some(key) => Some(format!("Bearer {key}").parse().map_err( + |e: InvalidMetadataValue| SdkError::ServiceConnectivity { + err: format!( + "(Breez: {}) Failed parse API key: {e}", + self.server_url.clone() + ), + }, + )?), _ => None, }; let client = @@ -1611,32 +1645,32 @@ impl BreezServer { Ok(client) } - pub(crate) async fn get_information_client(&self) -> Result> { - InformationClient::connect(Uri::from_str(&self.server_url)?) - .await - .map_err(|e| anyhow!(e)) + pub(crate) async fn get_information_client(&self) -> SdkResult> { + let url = Uri::from_str(&self.server_url).map_err(|e| SdkError::ServiceConnectivity { + err: format!("(Breez: {}) {e}", self.server_url.clone()), + })?; + Ok(InformationClient::connect(url).await?) } - pub(crate) async fn get_fund_manager_client(&self) -> Result> { - FundManagerClient::connect(Uri::from_str(&self.server_url)?) - .await - .map_err(|e| anyhow!(e)) + pub(crate) async fn get_fund_manager_client(&self) -> SdkResult> { + let url = Uri::from_str(&self.server_url).map_err(|e| SdkError::ServiceConnectivity { + err: format!("(Breez: {}) {e}", self.server_url.clone()), + })?; + Ok(FundManagerClient::connect(url).await?) } - pub(crate) async fn get_signer_client(&self) -> Result> { - Ok(SignerClient::new( - tonic::transport::Endpoint::new(Uri::from_str(&self.server_url)?)? - .connect() - .await?, - )) + pub(crate) async fn get_signer_client(&self) -> SdkResult> { + let url = Uri::from_str(&self.server_url).map_err(|e| SdkError::ServiceConnectivity { + err: format!("(Breez: {}) {e}", self.server_url.clone()), + })?; + Ok(SignerClient::new(Endpoint::new(url)?.connect().await?)) } - pub(crate) async fn get_swapper_client(&self) -> Result> { - Ok(SwapperClient::new( - tonic::transport::Endpoint::new(Uri::from_str(&self.server_url)?)? - .connect() - .await?, - )) + pub(crate) async fn get_swapper_client(&self) -> SdkResult> { + let url = Uri::from_str(&self.server_url).map_err(|e| SdkError::ServiceConnectivity { + err: format!("(Breez: {}) {e}", self.server_url.clone()), + })?; + Ok(SwapperClient::new(Endpoint::new(url)?.connect().await?)) } } @@ -1668,7 +1702,7 @@ pub trait Receiver: Send + Sync { async fn receive_payment( &self, req: ReceivePaymentRequest, - ) -> SdkResult; + ) -> Result; } pub(crate) struct PaymentReceiver { @@ -1683,19 +1717,18 @@ impl Receiver for PaymentReceiver { async fn receive_payment( &self, req: ReceivePaymentRequest, - ) -> SdkResult { + ) -> Result { self.node_api.start().await?; let lsp_info = get_lsp(self.persister.clone(), self.lsp.clone()).await?; let node_state = self .persister .get_node_state()? - .ok_or("Failed to retrieve node state") - .map_err(|err| anyhow!(err))?; + .ok_or(anyhow!("Node info not found"))?; let expiry = req.expiry.unwrap_or(INVOICE_PAYMENT_FEE_EXPIRY_SECONDS); ensure_sdk!( req.amount_msat > 0, - SdkError::ReceivePaymentFailed { + ReceivePaymentError::InvalidAmount { err: "Receive amount must be more than 0".into() } ); @@ -1724,12 +1757,12 @@ impl Receiver for PaymentReceiver { ofp.proportional, ofp.min_msat, channel_fees_msat); if req.amount_msat < channel_fees_msat + 1000 { - return Err(SdkError::ReceivePaymentFailed { - err: format!( - "requestPayment: Amount should be more than the minimum fees {channel_fees_msat} msat, but is {} msat", + return Err( + ReceivePaymentError::InvalidAmount{err: format!( + "Amount should be more than the minimum fees {channel_fees_msat} msat, but is {} msat", req.amount_msat - ), - }); + )} + ); } // remove the fees from the amount to get the small amount on the current node invoice. destination_invoice_amount_msat = req.amount_msat - channel_fees_msat; @@ -1743,9 +1776,7 @@ impl Receiver for PaymentReceiver { .channels .iter() .find(|&c| c.state == ChannelState::Opened) - .ok_or_else(|| SdkError::ReceivePaymentFailed { - err: "No open channel found".into(), - })?; + .ok_or_else(|| anyhow!("No open channel found"))?; let hint = active_channel .clone() .alias_remote @@ -1821,7 +1852,7 @@ impl Receiver for PaymentReceiver { info!("Registering payment with LSP"); if channel_opening_fee_params.is_none() { - return Err(SdkError::ReceivePaymentFailed { + return Err(ReceivePaymentError::Generic { err: "We need to open a channel, but no channel opening fee params found" .into(), }); @@ -1835,17 +1866,11 @@ impl Receiver for PaymentReceiver { lsp_info.id.clone(), lsp_info.lsp_pubkey.clone(), PaymentInformation { - payment_hash: hex::decode(parsed_invoice.payment_hash.clone()).map_err( - |e| SdkError::ReceivePaymentFailed { - err: format!("Failed to decode hex payment hash: {e}"), - }, - )?, + payment_hash: hex::decode(parsed_invoice.payment_hash.clone()) + .map_err(|e| anyhow!("Failed to decode hex payment hash: {e}"))?, payment_secret: parsed_invoice.payment_secret.clone(), - destination: hex::decode(parsed_invoice.payee_pubkey.clone()).map_err( - |e| SdkError::ReceivePaymentFailed { - err: format!("Failed to decode hex payee pubkey: {e}"), - }, - )?, + destination: hex::decode(parsed_invoice.payee_pubkey.clone()) + .map_err(|e| anyhow!("Failed to decode hex payee pubkey: {e}"))?, incoming_amount_msat: req.amount_msat as i64, outgoing_amount_msat: destination_invoice_amount_msat as i64, tag: json!({ "apiKeyHash": api_key_hash }).to_string(), @@ -1870,14 +1895,11 @@ impl Receiver for PaymentReceiver { /// Convenience method to look up LSP info based on current LSP ID async fn get_lsp(persister: Arc, lsp: Arc) -> Result { - let lsp_id = persister - .get_lsp_id()? - .ok_or("No LSP ID found") - .map_err(|err| anyhow!(err))?; + let lsp_id = persister.get_lsp_id()?.ok_or(anyhow!("No LSP ID found"))?; get_lsp_by_id(persister, lsp, lsp_id.as_str()) .await? - .ok_or_else(|| anyhow!("No LSP found for id {}", lsp_id)) + .ok_or_else(|| anyhow!("No LSP found for id {lsp_id}")) } async fn get_lsp_by_id( @@ -1887,8 +1909,7 @@ async fn get_lsp_by_id( ) -> Result> { let node_pubkey = persister .get_node_state()? - .ok_or("No NodeState found") - .map_err(|err| anyhow!(err))? + .ok_or(anyhow!("Node info not found"))? .id; Ok(lsp @@ -1904,26 +1925,26 @@ pub(crate) mod tests { use std::collections::HashMap; use std::sync::Arc; - use anyhow::Result; + use anyhow::{anyhow, Result}; use regex::Regex; use reqwest::Url; use crate::breez_services::{BreezServices, BreezServicesBuilder}; - use crate::error::{SdkError, SdkResult}; use crate::fiat::Rate; use crate::lnurl::pay::model::MessageSuccessActionData; use crate::lnurl::pay::model::SuccessActionProcessed; use crate::models::{LnPaymentDetails, NodeState, Payment, PaymentDetails, PaymentTypeFilter}; + use crate::node_api::NodeAPI; + use crate::PaymentType; use crate::{ input_parser, parse_short_channel_id, test_utils::*, BuyBitcoinProvider, BuyBitcoinRequest, InputType, ListPaymentsRequest, PaymentStatus, ReceivePaymentRequest, }; - use crate::{NodeAPI, PaymentType}; use super::{PaymentReceiver, Receiver}; #[tokio::test] - async fn test_node_state() -> SdkResult<()> { + async fn test_node_state() -> Result<()> { // let storage_path = format!("{}/storage.sql", get_test_working_dir()); // std::fs::remove_file(storage_path).ok(); @@ -2090,7 +2111,7 @@ pub(crate) mod tests { } #[tokio::test] - async fn test_receive_with_open_channel() -> SdkResult<()> { + async fn test_receive_with_open_channel() -> Result<()> { let config = create_test_config(); let persister = Arc::new(create_test_persister(config.clone())); persister.init().unwrap(); @@ -2129,13 +2150,13 @@ pub(crate) mod tests { } #[tokio::test] - async fn test_list_lsps() -> SdkResult<()> { + async fn test_list_lsps() -> Result<()> { let storage_path = format!("{}/storage.sql", get_test_working_dir()); std::fs::remove_file(storage_path).ok(); - let breez_services = breez_services().await.map_err(|e| SdkError::InitFailed { - err: format!("Failed to get the BreezServices: {e}"), - })?; + let breez_services = breez_services() + .await + .map_err(|e| anyhow!("Failed to get the BreezServices: {e}"))?; breez_services.sync().await?; let node_pubkey = breez_services.node_info()?.id; diff --git a/libs/sdk-core/src/chain.rs b/libs/sdk-core/src/chain.rs index 2d176230e..757bccd29 100644 --- a/libs/sdk-core/src/chain.rs +++ b/libs/sdk-core/src/chain.rs @@ -1,5 +1,5 @@ use crate::input_parser::get_parse_and_log_response; -use anyhow::Result; +use anyhow::{anyhow, Result}; use bitcoin::hashes::hex::FromHex; use bitcoin::{OutPoint, Txid}; use serde::{Deserialize, Serialize}; @@ -244,10 +244,9 @@ impl ChainService for MempoolSpace { .send() .await? .text() - .await - .map_err(anyhow::Error::msg)?; + .await?; match txid_or_error.contains("error") { - true => Err(anyhow::Error::msg(txid_or_error)), + true => Err(anyhow!("Error fetching tx: {txid_or_error}")), false => Ok(txid_or_error), } } diff --git a/libs/sdk-core/src/crypt.rs b/libs/sdk-core/src/crypt.rs index c9b1b213f..af3c9ac29 100644 --- a/libs/sdk-core/src/crypt.rs +++ b/libs/sdk-core/src/crypt.rs @@ -1,9 +1,9 @@ -use anyhow::{anyhow, Result}; +use anyhow::Result; pub fn encrypt(key: Vec, msg: Vec) -> Result> { match ecies::encrypt(key.as_slice(), msg.as_slice()) { Ok(res) => Ok(res), - Err(err) => Err(anyhow!(err)), + Err(err) => Err(err.into()), } } @@ -11,6 +11,6 @@ pub fn encrypt(key: Vec, msg: Vec) -> Result> { pub fn decrypt(key: Vec, msg: Vec) -> Result> { match ecies::decrypt(key.as_slice(), msg.as_slice()) { Ok(res) => Ok(res), - Err(err) => Err(anyhow!(err)), + Err(err) => Err(err.into()), } } diff --git a/libs/sdk-core/src/error.rs b/libs/sdk-core/src/error.rs index 3620330d6..7d8ab2670 100644 --- a/libs/sdk-core/src/error.rs +++ b/libs/sdk-core/src/error.rs @@ -1,60 +1,654 @@ +use anyhow::Result; +use bitcoin::util::bip32; use thiserror::Error; +use crate::{ + invoice::InvoiceError, lnurl::error::LnUrlError, node_api::NodeError, + persist::error::PersistError, swap_in::error::SwapError, swap_out::error::ReverseSwapError, +}; + pub type SdkResult = Result; -/// Type of error returned by the SDK +/// Error returned by [BreezServices::lnurl_auth] #[derive(Debug, Error)] -pub enum SdkError { - /// Generic error, that doesn't fit any of the other types - #[error("Breez SDK error: {err}")] +pub enum LnUrlAuthError { + #[error("Generic: {err}")] + Generic { err: String }, + + #[error("Invalid uri: {err}")] + InvalidUri { err: String }, + + #[error("Service connectivity: {err}")] + ServiceConnectivity { err: String }, +} + +impl From for LnUrlAuthError { + fn from(value: LnUrlError) -> Self { + match value { + LnUrlError::InvalidUri(err) => Self::InvalidUri { + err: err.to_string(), + }, + LnUrlError::ServiceConnectivity(err) => Self::ServiceConnectivity { + err: err.to_string(), + }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +impl From for LnUrlAuthError { + fn from(value: SdkError) -> Self { + match value { + SdkError::ServiceConnectivity { err } => Self::ServiceConnectivity { err }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +/// Error returned by [BreezServices::lnurl_pay] +#[derive(Debug, Error)] +pub enum LnUrlPayError { + #[error("Aes decryption failed: {err}")] + AesDecryptionFailed { err: String }, + + #[error("Invoice already paid")] + AlreadyPaid, + + #[error("Generic: {err}")] + Generic { err: String }, + + #[error("Invalid amount: {err}")] + InvalidAmount { err: String }, + + #[error("Invalid invoice: {err}")] + InvalidInvoice { err: String }, + + #[error("Invalid uri: {err}")] + InvalidUri { err: String }, + + #[error("Invoice expired: {err}")] + InvoiceExpired { err: String }, + + #[error("Payment failed: {err}")] + PaymentFailed { err: String }, + + #[error("Payment timeout: {err}")] + PaymentTimeout { err: String }, + + #[error("Route not found: {err}")] + RouteNotFound { err: String }, + + #[error("Route too expensive: {err}")] + RouteTooExpensive { err: String }, + + #[error("Service connectivity: {err}")] + ServiceConnectivity { err: String }, +} + +impl From for LnUrlPayError { + fn from(err: anyhow::Error) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} + +impl From for LnUrlPayError { + fn from(err: bitcoin::hashes::hex::Error) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} + +impl From for LnUrlPayError { + fn from(value: LnUrlError) -> Self { + match value { + LnUrlError::InvalidUri(err) => Self::InvalidUri { + err: err.to_string(), + }, + LnUrlError::InvalidInvoice(err) => Self::InvalidInvoice { + err: err.to_string(), + }, + LnUrlError::ServiceConnectivity(err) => Self::ServiceConnectivity { + err: err.to_string(), + }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +impl From for LnUrlPayError { + fn from(err: PersistError) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} + +impl From for LnUrlPayError { + fn from(value: SdkError) -> Self { + match value { + SdkError::ServiceConnectivity { err } => Self::ServiceConnectivity { err }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +impl From for LnUrlPayError { + fn from(value: SendPaymentError) -> Self { + match value { + SendPaymentError::AlreadyPaid => Self::AlreadyPaid, + SendPaymentError::InvalidAmount { err } => Self::InvalidAmount { err }, + SendPaymentError::InvalidInvoice { err } => Self::InvalidInvoice { err }, + SendPaymentError::InvoiceExpired { err } => Self::InvoiceExpired { err }, + SendPaymentError::PaymentFailed { err } => Self::PaymentFailed { err }, + SendPaymentError::PaymentTimeout { err } => Self::PaymentTimeout { err }, + SendPaymentError::RouteNotFound { err } => Self::RouteNotFound { err }, + SendPaymentError::RouteTooExpensive { err } => Self::RouteTooExpensive { err }, + SendPaymentError::ServiceConnectivity { err } => Self::ServiceConnectivity { err }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +/// Error returned by [BreezServices::lnurl_withdraw] +#[derive(Debug, Error)] +pub enum LnUrlWithdrawError { + #[error("Generic: {err}")] Generic { err: String }, - #[error("Failed to initialize the SDK: {err}")] - InitFailed { err: String }, + #[error("Invalid amount: {err}")] + InvalidAmount { err: String }, - #[error("SDK is not ready: {err}")] - NotReady { err: String }, + #[error("Invalid invoice: {err}")] + InvalidInvoice { err: String }, - #[error("Failed to communicate with the LSP API: {err}")] - LspConnectFailed { err: String }, + #[error("Invalid uri: {err}")] + InvalidUri { err: String }, - #[error("LSP doesn't support opening a new channel: {err}")] - LspOpenChannelNotSupported { err: String }, + #[error("Service connectivity: {err}")] + ServiceConnectivity { err: String }, +} + +impl From for LnUrlWithdrawError { + fn from(value: LnUrlError) -> Self { + match value { + LnUrlError::InvalidUri(err) => Self::InvalidUri { + err: err.to_string(), + }, + LnUrlError::InvalidInvoice(err) => Self::InvalidInvoice { + err: err.to_string(), + }, + LnUrlError::ServiceConnectivity(err) => Self::ServiceConnectivity { + err: err.to_string(), + }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +impl From for LnUrlWithdrawError { + fn from(err: PersistError) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} + +impl From for LnUrlWithdrawError { + fn from(value: ReceivePaymentError) -> Self { + match value { + ReceivePaymentError::InvalidAmount { err } => Self::InvalidAmount { err }, + ReceivePaymentError::InvalidInvoice { err } => Self::InvalidInvoice { err }, + ReceivePaymentError::ServiceConnectivity { err } => Self::ServiceConnectivity { err }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +impl From for LnUrlWithdrawError { + fn from(value: SdkError) -> Self { + match value { + SdkError::ServiceConnectivity { err } => Self::ServiceConnectivity { err }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +/// Error returned by [BreezServices::receive_onchain] and [BreezServices::buy_bitcoin] +#[derive(Debug, Error)] +pub enum ReceiveOnchainError { + #[error("Generic: {err}")] + Generic { err: String }, + + #[error("Service connectivity: {err}")] + ServiceConnectivity { err: String }, + + #[error("Swap in progress: {err}")] + SwapInProgress { err: String }, +} + +impl From for ReceiveOnchainError { + fn from(err: anyhow::Error) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} - #[error("Failed to calculate channel opening fee: {err}")] - CalculateOpenChannelFeesFailed { err: String }, +impl From for ReceiveOnchainError { + fn from(value: SdkError) -> Self { + match value { + SdkError::ServiceConnectivity { err } => Self::ServiceConnectivity { err }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} - #[error("Failed to use the local DB for persistence: {err}")] - PersistenceFailure { err: String }, +impl From for ReceiveOnchainError { + fn from(value: SwapError) -> Self { + match value { + SwapError::ServiceConnectivity(err) => Self::ServiceConnectivity { + err: err.to_string(), + }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} - #[error("Failed to receive payment: {err}")] - ReceivePaymentFailed { err: String }, +/// Error returned by [BreezServices::receive_payment] +#[derive(Debug, Error)] +pub enum ReceivePaymentError { + #[error("Generic: {err}")] + Generic { err: String }, - #[error("Failed to send payment: {err}")] - SendPaymentFailed { err: String }, + #[error("Invalid amount: {err}")] + InvalidAmount { err: String }, + + #[error("Invalid invoice: {err}")] + InvalidInvoice { err: String }, + + #[error("Invoice expired: {err}")] + InvoiceExpired { err: String }, + + #[error("Invoice no description: {err}")] + InvoiceNoDescription { err: String }, + + #[error("Invoice preimage already exists: {err}")] + InvoicePreimageAlreadyExists { err: String }, + + #[error("Service connectivity: {err}")] + ServiceConnectivity { err: String }, } -impl From for SdkError { - fn from(value: rusqlite::Error) -> Self { - Self::PersistenceFailure { - err: value.to_string(), +impl From for ReceivePaymentError { + fn from(err: anyhow::Error) -> Self { + Self::Generic { + err: err.to_string(), } } } -impl From for SdkError { - fn from(value: rusqlite_migration::Error) -> Self { - Self::PersistenceFailure { - err: value.to_string(), +impl From for ReceivePaymentError { + fn from(err: InvoiceError) -> Self { + Self::InvalidInvoice { + err: err.to_string(), } } } -// TODO This won't be necessary when all service methods return SdkResult +impl From for ReceivePaymentError { + fn from(value: NodeError) -> Self { + match value { + NodeError::InvoiceExpired(err) => Self::InvoiceExpired { + err: err.to_string(), + }, + NodeError::InvoiceNoDescription(err) => Self::InvoiceNoDescription { + err: err.to_string(), + }, + NodeError::InvoicePreimageAlreadyExists(err) => Self::InvoicePreimageAlreadyExists { + err: err.to_string(), + }, + NodeError::ServiceConnectivity(err) => Self::ServiceConnectivity { + err: err.to_string(), + }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +impl From for ReceivePaymentError { + fn from(err: PersistError) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} + +impl From for ReceivePaymentError { + fn from(value: SdkError) -> Self { + match value { + SdkError::ServiceConnectivity { err } => Self::ServiceConnectivity { err }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +/// General error returned by the SDK +#[derive(Debug, Error)] +pub enum SdkError { + #[error("Generic: {err}")] + Generic { err: String }, + + #[error("Service connectivity: {err}")] + ServiceConnectivity { err: String }, +} + impl From for SdkError { - fn from(value: anyhow::Error) -> Self { + fn from(err: anyhow::Error) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} + +impl From for SdkError { + fn from(err: bitcoin::hashes::hex::Error) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} + +impl From for SdkError { + fn from(err: bip32::Error) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} + +impl From for SdkError { + fn from(err: InvoiceError) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} + +impl From for SdkError { + fn from(err: LnUrlError) -> Self { + SdkError::Generic { + err: err.to_string(), + } + } +} + +impl From for SdkError { + fn from(value: NodeError) -> Self { + match value { + NodeError::ServiceConnectivity(err) => Self::ServiceConnectivity { + err: err.to_string(), + }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +impl From for SdkError { + fn from(err: PersistError) -> Self { Self::Generic { - err: value.to_string(), + err: err.to_string(), + } + } +} + +impl From for SdkError { + fn from(value: ReverseSwapError) -> Self { + match value { + ReverseSwapError::ServiceConnectivity(err) => Self::ServiceConnectivity { + err: err.to_string(), + }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +impl From for SdkError { + fn from(err: serde_json::Error) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} + +impl From for SdkError { + fn from(err: tonic::transport::Error) -> Self { + Self::ServiceConnectivity { + err: err.to_string(), + } + } +} + +impl From for SdkError { + fn from(err: tonic::Status) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} + +impl From for SdkError { + fn from(value: SendPaymentError) -> Self { + match value { + SendPaymentError::Generic { err } => Self::Generic { err }, + SendPaymentError::ServiceConnectivity { err } => Self::ServiceConnectivity { err }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +/// Error returned by [BreezServices::send_onchain] +#[derive(Debug, Error)] +pub enum SendOnchainError { + #[error("Generic: {err}")] + Generic { err: String }, + + #[error("Invalid destination address: {err}")] + InvalidDestinationAddress { err: String }, + + #[error("Payment failed: {err}")] + PaymentFailed { err: String }, + + #[error("Payment timeout: {err}")] + PaymentTimeout { err: String }, + + #[error("Reverse swap in progress: {err}")] + ReverseSwapInProgress { err: String }, + + #[error("Service connectivity: {err}")] + ServiceConnectivity { err: String }, +} + +impl From for SendOnchainError { + fn from(err: anyhow::Error) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} + +impl From for SendOnchainError { + fn from(value: NodeError) -> Self { + match value { + NodeError::PaymentFailed(err) => Self::PaymentFailed { + err: err.to_string(), + }, + NodeError::PaymentTimeout(err) => Self::PaymentTimeout { + err: err.to_string(), + }, + NodeError::ServiceConnectivity(err) => Self::ServiceConnectivity { + err: err.to_string(), + }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +impl From for SendOnchainError { + fn from(value: SdkError) -> Self { + match value { + SdkError::ServiceConnectivity { err } => Self::ServiceConnectivity { err }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +impl From for SendOnchainError { + fn from(value: ReverseSwapError) -> Self { + match value { + ReverseSwapError::InvalidDestinationAddress(err) => Self::InvalidDestinationAddress { + err: err.to_string(), + }, + ReverseSwapError::ServiceConnectivity(err) => Self::ServiceConnectivity { + err: err.to_string(), + }, + ReverseSwapError::Node(err) => err.into(), + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +/// Error returned by [BreezServices::send_payment] and [BreezServices::send_spontaneous_payment] +#[derive(Debug, Error)] +pub enum SendPaymentError { + #[error("Invoice already paid")] + AlreadyPaid, + + #[error("Generic: {err}")] + Generic { err: String }, + + #[error("Invalid amount: {err}")] + InvalidAmount { err: String }, + + #[error("Invalid invoice: {err}")] + InvalidInvoice { err: String }, + + #[error("Invoice expired: {err}")] + InvoiceExpired { err: String }, + + #[error("Payment failed: {err}")] + PaymentFailed { err: String }, + + #[error("Payment timeout: {err}")] + PaymentTimeout { err: String }, + + #[error("Route not found: {err}")] + RouteNotFound { err: String }, + + #[error("Route too expensive: {err}")] + RouteTooExpensive { err: String }, + + #[error("Service connectivity: {err}")] + ServiceConnectivity { err: String }, +} + +impl From for SendPaymentError { + fn from(err: anyhow::Error) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} + +impl From for SendPaymentError { + fn from(err: InvoiceError) -> Self { + Self::InvalidInvoice { + err: err.to_string(), + } + } +} + +impl From for SendPaymentError { + fn from(value: NodeError) -> Self { + match value { + NodeError::InvoiceExpired(err) => Self::InvoiceExpired { + err: err.to_string(), + }, + NodeError::PaymentFailed(err) => Self::PaymentFailed { + err: err.to_string(), + }, + NodeError::PaymentTimeout(err) => Self::PaymentTimeout { + err: err.to_string(), + }, + NodeError::RouteNotFound(err) => Self::RouteNotFound { + err: err.to_string(), + }, + NodeError::RouteTooExpensive(err) => Self::RouteTooExpensive { + err: err.to_string(), + }, + NodeError::ServiceConnectivity(err) => Self::ServiceConnectivity { + err: err.to_string(), + }, + _ => Self::Generic { + err: value.to_string(), + }, + } + } +} + +impl From for SendPaymentError { + fn from(err: PersistError) -> Self { + Self::Generic { + err: err.to_string(), + } + } +} + +impl From for SendPaymentError { + fn from(value: SdkError) -> Self { + match value { + SdkError::ServiceConnectivity { err } => Self::ServiceConnectivity { err }, + _ => Self::Generic { + err: value.to_string(), + }, } } } diff --git a/libs/sdk-core/src/fiat.rs b/libs/sdk-core/src/fiat.rs index 387274605..0402d808c 100644 --- a/libs/sdk-core/src/fiat.rs +++ b/libs/sdk-core/src/fiat.rs @@ -1,9 +1,9 @@ use std::collections::HashMap; -use crate::breez_services::BreezServer; +use crate::error::SdkResult; use crate::grpc::RatesRequest; use crate::models::FiatAPI; -use anyhow::Result; +use crate::{breez_services::BreezServer, error::SdkError}; use serde::{Deserialize, Serialize}; use tonic::Request; @@ -64,7 +64,7 @@ fn convert_to_fiat_currency_with_id(id: String, info: CurrencyInfo) -> FiatCurre #[tonic::async_trait] impl FiatAPI for BreezServer { - async fn list_fiat_currencies(&self) -> Result> { + async fn list_fiat_currencies(&self) -> SdkResult> { let known_rates = self.fetch_fiat_rates().await?; let known_rates_currencies = known_rates .iter() @@ -82,11 +82,16 @@ impl FiatAPI for BreezServer { Ok(fiat_currency_list) } - async fn fetch_fiat_rates(&self) -> Result> { + async fn fetch_fiat_rates(&self) -> SdkResult> { let mut client = self.get_information_client().await?; let request = Request::new(RatesRequest {}); - let response = client.rates(request).await?; + let response = client + .rates(request) + .await + .map_err(|e| SdkError::ServiceConnectivity { + err: format!("Fetch rates request failed: {e}"), + })?; Ok(response .into_inner() .rates diff --git a/libs/sdk-core/src/greenlight/backup_transport.rs b/libs/sdk-core/src/greenlight/backup_transport.rs index bcfc847e2..08d92ca83 100644 --- a/libs/sdk-core/src/greenlight/backup_transport.rs +++ b/libs/sdk-core/src/greenlight/backup_transport.rs @@ -1,7 +1,9 @@ -use crate::backup::{BackupState, BackupTransport}; +use crate::{ + backup::{BackupState, BackupTransport}, + error::{SdkError, SdkResult}, +}; use super::node_api::Greenlight; -use anyhow::{anyhow, Result}; use gl_client::{node, pb}; use std::sync::Arc; @@ -16,9 +18,10 @@ impl GLBackupTransport { BREEZ_SDK_DATASTORE_PATH.map(|s| s.into()).to_vec() } } + #[tonic::async_trait] impl BackupTransport for GLBackupTransport { - async fn pull(&self) -> Result> { + async fn pull(&self) -> SdkResult> { let key = self.gl_key(); let mut c: node::ClnClient = self.inner.get_node_client().await?; let response: pb::cln::ListdatastoreResponse = c @@ -32,11 +35,13 @@ impl BackupTransport for GLBackupTransport { generation: store[0].generation.unwrap(), data: store[0].clone().hex.unwrap(), })), - _ => Err(anyhow!("get returned multiple values")), + _ => Err(SdkError::Generic { + err: "Get returned multiple values".into(), + }), } } - async fn push(&self, version: Option, hex: Vec) -> Result { + async fn push(&self, version: Option, hex: Vec) -> SdkResult { let key = self.gl_key(); info!("set_value key = {:?} data length={:?}", key, hex.len()); let mut c: node::ClnClient = self.inner.get_node_client().await?; diff --git a/libs/sdk-core/src/greenlight/error.rs b/libs/sdk-core/src/greenlight/error.rs new file mode 100644 index 000000000..9a1764a59 --- /dev/null +++ b/libs/sdk-core/src/greenlight/error.rs @@ -0,0 +1,213 @@ +use std::{num::TryFromIntError, time::SystemTimeError}; + +use anyhow::{anyhow, Result}; +use bitcoin::secp256k1; +use regex::Regex; +use strum_macros::FromRepr; + +use crate::{invoice::InvoiceError, node_api::NodeError, persist::error::PersistError}; + +#[derive(FromRepr, Debug, PartialEq)] +#[repr(i16)] +pub(crate) enum JsonRpcErrCode { + /* Errors from `pay`, `sendpay`, or `waitsendpay` commands */ + PayInProgress = 200, + PayRhashAlreadyUsed = 201, + PayUnparseableOnion = 202, + PayDestinationPermFail = 203, + PayTryOtherRoute = 204, + PayRouteNotFound = 205, + PayRouteTooExpensive = 206, + PayInvoiceExpired = 207, + PayNoSuchPayment = 208, + PayUnspecifiedError = 209, + PayStoppedRetrying = 210, + PayStatusUnexpected = 211, + PayInvoiceRequestInvalid = 212, + PayInvoicePreapprovalDeclined = 213, + PayKeysendPreapprovalDeclined = 214, + + /* `fundchannel` or `withdraw` errors */ + FundMaxExceeded = 300, + FundCannotAfford = 301, + FundOutputIsDust = 302, + FundingBroadcastFail = 303, + FundingStillSyncingBitcoin = 304, + FundingPeerNotConnected = 305, + FundingUnknownPeer = 306, + FundingNothingToCancel = 307, + FundingCancelNotSafe = 308, + FundingPsbtInvalid = 309, + FundingV2NotSupported = 310, + FundingUnknownChannel = 311, + FundingStateInvalid = 312, + FundCannotAffordWithEmergency = 313, + + /* Splice errors */ + SpliceBroadcastFail = 350, + SpliceWrongOwner = 351, + SpliceUnknownChannel = 352, + SpliceInvalidChannelState = 353, + SpliceNotSupported = 354, + SpliceBusyError = 355, + SpliceInputError = 356, + SpliceFundingLow = 357, + SpliceStateError = 358, + SpliceLowFee = 359, + SpliceHighFee = 360, + + /* `connect` errors */ + ConnectNoKnownAddress = 400, + ConnectAllAddressesFailed = 401, + ConnectDisconnectedDuring = 402, + + /* bitcoin-cli plugin errors */ + BcliError = 500, + BcliNoFeeEstimates = 501, + + /* Errors from `invoice` or `delinvoice` commands */ + InvoiceLabelAlreadyExists = 900, + InvoicePreimageAlreadyExists = 901, + InvoiceHintsGaveNoRoutes = 902, + InvoiceExpiredDuringWait = 903, + InvoiceWaitTimedOut = 904, + InvoiceNotFound = 905, + InvoiceStatusUnexpected = 906, + InvoiceOfferInactive = 907, + InvoiceNoDescription = 908, + + /* Errors from HSM crypto operations. */ + HsmEcdhFailed = 800, + + /* Errors from `offer` commands */ + OfferAlreadyExists = 1000, + OfferAlreadyDisabled = 1001, + OfferExpired = 1002, + OfferRouteNotFound = 1003, + OfferBadInvreqReply = 1004, + OfferTimeout = 1005, + + /* Errors from datastore command */ + DatastoreDelDoesNotExist = 1200, + DatastoreDelWrongGeneration = 1201, + DatastoreUpdateAlreadyExists = 1202, + DatastoreUpdateDoesNotExist = 1203, + DatastoreUpdateWrongGeneration = 1204, + DatastoreUpdateHasChildren = 1205, + DatastoreUpdateNoChildren = 1206, + + /* Errors from signmessage command */ + SignmessagePubkeyNotFound = 1301, + + /* Errors from delforward command */ + DelforwardNotFound = 1401, + + /* Errors from runes */ + RuneNotAuthorized = 1501, + RuneNotPermitted = 1502, + RuneBlacklisted = 1503, + + /* Errors from wait* commands */ + WaitTimeout = 2000, +} + +impl From for NodeError { + fn from(err: anyhow::Error) -> Self { + Self::Generic(err) + } +} + +impl From for NodeError { + fn from(err: bitcoin::util::address::Error) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +impl From for NodeError { + fn from(err: bitcoin::util::bip32::Error) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +impl From for NodeError { + fn from(err: hex::FromHexError) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +impl From for NodeError { + fn from(err: InvoiceError) -> Self { + Self::InvalidInvoice(err) + } +} + +impl From for NodeError { + fn from(err: PersistError) -> Self { + Self::Persistance(err) + } +} + +impl From for NodeError { + fn from(err: secp256k1::Error) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +impl From for NodeError { + fn from(err: SystemTimeError) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +impl From for NodeError { + fn from(status: tonic::Status) -> Self { + match parse_cln_error(status.clone()) { + Ok(code) => match code { + // Pay errors + JsonRpcErrCode::PayInvoiceExpired => Self::InvoiceExpired(status.into()), + JsonRpcErrCode::PayTryOtherRoute | JsonRpcErrCode::PayRouteNotFound => { + Self::RouteNotFound(status.into()) + } + JsonRpcErrCode::PayRouteTooExpensive => Self::RouteTooExpensive(status.into()), + JsonRpcErrCode::PayStoppedRetrying => Self::PaymentTimeout(status.into()), + JsonRpcErrCode::PayRhashAlreadyUsed + | JsonRpcErrCode::PayUnparseableOnion + | JsonRpcErrCode::PayDestinationPermFail + | JsonRpcErrCode::PayNoSuchPayment + | JsonRpcErrCode::PayUnspecifiedError + | JsonRpcErrCode::PayStatusUnexpected + | JsonRpcErrCode::PayInvoiceRequestInvalid + | JsonRpcErrCode::PayInvoicePreapprovalDeclined + | JsonRpcErrCode::PayKeysendPreapprovalDeclined => { + Self::PaymentFailed(status.into()) + } + // Invoice errors + JsonRpcErrCode::InvoiceExpiredDuringWait => Self::InvoiceExpired(status.into()), + JsonRpcErrCode::InvoiceNoDescription => Self::InvoiceNoDescription(status.into()), + JsonRpcErrCode::InvoicePreimageAlreadyExists => { + Self::InvoicePreimageAlreadyExists(status.into()) + } + _ => Self::Generic(status.into()), + }, + _ => Self::Generic(status.into()), + } + } +} + +impl From for NodeError { + fn from(err: TryFromIntError) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +#[allow(clippy::invalid_regex)] +pub(crate) fn parse_cln_error(status: tonic::Status) -> Result { + let re: Regex = Regex::new(r"Some\((?-?\d+)\)")?; + re.captures(status.message()) + .and_then(|caps| { + caps["code"] + .parse::() + .map_or(None, JsonRpcErrCode::from_repr) + }) + .ok_or(anyhow!("No code found")) +} diff --git a/libs/sdk-core/src/greenlight/mod.rs b/libs/sdk-core/src/greenlight/mod.rs index 2154a99b7..1b2095366 100644 --- a/libs/sdk-core/src/greenlight/mod.rs +++ b/libs/sdk-core/src/greenlight/mod.rs @@ -1,4 +1,5 @@ mod backup_transport; +pub(crate) mod error; mod node_api; pub(crate) use backup_transport::GLBackupTransport; pub(crate) use node_api::Greenlight; diff --git a/libs/sdk-core/src/greenlight/node_api.rs b/libs/sdk-core/src/greenlight/node_api.rs index f86d415d9..7860df49c 100644 --- a/libs/sdk-core/src/greenlight/node_api.rs +++ b/libs/sdk-core/src/greenlight/node_api.rs @@ -39,8 +39,9 @@ use tokio::time::sleep; use tokio_stream::{Stream, StreamExt}; use tonic::Streaming; -use crate::invoice::parse_invoice; +use crate::invoice::{parse_invoice, InvoiceError}; use crate::models::*; +use crate::node_api::{NodeAPI, NodeError, NodeResult}; use crate::persist::db::SqliteStorage; use crate::{Channel, ChannelState, NodeConfig, PrepareSweepRequest, PrepareSweepResponse}; use std::iter::Iterator; @@ -187,20 +188,22 @@ impl Greenlight { network: Network, signer: &Signer, path: Vec, - ) -> Result { - ExtendedPrivKey::new_master(network.into(), &signer.bip32_ext_key())? - .derive_priv(&Secp256k1::new(), &path) - .map_err(|e| anyhow!(e)) + ) -> NodeResult { + Ok( + ExtendedPrivKey::new_master(network.into(), &signer.bip32_ext_key())? + .derive_priv(&Secp256k1::new(), &path)?, + ) } fn legacy_derive_bip32_key( network: Network, signer: &Signer, path: Vec, - ) -> Result { - ExtendedPrivKey::new_master(network.into(), &signer.legacy_bip32_ext_key())? - .derive_priv(&Secp256k1::new(), &path) - .map_err(|e| anyhow!(e)) + ) -> NodeResult { + Ok( + ExtendedPrivKey::new_master(network.into(), &signer.legacy_bip32_ext_key())? + .derive_priv(&Secp256k1::new(), &path)?, + ) } async fn register( @@ -251,22 +254,34 @@ impl Greenlight { }) } - async fn get_client(&self) -> Result { + async fn get_client(&self) -> NodeResult { let mut gl_client = self.gl_client.lock().await; if gl_client.is_none() { - let scheduler = - Scheduler::new(self.signer.node_id(), self.sdk_config.network.into()).await?; - *gl_client = Some(scheduler.schedule(self.tls_config.clone()).await?); + let scheduler = Scheduler::new(self.signer.node_id(), self.sdk_config.network.into()) + .await + .map_err(NodeError::ServiceConnectivity)?; + *gl_client = Some( + scheduler + .schedule(self.tls_config.clone()) + .await + .map_err(NodeError::ServiceConnectivity)?, + ); } Ok(gl_client.clone().unwrap()) } - pub(crate) async fn get_node_client(&self) -> Result { + pub(crate) async fn get_node_client(&self) -> NodeResult { let mut node_client = self.node_client.lock().await; if node_client.is_none() { - let scheduler = - Scheduler::new(self.signer.node_id(), self.sdk_config.network.into()).await?; - *node_client = Some(scheduler.schedule(self.tls_config.clone()).await?); + let scheduler = Scheduler::new(self.signer.node_id(), self.sdk_config.network.into()) + .await + .map_err(NodeError::ServiceConnectivity)?; + *node_client = Some( + scheduler + .schedule(self.tls_config.clone()) + .await + .map_err(NodeError::ServiceConnectivity)?, + ); } Ok(node_client.clone().unwrap()) } @@ -275,7 +290,7 @@ impl Greenlight { cln_client: node::ClnClient, persister: Arc, balance_changed: bool, - ) -> Result<( + ) -> NodeResult<( Vec, Vec, Vec, @@ -310,7 +325,7 @@ impl Greenlight { async fn fetch_channels_and_balance( mut cln_client: node::ClnClient, - ) -> Result<( + ) -> NodeResult<( Vec, Vec, Vec, @@ -406,7 +421,7 @@ impl NodeAPI for Greenlight { use_description_hash: Option, expiry: Option, cltv: Option, - ) -> Result { + ) -> NodeResult { let mut client = self.get_node_client().await?; let request = InvoiceRequest { amount_msat: Some(AmountOrAny { @@ -435,7 +450,7 @@ impl NodeAPI for Greenlight { &self, since_timestamp: u64, balance_changed: bool, - ) -> Result { + ) -> NodeResult { info!("pull changed since {}", since_timestamp); let node_client = self.get_node_client().await?; @@ -471,7 +486,7 @@ impl NodeAPI for Greenlight { let closed_channels = closed_channels_res?.into_inner().closedchannels; let (all_channels, opened_channels, connected_peers, channels_balance) = balance_res?; - let forgotten_closed_channels: Result> = closed_channels + let forgotten_closed_channels: NodeResult> = closed_channels .into_iter() .filter(|cc| { all_channels @@ -540,7 +555,7 @@ impl NodeAPI for Greenlight { &self, bolt11: String, amount_msat: Option, - ) -> Result { + ) -> NodeResult { let mut description = None; if !bolt11.is_empty() { description = parse_invoice(&bolt11)?.description; @@ -570,7 +585,7 @@ impl NodeAPI for Greenlight { &self, node_id: String, amount_msat: u64, - ) -> Result { + ) -> NodeResult { let mut client: node::ClnClient = self.get_node_client().await?; let request = pb::cln::KeysendRequest { destination: hex::decode(node_id)?, @@ -589,7 +604,7 @@ impl NodeAPI for Greenlight { client.key_send(request).await?.into_inner().try_into() } - async fn start(&self) -> Result<()> { + async fn start(&self) -> NodeResult<()> { self.get_node_client() .await? .getinfo(pb::cln::GetinfoRequest {}) @@ -597,7 +612,7 @@ impl NodeAPI for Greenlight { Ok(()) } - async fn sweep(&self, to_address: String, fee_rate_sats_per_vbyte: u32) -> Result> { + async fn sweep(&self, to_address: String, fee_rate_sats_per_vbyte: u32) -> NodeResult> { let mut client = self.get_node_client().await?; let request = pb::cln::WithdrawRequest { @@ -617,7 +632,7 @@ impl NodeAPI for Greenlight { Ok(client.withdraw(request).await?.into_inner().txid) } - async fn prepare_sweep(&self, req: PrepareSweepRequest) -> Result { + async fn prepare_sweep(&self, req: PrepareSweepRequest) -> NodeResult { let funds = self.list_funds().await?; let utxos = self.utxos(funds).await?; @@ -659,7 +674,9 @@ impl NodeAPI for Greenlight { + witness_input_size * txins.len() as u64; let fee: u64 = tx_weight * req.sats_per_vbyte / WITNESS_SCALE_FACTOR as u64; if fee >= amount { - return Err(anyhow!("insufficient funds to pay fees")); + return Err(NodeError::Generic(anyhow!( + "Insufficient funds to pay fees" + ))); } tx.output[0].value = amount - fee; @@ -677,7 +694,7 @@ impl NodeAPI for Greenlight { } } - async fn list_peers(&self) -> Result> { + async fn list_peers(&self) -> NodeResult> { let mut client = self.get_node_client().await?; let res: cln::ListpeersResponse = client @@ -689,7 +706,7 @@ impl NodeAPI for Greenlight { Ok(peers_models) } - async fn connect_peer(&self, id: String, addr: String) -> Result<()> { + async fn connect_peer(&self, id: String, addr: String) -> NodeResult<()> { let mut client = self.get_node_client().await?; let connect_req = pb::cln::ConnectRequest { id: format!("{id}@{addr}"), @@ -700,19 +717,24 @@ impl NodeAPI for Greenlight { Ok(()) } - async fn sign_message(&self, message: &str) -> Result { + async fn sign_message(&self, message: &str) -> NodeResult { let (sig, recovery_id) = self.signer.sign_message(message.as_bytes().to_vec())?; let mut complete_signature = vec![31 + recovery_id]; complete_signature.extend_from_slice(&sig); Ok(zbase32::encode_full_bytes(&complete_signature)) } - async fn check_message(&self, message: &str, pubkey: &str, signature: &str) -> Result { + async fn check_message( + &self, + message: &str, + pubkey: &str, + signature: &str, + ) -> NodeResult { let pk = PublicKey::from_str(pubkey)?; Ok(verify(message.as_bytes(), signature, &pk)) } - fn sign_invoice(&self, invoice: RawInvoice) -> Result { + fn sign_invoice(&self, invoice: RawInvoice) -> NodeResult { let hrp_bytes = invoice.hrp.to_string().as_bytes().to_vec(); let data_bytes = invoice.data.to_base32(); @@ -740,14 +762,13 @@ impl NodeAPI for Greenlight { // contruct the RecoveryId let rid = RecoveryId::from_i32(raw_result[64] as i32).expect("recovery ID"); let sig = &raw_result[0..64]; - let recoverable_sig = - RecoverableSignature::from_compact(sig, rid).map_err(|e| anyhow!(e))?; + let recoverable_sig = RecoverableSignature::from_compact(sig, rid)?; let signed_invoice: Result = invoice.sign(|_| Ok(recoverable_sig)); Ok(signed_invoice?.to_string()) } - async fn close_peer_channels(&self, node_id: String) -> Result> { + async fn close_peer_channels(&self, node_id: String) -> NodeResult> { let mut client = self.get_node_client().await?; let closed_channels = client .list_peer_channels(ListpeerchannelsRequest { @@ -773,7 +794,7 @@ impl NodeAPI for Greenlight { } if should_close { - let chan_id = channel.channel_id.ok_or(anyhow!("empty channel id"))?; + let chan_id = channel.channel_id.ok_or(anyhow!("Empty channel id"))?; let response = client .close(CloseRequest { id: hex::encode(chan_id), @@ -790,19 +811,19 @@ impl NodeAPI for Greenlight { tx_ids.push(hex::encode( res.into_inner() .txid - .ok_or(anyhow!("empty txid in close response"))?, + .ok_or(anyhow!("Empty txid in close response"))?, )); } - Err(e) => { - error!("error closing channel: {}", e); - } + Err(e) => Err(anyhow!("Empty closing channel: {e}"))?, }; } } Ok(tx_ids) } - async fn stream_incoming_payments(&self) -> Result> { + async fn stream_incoming_payments( + &self, + ) -> NodeResult> { let mut client = self.get_client().await?; let stream = client .stream_incoming(gl_client::pb::StreamIncomingFilter {}) @@ -811,7 +832,7 @@ impl NodeAPI for Greenlight { Ok(stream) } - async fn stream_log_messages(&self) -> Result> { + async fn stream_log_messages(&self) -> NodeResult> { let mut client = self.get_client().await?; let stream = client .stream_log(gl_client::pb::StreamLogRequest {}) @@ -820,7 +841,7 @@ impl NodeAPI for Greenlight { Ok(stream) } - async fn static_backup(&self) -> Result> { + async fn static_backup(&self) -> NodeResult> { let mut client = self.get_node_client().await?; let res = client .static_backup(StaticbackupRequest {}) @@ -830,9 +851,9 @@ impl NodeAPI for Greenlight { Ok(hex_vec) } - async fn execute_command(&self, command: String) -> Result { - let node_cmd = NodeCommand::from_str(&command) - .map_err(|_| anyhow!(format!("command not found: {command}")))?; + async fn execute_command(&self, command: String) -> NodeResult { + let node_cmd = + NodeCommand::from_str(&command).map_err(|_| anyhow!("Command not found: {command}"))?; match node_cmd { NodeCommand::ListPeers => { let resp = self @@ -904,17 +925,17 @@ impl NodeAPI for Greenlight { } } - fn derive_bip32_key(&self, path: Vec) -> Result { + fn derive_bip32_key(&self, path: Vec) -> NodeResult { Self::derive_bip32_key(self.sdk_config.network, &self.signer, path) } - fn legacy_derive_bip32_key(&self, path: Vec) -> Result { + fn legacy_derive_bip32_key(&self, path: Vec) -> NodeResult { Self::legacy_derive_bip32_key(self.sdk_config.network, &self.signer, path) } async fn stream_custom_messages( &self, - ) -> Result> + Send>>> { + ) -> NodeResult> + Send>>> { let stream = { let mut client = match self.get_client().await { Ok(c) => Ok(c), @@ -955,7 +976,7 @@ impl NodeAPI for Greenlight { }))) } - async fn send_custom_message(&self, message: CustomMessage) -> Result<()> { + async fn send_custom_message(&self, message: CustomMessage) -> NodeResult<()> { let mut msg = message.message_type.to_be_bytes().to_vec(); msg.extend(message.payload); let resp = self @@ -998,7 +1019,10 @@ enum NodeCommand { // pulls transactions from greenlight based on last sync timestamp. // greenlight gives us the payments via API and for received payments we are looking for settled invoices. -async fn pull_transactions(since_timestamp: u64, client: node::ClnClient) -> Result> { +async fn pull_transactions( + since_timestamp: u64, + client: node::ClnClient, +) -> NodeResult> { let mut c = client.clone(); // list invoices @@ -1007,7 +1031,7 @@ async fn pull_transactions(since_timestamp: u64, client: node::ClnClient) -> Res .await? .into_inner(); // construct the received transactions by filtering the invoices to those paid and beyond the filter timestamp - let received_transactions: Result> = invoices + let received_transactions: NodeResult> = invoices .invoices .into_iter() .filter(|i| { @@ -1024,7 +1048,7 @@ async fn pull_transactions(since_timestamp: u64, client: node::ClnClient) -> Res .into_inner(); debug!("list payments: {:?}", payments); // construct the payment transactions (pending and complete) - let outbound_transactions: Result> = payments + let outbound_transactions: NodeResult> = payments .pays .into_iter() .filter(|p| p.created_at > since_timestamp) @@ -1040,7 +1064,7 @@ async fn pull_transactions(since_timestamp: u64, client: node::ClnClient) -> Res //pub(crate) fn offchain_payment_to_transaction impl TryFrom for Payment { - type Error = anyhow::Error; + type Error = NodeError; fn try_from(p: OffChainPayment) -> std::result::Result { let ln_invoice = parse_invoice(&p.bolt11)?; @@ -1075,7 +1099,7 @@ impl TryFrom for Payment { /// Construct a lightning transaction from an invoice impl TryFrom for Payment { - type Error = anyhow::Error; + type Error = NodeError; fn try_from(invoice: pb::Invoice) -> std::result::Result { let ln_invoice = parse_invoice(&invoice.bolt11)?; @@ -1117,7 +1141,7 @@ impl From for PaymentStatus { /// Construct a lightning transaction from an invoice impl TryFrom for Payment { - type Error = anyhow::Error; + type Error = NodeError; fn try_from(payment: pb::Payment) -> std::result::Result { let mut description = None; @@ -1157,13 +1181,13 @@ impl TryFrom for Payment { /// Construct a lightning transaction from an invoice impl TryFrom for Payment { - type Error = anyhow::Error; + type Error = NodeError; fn try_from(invoice: ListinvoicesInvoices) -> std::result::Result { let ln_invoice = invoice .bolt11 .as_ref() - .ok_or(anyhow!("No bolt11 invoice")) + .ok_or(InvoiceError::Generic(anyhow!("No bolt11 invoice"))) .and_then(|b| parse_invoice(b))?; Ok(Payment { id: hex::encode(invoice.payment_hash.clone()), @@ -1205,13 +1229,13 @@ impl From for PaymentStatus { } impl TryFrom for Payment { - type Error = anyhow::Error; + type Error = NodeError; - fn try_from(payment: ListpaysPays) -> std::result::Result { + fn try_from(payment: ListpaysPays) -> NodeResult { let ln_invoice = payment .bolt11 .as_ref() - .ok_or(anyhow!("No bolt11 invoice")) + .ok_or(InvoiceError::Generic(anyhow!("No bolt11 invoice"))) .and_then(|b| parse_invoice(b)); let payment_amount = payment .amount_msat @@ -1257,7 +1281,7 @@ impl TryFrom for Payment { } impl TryFrom for PaymentResponse { - type Error = anyhow::Error; + type Error = NodeError; fn try_from(payment: pb::cln::PayResponse) -> std::result::Result { let payment_amount = payment.amount_msat.unwrap_or_default().msat; @@ -1274,7 +1298,7 @@ impl TryFrom for PaymentResponse { } impl TryFrom for PaymentResponse { - type Error = anyhow::Error; + type Error = NodeError; fn try_from(payment: pb::cln::KeysendResponse) -> std::result::Result { let payment_amount = payment.amount_msat.unwrap_or_default().msat; @@ -1343,7 +1367,7 @@ impl From for Channel { /// Conversion for a closed channel impl TryFrom for Channel { - type Error = anyhow::Error; + type Error = NodeError; fn try_from(c: ListclosedchannelsClosedchannels) -> std::result::Result { let (alias_remote, alias_local) = match c.alias { diff --git a/libs/sdk-core/src/input_parser.rs b/libs/sdk-core/src/input_parser.rs index a8cf0e4c3..475e7d439 100644 --- a/libs/sdk-core/src/input_parser.rs +++ b/libs/sdk-core/src/input_parser.rs @@ -7,10 +7,12 @@ use bitcoin::bech32::FromBase32; use serde::Deserialize; use serde::Serialize; +use crate::ensure_sdk; use crate::input_parser::InputType::*; use crate::input_parser::LnUrlRequestData::*; use crate::invoice::{parse_invoice, LNInvoice}; +use crate::lnurl::error::LnUrlResult; use crate::lnurl::maybe_replace_host_with_mockito_test_host; /// Parses generic user input, typically pasted from clipboard or scanned from a QR. @@ -204,7 +206,9 @@ pub async fn parse(input: &str) -> Result { } lnurl_endpoint = maybe_replace_host_with_mockito_test_host(lnurl_endpoint)?; - let lnurl_data: LnUrlRequestData = get_parse_and_log_response(&lnurl_endpoint).await?; + let lnurl_data: LnUrlRequestData = get_parse_and_log_response(&lnurl_endpoint) + .await + .map_err(|_| anyhow!("Failed to parse response"))?; let temp = lnurl_data.into(); let temp = match temp { // Modify the LnUrlPay payload by adding the domain of the LNURL endpoint @@ -246,7 +250,7 @@ where { let raw_body = get_and_log_response(url).await?; - serde_json::from_str(&raw_body).map_err(|e| anyhow!("Failed to parse json: {e}")) + Ok(serde_json::from_str(&raw_body)?) } /// Prepends the given prefix to the input, if the input doesn't already start with it @@ -308,25 +312,30 @@ fn ln_address_decode(ln_address: &str) -> Result<(String, String)> { /// LNURLs in all uppercase or all lowercase are valid, but mixed case ones are invalid. /// /// For LN addresses, the username is limited to `a-z0-9-_.`, which is more restrictive than email addresses. -fn lnurl_decode(encoded: &str) -> Result<(String, String, bool)> { +fn lnurl_decode(encoded: &str) -> LnUrlResult<(String, String, bool)> { if let Ok((domain, url)) = ln_address_decode(encoded) { return Ok((domain, url, true)); } match bech32::decode(encoded) { Ok((_hrp, payload, _variant)) => { - let decoded = String::from_utf8(Vec::from_base32(&payload)?).map_err(|e| anyhow!(e))?; + let decoded = String::from_utf8(Vec::from_base32(&payload)?)?; - let url = reqwest::Url::parse(&decoded)?; - let domain = url - .domain() - .ok_or_else(|| anyhow!("Could not determine domain"))?; + let url = reqwest::Url::parse(&decoded) + .map_err(|e| super::lnurl::error::LnUrlError::InvalidUri(anyhow::Error::new(e)))?; + let domain = url.domain().ok_or_else(|| { + super::lnurl::error::LnUrlError::InvalidUri(anyhow!("Could not determine domain")) + })?; if url.scheme() == "http" && !domain.ends_with(".onion") { - return Err(anyhow!("HTTP scheme only allowed for onion domains")); + return Err(super::lnurl::error::LnUrlError::Generic(anyhow!( + "HTTP scheme only allowed for onion domains" + ))); } if url.scheme() == "https" && domain.ends_with(".onion") { - return Err(anyhow!("HTTPS scheme not allowed for onion domains")); + return Err(super::lnurl::error::LnUrlError::Generic(anyhow!( + "HTTPS scheme not allowed for onion domains" + ))); } Ok((domain.into(), decoded, false)) @@ -346,14 +355,15 @@ fn lnurl_decode(encoded: &str) -> Result<(String, String, bool)> { } } - let url = reqwest::Url::parse(&encoded)?; - let domain = url - .domain() - .ok_or_else(|| anyhow!("Could not determine domain"))?; - - if !supported_prefixes.contains(&url.scheme()) { - return Err(anyhow!("Invalid prefix scheme")); - } + let url = reqwest::Url::parse(&encoded) + .map_err(|e| super::lnurl::error::LnUrlError::InvalidUri(anyhow::Error::new(e)))?; + let domain = url.domain().ok_or_else(|| { + super::lnurl::error::LnUrlError::InvalidUri(anyhow!("Could not determine domain")) + })?; + ensure_sdk!( + supported_prefixes.contains(&url.scheme()), + super::lnurl::error::LnUrlError::Generic(anyhow!("Invalid prefix scheme")) + ); let scheme = url.scheme(); let new_scheme = match domain.ends_with(".onion") { @@ -520,7 +530,9 @@ impl LnUrlPayRequestData { /// Parsed metadata items. Use `metadata_str` to get the raw metadata string, as received from /// the LNURL endpoint. pub fn metadata_vec(&self) -> Result> { - serde_json::from_str::>(&self.metadata_str).map_err(|err| anyhow!(err)) + Ok(serde_json::from_str::>( + &self.metadata_str, + )?) } } diff --git a/libs/sdk-core/src/invoice.rs b/libs/sdk-core/src/invoice.rs index 740de400c..36637f3da 100644 --- a/libs/sdk-core/src/invoice.rs +++ b/libs/sdk-core/src/invoice.rs @@ -1,5 +1,4 @@ -use anyhow::{anyhow, Result}; -use bitcoin::secp256k1::PublicKey; +use bitcoin::secp256k1::{self, PublicKey}; use hex::ToHex; use lightning::routing::gossip::RoutingFees; use lightning::routing::*; @@ -7,7 +6,54 @@ use lightning_invoice::*; use regex::Regex; use serde::{Deserialize, Serialize}; use std::str::FromStr; -use std::time::UNIX_EPOCH; +use std::time::{SystemTimeError, UNIX_EPOCH}; + +pub type InvoiceResult = Result; + +#[derive(Debug, thiserror::Error)] +pub enum InvoiceError { + #[error("Generic: {0}")] + Generic(#[from] anyhow::Error), + + #[error("Validation: {0}")] + Validation(anyhow::Error), +} + +impl From for InvoiceError { + fn from(err: lightning_invoice::CreationError) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +impl From for InvoiceError { + fn from(err: lightning_invoice::ParseError) -> Self { + Self::Validation(anyhow::Error::new(err)) + } +} + +impl From for InvoiceError { + fn from(err: lightning_invoice::SemanticError) -> Self { + Self::Validation(anyhow::Error::new(err)) + } +} + +impl From for InvoiceError { + fn from(err: regex::Error) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +impl From for InvoiceError { + fn from(err: secp256k1::Error) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +impl From for InvoiceError { + fn from(err: SystemTimeError) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} /// Wrapper for a BOLT11 LN invoice #[derive(Clone, Debug, Serialize, Deserialize, PartialEq)] @@ -50,7 +96,7 @@ pub struct RouteHint { } impl RouteHint { - pub fn to_ldk_hint(&self) -> Result { + pub fn to_ldk_hint(&self) -> InvoiceResult { let mut hops = Vec::new(); for hop in self.hops.iter() { let pubkey_res = PublicKey::from_str(&hop.src_node_id)?; @@ -95,7 +141,7 @@ pub fn add_lsp_routing_hints( invoice: String, lsp_hint: Option, new_amount_msats: u64, -) -> Result { +) -> InvoiceResult { let signed = invoice.parse::()?; let invoice = Invoice::from_signed(signed)?; @@ -138,16 +184,11 @@ pub fn add_lsp_routing_hints( invoice_builder = invoice_builder.private_route(hint); } - let invoice_builder = invoice_builder.build_raw(); - - match invoice_builder { - Ok(invoice) => Ok(invoice), - Err(err) => Err(anyhow!(err)), - } + Ok(invoice_builder.build_raw()?) } /// Parse a BOLT11 payment request and return a structure contains the parsed fields. -pub fn parse_invoice(bolt11: &str) -> Result { +pub fn parse_invoice(bolt11: &str) -> InvoiceResult { let re = Regex::new(r"(?i)^lightning:")?; let bolt11 = re.replace_all(bolt11, ""); let signed = bolt11.parse::()?; diff --git a/libs/sdk-core/src/lib.rs b/libs/sdk-core/src/lib.rs index 5b3a963f3..433d4c157 100644 --- a/libs/sdk-core/src/lib.rs +++ b/libs/sdk-core/src/lib.rs @@ -161,7 +161,6 @@ extern crate log; mod backup; pub mod binding; -mod boltzswap; mod breez_services; mod chain; mod crypt; @@ -180,9 +179,10 @@ mod lsps0; mod lsps2; mod models; mod moonpay; +mod node_api; mod persist; -mod reverseswap; -mod swap; +mod swap_in; +mod swap_out; #[cfg(test)] mod test_utils; @@ -202,4 +202,4 @@ pub use invoice::{parse_invoice, LNInvoice, RouteHint, RouteHintHop}; pub use lnurl::pay::model::*; pub use lsp::LspInformation; pub use models::*; -pub use reverseswap::{ESTIMATED_CLAIM_TX_VSIZE, ESTIMATED_LOCKUP_TX_VSIZE}; +pub use swap_out::reverseswap::{ESTIMATED_CLAIM_TX_VSIZE, ESTIMATED_LOCKUP_TX_VSIZE}; diff --git a/libs/sdk-core/src/lnurl/auth.rs b/libs/sdk-core/src/lnurl/auth.rs index 24c7eec6d..9ed4d0e41 100644 --- a/libs/sdk-core/src/lnurl/auth.rs +++ b/libs/sdk-core/src/lnurl/auth.rs @@ -1,6 +1,6 @@ use crate::input_parser::get_parse_and_log_response; -use crate::{LnUrlAuthRequestData, LnUrlCallbackStatus, NodeAPI}; -use anyhow::{anyhow, Result}; +use crate::{node_api::NodeAPI, LnUrlAuthRequestData, LnUrlCallbackStatus}; +use anyhow::anyhow; use bitcoin::hashes::{hex::ToHex, sha256, Hash, HashEngine, Hmac, HmacEngine}; use bitcoin::secp256k1::{Message, Secp256k1}; use bitcoin::util::bip32::ChildNumber; @@ -9,6 +9,8 @@ use reqwest::Url; use std::str::FromStr; use std::sync::Arc; +use super::error::{LnUrlError, LnUrlResult}; + /// Performs the third and last step of LNURL-auth, as per /// /// @@ -16,14 +18,20 @@ use std::sync::Arc; pub(crate) async fn perform_lnurl_auth( node_api: Arc, req_data: LnUrlAuthRequestData, -) -> Result { - let linking_keys = derive_linking_keys(node_api, Url::from_str(&req_data.url)?)?; - - let k1_to_sign = Message::from_slice(&hex::decode(req_data.k1)?)?; +) -> LnUrlResult { + let url = + Url::from_str(&req_data.url).map_err(|e| LnUrlError::InvalidUri(anyhow::Error::new(e)))?; + let linking_keys = derive_linking_keys(node_api, url)?; + + let k1_to_sign = Message::from_slice( + &hex::decode(req_data.k1) + .map_err(|e| LnUrlError::Generic(anyhow!("Error decoding k1: {e}")))?, + )?; let sig = Secp256k1::new().sign_ecdsa(&k1_to_sign, &linking_keys.secret_key()); // ?&sig=&key= - let mut callback_url = Url::from_str(&req_data.url)?; + let mut callback_url = + Url::from_str(&req_data.url).map_err(|e| LnUrlError::InvalidUri(anyhow::Error::new(e)))?; callback_url .query_pairs_mut() .append_pair("sig", &sig.serialize_der().to_hex()); @@ -31,35 +39,43 @@ pub(crate) async fn perform_lnurl_auth( .query_pairs_mut() .append_pair("key", &linking_keys.public_key().to_hex()); - get_parse_and_log_response(callback_url.as_ref()).await + get_parse_and_log_response(callback_url.as_ref()) + .await + .map_err(LnUrlError::ServiceConnectivity) } pub(crate) fn validate_request( domain: String, lnurl_endpoint: String, -) -> Result { - let query = Url::from_str(&lnurl_endpoint)?; +) -> LnUrlResult { + let query = Url::from_str(&lnurl_endpoint) + .map_err(|e| LnUrlError::InvalidUri(anyhow::Error::new(e)))?; let query_pairs = query.query_pairs(); let k1 = query_pairs .into_iter() .find(|(key, _)| key == "k1") .map(|(_, v)| v.to_string()) - .ok_or(anyhow!("LNURL-auth k1 arg not found"))?; + .ok_or(LnUrlError::Generic(anyhow!("LNURL-auth k1 arg not found")))?; let maybe_action = query_pairs .into_iter() .find(|(key, _)| key == "action") .map(|(_, v)| v.to_string()); - let k1_bytes = hex::decode(&k1)?; + let k1_bytes = + hex::decode(&k1).map_err(|e| LnUrlError::Generic(anyhow!("Error decoding k1: {e}")))?; if k1_bytes.len() != 32 { - return Err(anyhow!("LNURL-auth k1 is of unexpected length")); + return Err(LnUrlError::Generic(anyhow!( + "LNURL-auth k1 is of unexpected length" + ))); } if let Some(action) = &maybe_action { if !["register", "login", "link", "auth"].contains(&action.as_str()) { - return Err(anyhow!("LNURL-auth action is of unexpected type")); + return Err(LnUrlError::Generic(anyhow!( + "LNURL-auth action is of unexpected type" + ))); } } @@ -80,8 +96,10 @@ fn hmac_sha256(key: &[u8], input: &[u8]) -> Hmac { /// Linking key is derived as per LUD-05 /// /// https://github.com/lnurl/luds/blob/luds/05.md -fn derive_linking_keys(node_api: Arc, url: Url) -> Result { - let domain = url.domain().ok_or(anyhow!("Could not determine domain"))?; +fn derive_linking_keys(node_api: Arc, url: Url) -> LnUrlResult { + let domain = url.domain().ok_or(LnUrlError::InvalidUri(anyhow!( + "Could not determine domain" + )))?; // m/138'/0 let hashing_key = node_api.derive_bip32_key(vec![ diff --git a/libs/sdk-core/src/lnurl/error.rs b/libs/sdk-core/src/lnurl/error.rs new file mode 100644 index 000000000..e632420e7 --- /dev/null +++ b/libs/sdk-core/src/lnurl/error.rs @@ -0,0 +1,87 @@ +use std::{array::TryFromSliceError, string::FromUtf8Error}; + +use anyhow::anyhow; +use bitcoin::{bech32, secp256k1, util::bip32}; + +use crate::{invoice::InvoiceError, node_api::NodeError}; + +pub type LnUrlResult = Result; + +#[derive(Debug, thiserror::Error)] +pub enum LnUrlError { + #[error("Generic: {0}")] + Generic(#[from] anyhow::Error), + + #[error(transparent)] + InvalidInvoice(#[from] InvoiceError), + + #[error("Invalid uri: {0}")] + InvalidUri(anyhow::Error), + + #[error("Service connectivity: {0}")] + ServiceConnectivity(anyhow::Error), +} + +impl From for LnUrlError { + fn from(err: aes::cipher::InvalidLength) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +impl From for LnUrlError { + fn from(err: aes::cipher::block_padding::UnpadError) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +impl From for LnUrlError { + fn from(err: base64::DecodeError) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +impl From for LnUrlError { + fn from(err: bip32::Error) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +impl From for LnUrlError { + fn from(err: bech32::Error) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +impl From for LnUrlError { + fn from(err: FromUtf8Error) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +impl From for LnUrlError { + fn from(err: NodeError) -> Self { + match err { + NodeError::InvalidInvoice(err) => Self::InvalidInvoice(err), + NodeError::ServiceConnectivity(err) => Self::ServiceConnectivity(err), + _ => Self::Generic(anyhow!(err.to_string())), + } + } +} + +impl From for LnUrlError { + fn from(err: secp256k1::Error) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} + +impl From for LnUrlError { + fn from(err: serde_json::Error) -> Self { + Self::ServiceConnectivity(anyhow::Error::new(err)) + } +} + +impl From for LnUrlError { + fn from(err: TryFromSliceError) -> Self { + Self::Generic(anyhow::Error::new(err)) + } +} diff --git a/libs/sdk-core/src/lnurl/mod.rs b/libs/sdk-core/src/lnurl/mod.rs index 38361a386..f733e81be 100644 --- a/libs/sdk-core/src/lnurl/mod.rs +++ b/libs/sdk-core/src/lnurl/mod.rs @@ -1,19 +1,29 @@ pub(crate) mod auth; +pub(crate) mod error; pub(crate) mod pay; pub(crate) mod withdraw; -use anyhow::Result; +use crate::lnurl::error::LnUrlResult; /// Replaces the scheme, host and port with a local mockito host. Preserves the rest of the path. #[cfg(test)] -pub(crate) fn maybe_replace_host_with_mockito_test_host(lnurl_endpoint: String) -> Result { +pub(crate) fn maybe_replace_host_with_mockito_test_host( + lnurl_endpoint: String, +) -> LnUrlResult { // During tests, the mockito test URL chooses a free port. This cannot be known in advance, // so the URL has to be adjusted dynamically. + + use self::error::LnUrlError; + let server = crate::input_parser::tests::MOCK_HTTP_SERVER.lock().unwrap(); - let mockito_endpoint_url = reqwest::Url::parse(&server.url())?; - let mut parsed_lnurl_endpoint = reqwest::Url::parse(&lnurl_endpoint)?; + let mockito_endpoint_url = reqwest::Url::parse(&server.url()) + .map_err(|e| LnUrlError::InvalidUri(anyhow::Error::new(e)))?; + let mut parsed_lnurl_endpoint = reqwest::Url::parse(&lnurl_endpoint) + .map_err(|e| LnUrlError::InvalidUri(anyhow::Error::new(e)))?; - parsed_lnurl_endpoint.set_host(mockito_endpoint_url.host_str())?; + parsed_lnurl_endpoint + .set_host(mockito_endpoint_url.host_str()) + .map_err(|e| LnUrlError::InvalidUri(anyhow::Error::new(e)))?; let _ = parsed_lnurl_endpoint.set_scheme(mockito_endpoint_url.scheme()); let _ = parsed_lnurl_endpoint.set_port(mockito_endpoint_url.port()); @@ -21,7 +31,9 @@ pub(crate) fn maybe_replace_host_with_mockito_test_host(lnurl_endpoint: String) } #[cfg(not(test))] -pub(crate) fn maybe_replace_host_with_mockito_test_host(lnurl_endpoint: String) -> Result { +pub(crate) fn maybe_replace_host_with_mockito_test_host( + lnurl_endpoint: String, +) -> LnUrlResult { // When not called from a test, we fallback to keeping the URL intact Ok(lnurl_endpoint) } diff --git a/libs/sdk-core/src/lnurl/pay.rs b/libs/sdk-core/src/lnurl/pay.rs index 2490fe255..fdf229c9b 100644 --- a/libs/sdk-core/src/lnurl/pay.rs +++ b/libs/sdk-core/src/lnurl/pay.rs @@ -1,12 +1,14 @@ -use crate::input_parser::*; use crate::invoice::parse_invoice; use crate::lnurl::maybe_replace_host_with_mockito_test_host; use crate::lnurl::pay::model::{CallbackResponse, SuccessAction, ValidatedCallbackResponse}; use crate::LnUrlErrorData; -use anyhow::{anyhow, Result}; +use crate::{ensure_sdk, input_parser::*}; +use anyhow::anyhow; use bitcoin::hashes::{sha256, Hash}; use std::str::FromStr; +use super::error::{LnUrlError, LnUrlResult}; + type Aes256CbcEnc = cbc::Encryptor; type Aes256CbcDec = cbc::Decryptor; @@ -18,7 +20,7 @@ pub(crate) async fn validate_lnurl_pay( user_amount_msat: u64, comment: Option, req_data: LnUrlPayRequestData, -) -> Result { +) -> LnUrlResult { validate_user_input( user_amount_msat, &comment, @@ -28,7 +30,9 @@ pub(crate) async fn validate_lnurl_pay( )?; let callback_url = build_pay_callback_url(user_amount_msat, &comment, &req_data)?; - let callback_resp_text = get_and_log_response(&callback_url).await?; + let callback_resp_text = get_and_log_response(&callback_url) + .await + .map_err(LnUrlError::ServiceConnectivity)?; if let Ok(err) = serde_json::from_str::(&callback_resp_text) { Ok(ValidatedCallbackResponse::EndpointError { data: err }) @@ -53,9 +57,10 @@ fn build_pay_callback_url( user_amount_msat: u64, user_comment: &Option, data: &LnUrlPayRequestData, -) -> Result { +) -> LnUrlResult { let amount_msat = user_amount_msat.to_string(); - let mut url = reqwest::Url::from_str(&data.callback)?; + let mut url = reqwest::Url::from_str(&data.callback) + .map_err(|e| LnUrlError::InvalidUri(anyhow::Error::new(e)))?; url.query_pairs_mut().append_pair("amount", &amount_msat); if let Some(comment) = user_comment { @@ -73,54 +78,69 @@ fn validate_user_input( condition_min_amount_msat: u64, condition_max_amount_msat: u64, condition_max_comment_len: u16, -) -> Result<()> { - if user_amount_msat < condition_min_amount_msat { - return Err(anyhow!("Amount is smaller than the minimum allowed")); - } +) -> LnUrlResult<()> { + ensure_sdk!( + user_amount_msat >= condition_min_amount_msat, + LnUrlError::Generic(anyhow!("Amount is smaller than the minimum allowed")) + ); - if user_amount_msat > condition_max_amount_msat { - return Err(anyhow!("Amount is bigger than the maximum allowed")); - } + ensure_sdk!( + user_amount_msat <= condition_max_amount_msat, + LnUrlError::Generic(anyhow!("Amount is bigger than the maximum allowed")) + ); match comment { None => Ok(()), Some(msg) => match msg.len() <= condition_max_comment_len as usize { true => Ok(()), - false => Err(anyhow!( + false => Err(LnUrlError::Generic(anyhow!( "Comment is longer than the maximum allowed comment length" - )), + ))), }, } } -fn validate_invoice(user_amount_msat: u64, bolt11: &str, data: &LnUrlPayRequestData) -> Result<()> { +fn validate_invoice( + user_amount_msat: u64, + bolt11: &str, + data: &LnUrlPayRequestData, +) -> LnUrlResult<()> { let invoice = parse_invoice(bolt11)?; match invoice.description_hash { - None => return Err(anyhow!("Invoice is missing description hash")), + None => { + return Err(LnUrlError::Generic(anyhow!( + "Invoice is missing description hash" + ))) + } Some(received_hash) => { // The hash is calculated from the exact metadata string, as received from the LNURL endpoint let calculated_hash = sha256::Hash::hash(data.metadata_str.as_bytes()); if received_hash != calculated_hash.to_string() { - return Err(anyhow!("Invoice has an invalid description hash")); + return Err(LnUrlError::Generic(anyhow!( + "Invoice has an invalid description hash" + ))); } } } match invoice.amount_msat { - None => Err(anyhow!("Amount is bigger than the maximum allowed")), + None => Err(LnUrlError::Generic(anyhow!( + "Amount is bigger than the maximum allowed" + ))), Some(invoice_amount_msat) => match invoice_amount_msat == user_amount_msat { true => Ok(()), - false => Err(anyhow!( + false => Err(LnUrlError::Generic(anyhow!( "Invoice amount is different than the user chosen amount" - )), + ))), }, } } pub(crate) mod model { - use crate::input_parser::*; + use crate::lnurl::error::{LnUrlError, LnUrlResult}; use crate::lnurl::pay::{Aes256CbcDec, Aes256CbcEnc}; + use crate::{ensure_sdk, input_parser::*}; use aes::cipher::{block_padding::Pkcs7, BlockDecryptMut, BlockEncryptMut, KeyIvInit}; use anyhow::{anyhow, Result}; @@ -229,23 +249,28 @@ pub(crate) mod model { impl AesSuccessActionData { /// Validates the fields, but does not decrypt and validate the ciphertext. - pub fn validate(&self) -> Result<()> { - if self.description.len() > 144 { - return Err(anyhow!( + pub fn validate(&self) -> LnUrlResult<()> { + ensure_sdk!( + self.description.len() <= 144, + LnUrlError::Generic(anyhow!( "AES action description length is larger than the maximum allowed" - )); - } + )) + ); - if self.ciphertext.len() > 4096 { - return Err(anyhow!( + ensure_sdk!( + self.ciphertext.len() <= 4096, + LnUrlError::Generic(anyhow!( "AES action ciphertext length is larger than the maximum allowed" - )); - } + )) + ); + base64::decode(&self.ciphertext)?; - if self.iv.len() != 24 { - return Err(anyhow!("AES action iv has unexpected length")); - } + ensure_sdk!( + self.iv.len() == 24, + LnUrlError::Generic(anyhow!("AES action iv has unexpected length")) + ); + base64::decode(&self.iv)?; Ok(()) @@ -257,7 +282,7 @@ pub(crate) mod model { Aes256CbcDec::new_from_slices(key, &base64::decode(&self.iv)?)? .decrypt_padded_vec_mut::(&base64::decode(&self.ciphertext)?)?; - String::from_utf8(plaintext_bytes).map_err(|e| e.into()) + Ok(String::from_utf8(plaintext_bytes)?) } /// Helper method that encrypts a given plaintext, with a given key and IV. @@ -286,40 +311,42 @@ pub(crate) mod model { } impl MessageSuccessActionData { - pub fn validate(&self) -> Result<()> { + pub fn validate(&self) -> LnUrlResult<()> { match self.message.len() <= 144 { true => Ok(()), - false => Err(anyhow!( + false => Err(LnUrlError::Generic(anyhow!( "Success action message is longer than the maximum allowed length" - )), + ))), } } } impl UrlSuccessActionData { - pub fn validate(&self, data: &LnUrlPayRequestData) -> Result<()> { + pub fn validate(&self, data: &LnUrlPayRequestData) -> LnUrlResult<()> { match self.description.len() <= 144 { true => Ok(()), - false => Err(anyhow!( + false => Err(LnUrlError::Generic(anyhow!( "Success action description is longer than the maximum allowed length" - )), + ))), } .and_then(|_| { - let req_url = reqwest::Url::parse(&data.callback)?; - let req_domain = req_url - .domain() - .ok_or_else(|| anyhow!("Could not determine callback domain"))?; - - let action_res_url = reqwest::Url::parse(&self.url)?; - let action_res_domain = action_res_url - .domain() - .ok_or_else(|| anyhow!("Could not determine Success Action URL domain"))?; + let req_url = reqwest::Url::parse(&data.callback) + .map_err(|e| LnUrlError::InvalidUri(anyhow::Error::new(e)))?; + let req_domain = req_url.domain().ok_or_else(|| { + LnUrlError::InvalidUri(anyhow!("Could not determine callback domain")) + })?; + + let action_res_url = reqwest::Url::parse(&self.url) + .map_err(|e| LnUrlError::InvalidUri(anyhow::Error::new(e)))?; + let action_res_domain = action_res_url.domain().ok_or_else(|| { + LnUrlError::InvalidUri(anyhow!("Could not determine Success Action URL domain")) + })?; match req_domain == action_res_domain { true => Ok(()), - false => Err(anyhow!( + false => Err(LnUrlError::Generic(anyhow!( "Success Action URL has different domain than the callback domain" - )), + ))), } }) } diff --git a/libs/sdk-core/src/lnurl/withdraw.rs b/libs/sdk-core/src/lnurl/withdraw.rs index 7e74c2aae..438d1613c 100644 --- a/libs/sdk-core/src/lnurl/withdraw.rs +++ b/libs/sdk-core/src/lnurl/withdraw.rs @@ -1,9 +1,12 @@ use std::str::FromStr; use crate::input_parser::get_parse_and_log_response; -use crate::{lnurl::*, LnUrlCallbackStatus, LnUrlWithdrawResult, LnUrlWithdrawSuccessData}; +use crate::lnurl::error::LnUrlError; +use crate::{ + ensure_sdk, lnurl::*, LnUrlCallbackStatus, LnUrlWithdrawResult, LnUrlWithdrawSuccessData, +}; use crate::{LNInvoice, LnUrlWithdrawRequestData}; -use anyhow::{anyhow, ensure, Result}; +use anyhow::anyhow; /// Validates invoice and performs the second and last step of LNURL-withdraw, as per /// @@ -16,24 +19,29 @@ use anyhow::{anyhow, ensure, Result}; pub(crate) async fn validate_lnurl_withdraw( req_data: LnUrlWithdrawRequestData, invoice: LNInvoice, -) -> Result { - let amount_msat = invoice - .amount_msat - .ok_or("Expected invoice amount, but found none") - .map_err(|e| anyhow!(e))?; +) -> LnUrlResult { + let amount_msat = invoice.amount_msat.ok_or(LnUrlError::Generic(anyhow!( + "Expected invoice amount, but found none" + )))?; - ensure!( + ensure_sdk!( amount_msat >= req_data.min_withdrawable, - "Amount is smaller than the minimum allowed by the LNURL-withdraw endpoint" + LnUrlError::Generic(anyhow!( + "Amount is smaller than the minimum allowed by the LNURL-withdraw endpoint" + )) ); - ensure!( + ensure_sdk!( amount_msat <= req_data.max_withdrawable, - "Amount is bigger than the maximum allowed by the LNURL-withdraw endpoint" + LnUrlError::Generic(anyhow!( + "Amount is bigger than the maximum allowed by the LNURL-withdraw endpoint" + )) ); // Send invoice to the LNURL-w endpoint via the callback let callback_url = build_withdraw_callback_url(&req_data, &invoice)?; - let callback_res: LnUrlCallbackStatus = get_parse_and_log_response(&callback_url).await?; + let callback_res: LnUrlCallbackStatus = get_parse_and_log_response(&callback_url) + .await + .map_err(LnUrlError::ServiceConnectivity)?; let withdraw_status = match callback_res { LnUrlCallbackStatus::Ok => LnUrlWithdrawResult::Ok { data: LnUrlWithdrawSuccessData { invoice }, @@ -47,8 +55,9 @@ pub(crate) async fn validate_lnurl_withdraw( fn build_withdraw_callback_url( req_data: &LnUrlWithdrawRequestData, invoice: &LNInvoice, -) -> Result { - let mut url = reqwest::Url::from_str(&req_data.callback)?; +) -> LnUrlResult { + let mut url = reqwest::Url::from_str(&req_data.callback) + .map_err(|e| LnUrlError::InvalidUri(anyhow::Error::new(e)))?; url.query_pairs_mut().append_pair("k1", &req_data.k1); url.query_pairs_mut().append_pair("pr", &invoice.bolt11); diff --git a/libs/sdk-core/src/lsp.rs b/libs/sdk-core/src/lsp.rs index 2bdd8d738..66460ed50 100644 --- a/libs/sdk-core/src/lsp.rs +++ b/libs/sdk-core/src/lsp.rs @@ -5,7 +5,7 @@ use crate::grpc::{ self, LspListRequest, PaymentInformation, RegisterPaymentReply, RegisterPaymentRequest, }; use crate::models::{LspAPI, OpeningFeeParams, OpeningFeeParamsMenu}; -use anyhow::Result; +use anyhow::{anyhow, Result}; use prost::Message; use serde::{Deserialize, Serialize}; use tonic::Request; @@ -76,7 +76,7 @@ impl LspInformation { /// /// If the LSP fees are needed, the LSP is expected to have at least one dynamic fee entry in its menu, /// otherwise this will result in an error. - pub(crate) fn cheapest_open_channel_fee(&self, expiry: u32) -> SdkResult<&OpeningFeeParams> { + pub(crate) fn cheapest_open_channel_fee(&self, expiry: u32) -> Result<&OpeningFeeParams> { for fee in &self.opening_fee_params_list.values { match fee.valid_for(expiry) { Ok(valid) => { @@ -84,22 +84,19 @@ impl LspInformation { return Ok(fee); } } - Err(e) => { - return Err(SdkError::CalculateOpenChannelFeesFailed { err: e.to_string() }) - } + Err(e) => return Err(anyhow!("Failed to calculate open channel fees: {e}")), } } - self.opening_fee_params_list.values.last().ok_or_else(|| { - SdkError::LspOpenChannelNotSupported { - err: "Dynamic fees menu contains no values".to_string(), - } - }) + self.opening_fee_params_list + .values + .last() + .ok_or_else(|| anyhow!("Dynamic fees menu contains no values")) } } #[tonic::async_trait] impl LspAPI for BreezServer { - async fn list_lsps(&self, pubkey: String) -> Result> { + async fn list_lsps(&self, pubkey: String) -> SdkResult> { let mut client = self.get_channel_opener_client().await?; let request = Request::new(LspListRequest { pubkey }); @@ -120,12 +117,16 @@ impl LspAPI for BreezServer { lsp_id: String, lsp_pubkey: Vec, payment_info: PaymentInformation, - ) -> Result { + ) -> SdkResult { let mut client = self.get_channel_opener_client().await?; let mut buf = Vec::new(); buf.reserve(payment_info.encoded_len()); - payment_info.encode(&mut buf)?; + payment_info + .encode(&mut buf) + .map_err(|e| SdkError::ServiceConnectivity { + err: format!("(LSP {lsp_id}) Failed to encode payment info: {e}"), + })?; let request = Request::new(RegisterPaymentRequest { lsp_id, @@ -139,8 +140,7 @@ impl LspAPI for BreezServer { #[cfg(test)] mod tests { - - use crate::{error::SdkError, LspInformation, OpeningFeeParams}; + use crate::{LspInformation, OpeningFeeParams}; use super::OpeningFeeParamsMenu; use anyhow::Result; @@ -192,13 +192,8 @@ mod tests { // Test the correct error when there are no fees in the menu lsp_info.opening_fee_params_list = OpeningFeeParamsMenu { values: vec![] }; - if let SdkError::LspOpenChannelNotSupported { err } = - lsp_info.cheapest_open_channel_fee(4 * 3600).err().unwrap() - { - assert_eq!(err, "Dynamic fees menu contains no values"); - } else { - panic!("Expected LspOpenChannelNotSupported error"); - } + let err = lsp_info.cheapest_open_channel_fee(4 * 3600).err().unwrap(); + assert_eq!(err.to_string(), "Dynamic fees menu contains no values"); Ok(()) } diff --git a/libs/sdk-core/src/lsps0/error.rs b/libs/sdk-core/src/lsps0/error.rs index 0d0427d16..3ebbd7bb0 100644 --- a/libs/sdk-core/src/lsps0/error.rs +++ b/libs/sdk-core/src/lsps0/error.rs @@ -1,5 +1,7 @@ use anyhow::anyhow; +use crate::node_api::NodeError; + use super::jsonrpc::RpcError; #[derive(Debug, thiserror::Error)] @@ -10,6 +12,9 @@ pub enum Error { #[error("Lsps0 deserialization error: {0}")] Deserialization(serde_json::Error), + #[error("Lsps0 node: {0}")] + Node(NodeError), + #[error("Lsps0 request timed out")] Timeout, @@ -23,6 +28,12 @@ impl From for Error { } } +impl From for Error { + fn from(value: NodeError) -> Self { + Self::Node(value) + } +} + impl From for Error { fn from(value: serde_json::Error) -> Self { Self::Deserialization(value) diff --git a/libs/sdk-core/src/lsps0/transport.rs b/libs/sdk-core/src/lsps0/transport.rs index 184f698e6..7419a348a 100644 --- a/libs/sdk-core/src/lsps0/transport.rs +++ b/libs/sdk-core/src/lsps0/transport.rs @@ -2,8 +2,8 @@ use std::collections::HashMap; use std::sync::Arc; use std::time::Duration; +use crate::node_api::NodeAPI; use crate::CustomMessage; -use crate::NodeAPI; use anyhow::{anyhow, Result}; use rand::distributions::Alphanumeric; use rand::distributions::DistString; diff --git a/libs/sdk-core/src/models.rs b/libs/sdk-core/src/models.rs index 61276c68c..9a8647e63 100644 --- a/libs/sdk-core/src/models.rs +++ b/libs/sdk-core/src/models.rs @@ -1,39 +1,34 @@ use std::cmp::max; use std::ops::Add; -use std::pin::Pin; use std::str::FromStr; use anyhow::{anyhow, ensure, Result}; use bitcoin::blockdata::opcodes; use bitcoin::blockdata::script::Builder; use bitcoin::hashes::hex::{FromHex, ToHex}; -use bitcoin::hashes::Hash; +use bitcoin::hashes::{sha256, Hash}; use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey}; -use bitcoin::util::bip32::{ChildNumber, ExtendedPrivKey}; use bitcoin::{Address, Script}; use chrono::{DateTime, Duration, Utc}; -use lightning_invoice::RawInvoice; use ripemd::Digest; use ripemd::Ripemd160; use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ToSqlOutput, ValueRef}; use rusqlite::ToSql; use serde::{Deserialize, Serialize}; use strum_macros::{Display, EnumString}; -use tokio::sync::mpsc; -use tokio_stream::Stream; -use tonic::Streaming; -use crate::boltzswap::{BoltzApiCreateReverseSwapResponse, BoltzApiReverseSwapStatus}; +use crate::breez_services::BreezServer; +use crate::error::SdkResult; use crate::fiat::{FiatCurrency, Rate}; use crate::grpc::{self, GetReverseRoutingNodeRequest, PaymentInformation, RegisterPaymentReply}; use crate::lnurl::pay::model::SuccessActionProcessed; use crate::lsp::LspInformation; use crate::models::Network::*; +use crate::swap_in::error::SwapResult; +use crate::swap_out::boltzswap::{BoltzApiCreateReverseSwapResponse, BoltzApiReverseSwapStatus}; +use crate::swap_out::error::{ReverseSwapError, ReverseSwapResult}; use crate::{LNInvoice, LnUrlErrorData, LnUrlPayRequestData, LnUrlWithdrawRequestData}; -use crate::breez_services::BreezServer; -use crate::error::{SdkError, SdkResult}; - pub const SWAP_PAYMENT_FEE_EXPIRY_SECONDS: u32 = 60 * 60 * 24 * 2; // 2 days pub const INVOICE_PAYMENT_FEE_EXPIRY_SECONDS: u32 = 60 * 60; // 60 minutes @@ -58,78 +53,26 @@ pub struct Peer { pub channels: Vec, } -/// Trait covering functions affecting the LN node -#[tonic::async_trait] -pub trait NodeAPI: Send + Sync { - async fn create_invoice( - &self, - amount_msat: u64, - description: String, - preimage: Option>, - use_description_hash: Option, - expiry: Option, - cltv: Option, - ) -> Result; - async fn pull_changed( - &self, - since_timestamp: u64, - balance_changed: bool, - ) -> Result; - /// As per the `pb::PayRequest` docs, `amount_msat` is only needed when the invoice doesn't specify an amount - async fn send_payment( - &self, - bolt11: String, - amount_msat: Option, - ) -> Result; - async fn send_spontaneous_payment( - &self, - node_id: String, - amount_msat: u64, - ) -> Result; - async fn start(&self) -> Result<()>; - async fn sweep(&self, to_address: String, fee_rate_sats_per_vbyte: u32) -> Result>; - async fn prepare_sweep(&self, req: PrepareSweepRequest) -> Result; - async fn start_signer(&self, shutdown: mpsc::Receiver<()>); - async fn list_peers(&self) -> Result>; - async fn connect_peer(&self, node_id: String, addr: String) -> Result<()>; - fn sign_invoice(&self, invoice: RawInvoice) -> Result; - async fn close_peer_channels(&self, node_id: String) -> Result>; - async fn stream_incoming_payments(&self) -> Result>; - async fn stream_log_messages(&self) -> Result>; - async fn static_backup(&self) -> Result>; - async fn execute_command(&self, command: String) -> Result; - async fn sign_message(&self, message: &str) -> Result; - async fn check_message(&self, message: &str, pubkey: &str, signature: &str) -> Result; - async fn send_custom_message(&self, message: CustomMessage) -> Result<()>; - async fn stream_custom_messages( - &self, - ) -> Result> + Send>>>; - - /// Gets the private key at the path specified - fn derive_bip32_key(&self, path: Vec) -> Result; - fn legacy_derive_bip32_key(&self, path: Vec) -> Result; -} - /// Trait covering LSP-related functionality #[tonic::async_trait] pub trait LspAPI: Send + Sync { - async fn list_lsps(&self, node_pubkey: String) -> Result>; + async fn list_lsps(&self, node_pubkey: String) -> SdkResult>; async fn register_payment( &self, lsp_id: String, lsp_pubkey: Vec, payment_info: PaymentInformation, - ) -> Result; + ) -> SdkResult; } /// Trait covering fiat-related functionality #[tonic::async_trait] pub trait FiatAPI: Send + Sync { /// List all supported fiat currencies for which there is a known exchange rate. - async fn list_fiat_currencies(&self) -> Result>; + async fn list_fiat_currencies(&self) -> SdkResult>; /// Get the live rates from the server. - async fn fetch_fiat_rates(&self) -> Result>; + async fn fetch_fiat_rates(&self) -> SdkResult>; } /// Summary of an ongoing swap @@ -151,7 +94,7 @@ pub trait SwapperAPI: Send + Sync { hash: Vec, payer_pubkey: Vec, node_pubkey: String, - ) -> Result; + ) -> SwapResult; async fn complete_swap(&self, bolt11: String) -> Result<()>; } @@ -226,7 +169,7 @@ impl FullReverseSwapInfo { compressed_pub_key: Vec, sig: Vec, lock_height: u32, - ) -> Result