Receive Chain Swaps (#310)

* Implement Chain Swaps for receiving

* Send: validate if we have sufficient funds (#321)

* Implement Chain Swaps for receiving

* Fix rebase of flutter_rust_bridge version

* Send: validate if we have sufficient funds

* Re-generate FRB

---------

Co-authored-by: Ross Savage <hello@satimoto.com>

* Chaim swap claim: remove refund_tx arg (#328)

---------

Co-authored-by: ok300 <106775972+ok300@users.noreply.github.com>
This commit is contained in:
Ross Savage
2024-06-25 17:33:38 +02:00
committed by GitHub
parent 8c85ffcf69
commit 9da16fba78
34 changed files with 4311 additions and 255 deletions

4
cli/Cargo.lock generated
View File

@@ -483,7 +483,7 @@ checksum = "829a082bd3761fde7476dc2ed85ca56c11628948460ece621e4f56fef5046567"
[[package]]
name = "boltz-client"
version = "0.1.3"
source = "git+https://github.com/dangeross/boltz-rust?rev=cb2cb02d44fb81cc8ce5d8000346f52cc26b3fc1#cb2cb02d44fb81cc8ce5d8000346f52cc26b3fc1"
source = "git+https://github.com/dangeross/boltz-rust?branch=savage-chain-swaps#0b6874c12332206b9821734561d4a140f6c0cfbb"
dependencies = [
"bip39",
"bitcoin 0.31.2",
@@ -1751,7 +1751,7 @@ dependencies = [
[[package]]
name = "lwk_wollet"
version = "0.5.1"
source = "git+https://github.com/Blockstream/lwk?rev=ffd793d0a1b1122c9bba7de23ccb73033eded98c#ffd793d0a1b1122c9bba7de23ccb73033eded98c"
source = "git+https://github.com/dangeross/lwk?branch=savage-try-headers-subscribe#ecf62efbbde5008301a329330d519e93e1e1b462"
dependencies = [
"aes-gcm-siv",
"base64 0.21.7",

View File

@@ -43,8 +43,33 @@ pub(crate) enum Command {
/// Amount the payer will send, in satoshi
payer_amount_sat: u64,
},
/// Receive lbtc and send btc onchain through a swap
ReceiveOnchainPayment {
/// Amount the payer will send, in satoshi
payer_amount_sat: u64,
},
/// List incoming and outgoing payments
ListPayments,
/// List refundable chain swaps
ListRefundables,
/// Prepare a refund transaction for an incomplete swap
PrepareRefund {
// Swap address of the lockup
swap_address: String,
// Btc onchain address to send the refund to
refund_address: String,
// Fee rate to use
sat_per_vbyte: u32,
},
/// Broadcast a refund transaction for an incomplete swap
Refund {
// Swap address of the lockup
swap_address: String,
// Btc onchain address to send the refund to
refund_address: String,
// Fee rate to use
sat_per_vbyte: u32,
},
/// Get the balance and general info of the current instance
GetInfo,
/// Sync local data with mempool and onchain data
@@ -201,6 +226,31 @@ pub(crate) async fn handle_command(
.await?;
command_result!(response)
}
Command::ReceiveOnchainPayment { payer_amount_sat } => {
let prepare_res = sdk
.prepare_receive_onchain(&PrepareReceiveOnchainRequest {
amount_sat: payer_amount_sat,
})
.await?;
wait_confirmation!(
format!(
"Fees: {} sat. Are the fees acceptable? (y/N) ",
prepare_res.fees_sat
),
"Payment receive halted"
);
let response = sdk
.receive_onchain(&ReceiveOnchainRequest { prepare_res })
.await?;
let bip21 = response.bip21.clone();
let mut result = command_result!(response);
result.push('\n');
result.push_str(&build_qr_text(&bip21));
result
}
Command::GetInfo => {
command_result!(sdk.get_info().await?)
}
@@ -208,6 +258,38 @@ pub(crate) async fn handle_command(
let payments = sdk.list_payments().await?;
command_result!(payments)
}
Command::ListRefundables => {
let refundables = sdk.list_refundables().await?;
command_result!(refundables)
}
Command::PrepareRefund {
swap_address,
refund_address,
sat_per_vbyte,
} => {
let res = sdk
.prepare_refund(&PrepareRefundRequest {
swap_address,
refund_address,
sat_per_vbyte,
})
.await?;
command_result!(res)
}
Command::Refund {
swap_address,
refund_address,
sat_per_vbyte,
} => {
let res = sdk
.refund(&RefundRequest {
swap_address,
refund_address,
sat_per_vbyte,
})
.await?;
command_result!(res)
}
Command::Sync => {
sdk.sync().await?;
command_result!("Synced successfully")

4
lib/Cargo.lock generated
View File

@@ -603,7 +603,7 @@ checksum = "829a082bd3761fde7476dc2ed85ca56c11628948460ece621e4f56fef5046567"
[[package]]
name = "boltz-client"
version = "0.1.3"
source = "git+https://github.com/dangeross/boltz-rust?rev=cb2cb02d44fb81cc8ce5d8000346f52cc26b3fc1#cb2cb02d44fb81cc8ce5d8000346f52cc26b3fc1"
source = "git+https://github.com/dangeross/boltz-rust?branch=savage-chain-swaps#0b6874c12332206b9821734561d4a140f6c0cfbb"
dependencies = [
"bip39",
"bitcoin 0.31.2",
@@ -1969,7 +1969,7 @@ dependencies = [
[[package]]
name = "lwk_wollet"
version = "0.5.1"
source = "git+https://github.com/Blockstream/lwk?rev=ffd793d0a1b1122c9bba7de23ccb73033eded98c#ffd793d0a1b1122c9bba7de23ccb73033eded98c"
source = "git+https://github.com/dangeross/lwk?branch=savage-try-headers-subscribe#ecf62efbbde5008301a329330d519e93e1e1b462"
dependencies = [
"aes-gcm-siv",
"base64 0.21.7",

View File

@@ -14,6 +14,8 @@ void store_dart_post_cobject(DartPostCObjectFnType ptr);
// EXTRA END
typedef struct _Dart_Handle* Dart_Handle;
#define LOWBALL_FEE_RATE_SAT_PER_VBYTE 0.01
/**
* The minimum acceptable fee rate when claiming using zero-conf
*/
@@ -89,19 +91,44 @@ typedef struct wire_cst_prepare_pay_onchain_request {
uint64_t amount_sat;
} wire_cst_prepare_pay_onchain_request;
typedef struct wire_cst_prepare_receive_onchain_request {
uint64_t amount_sat;
} wire_cst_prepare_receive_onchain_request;
typedef struct wire_cst_prepare_receive_request {
uint64_t payer_amount_sat;
} wire_cst_prepare_receive_request;
typedef struct wire_cst_prepare_refund_request {
struct wire_cst_list_prim_u_8_strict *swap_address;
struct wire_cst_list_prim_u_8_strict *refund_address;
uint32_t sat_per_vbyte;
} wire_cst_prepare_refund_request;
typedef struct wire_cst_prepare_send_request {
struct wire_cst_list_prim_u_8_strict *invoice;
} wire_cst_prepare_send_request;
typedef struct wire_cst_prepare_receive_onchain_response {
uint64_t amount_sat;
uint64_t fees_sat;
} wire_cst_prepare_receive_onchain_response;
typedef struct wire_cst_receive_onchain_request {
struct wire_cst_prepare_receive_onchain_response prepare_res;
} wire_cst_receive_onchain_request;
typedef struct wire_cst_prepare_receive_response {
uint64_t payer_amount_sat;
uint64_t fees_sat;
} wire_cst_prepare_receive_response;
typedef struct wire_cst_refund_request {
struct wire_cst_list_prim_u_8_strict *swap_address;
struct wire_cst_list_prim_u_8_strict *refund_address;
uint32_t sat_per_vbyte;
} wire_cst_refund_request;
typedef struct wire_cst_restore_request {
struct wire_cst_list_prim_u_8_strict *backup_path;
} wire_cst_restore_request;
@@ -308,6 +335,17 @@ typedef struct wire_cst_list_payment {
int32_t len;
} wire_cst_list_payment;
typedef struct wire_cst_refundable_swap {
struct wire_cst_list_prim_u_8_strict *swap_address;
uint32_t timestamp;
uint64_t amount_sat;
} wire_cst_refundable_swap;
typedef struct wire_cst_list_refundable_swap {
struct wire_cst_refundable_swap *ptr;
int32_t len;
} wire_cst_list_refundable_swap;
typedef struct wire_cst_get_info_response {
uint64_t balance_sat;
uint64_t pending_send_sat;
@@ -608,11 +646,25 @@ typedef struct wire_cst_payment_error {
union PaymentErrorKind kind;
} wire_cst_payment_error;
typedef struct wire_cst_prepare_refund_response {
uint32_t refund_tx_vsize;
uint64_t refund_tx_fee_sat;
} wire_cst_prepare_refund_response;
typedef struct wire_cst_receive_onchain_response {
struct wire_cst_list_prim_u_8_strict *address;
struct wire_cst_list_prim_u_8_strict *bip21;
} wire_cst_receive_onchain_response;
typedef struct wire_cst_receive_payment_response {
struct wire_cst_list_prim_u_8_strict *id;
struct wire_cst_list_prim_u_8_strict *invoice;
} wire_cst_receive_payment_response;
typedef struct wire_cst_refund_response {
struct wire_cst_list_prim_u_8_strict *refund_tx_id;
} wire_cst_refund_response;
typedef struct wire_cst_send_payment_response {
struct wire_cst_payment payment;
} wire_cst_send_payment_response;
@@ -635,6 +687,9 @@ void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_get_info(int64_
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_list_payments(int64_t port_,
uintptr_t that);
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_list_refundables(int64_t port_,
uintptr_t that);
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_lnurl_auth(int64_t port_,
uintptr_t that,
struct wire_cst_ln_url_auth_request_data *req_data);
@@ -655,18 +710,34 @@ void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_pay_onc
uintptr_t that,
struct wire_cst_prepare_pay_onchain_request *req);
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchain(int64_t port_,
uintptr_t that,
struct wire_cst_prepare_receive_onchain_request *req);
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_receive_payment(int64_t port_,
uintptr_t that,
struct wire_cst_prepare_receive_request *req);
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_refund(int64_t port_,
uintptr_t that,
struct wire_cst_prepare_refund_request *req);
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_send_payment(int64_t port_,
uintptr_t that,
struct wire_cst_prepare_send_request *req);
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_receive_onchain(int64_t port_,
uintptr_t that,
struct wire_cst_receive_onchain_request *req);
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_receive_payment(int64_t port_,
uintptr_t that,
struct wire_cst_prepare_receive_response *req);
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_refund(int64_t port_,
uintptr_t that,
struct wire_cst_refund_request *req);
WireSyncRust2DartDco frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_restore(uintptr_t that,
struct wire_cst_restore_request *req);
@@ -740,14 +811,22 @@ struct wire_cst_payment *frbgen_breez_liquid_cst_new_box_autoadd_payment(void);
struct wire_cst_prepare_pay_onchain_request *frbgen_breez_liquid_cst_new_box_autoadd_prepare_pay_onchain_request(void);
struct wire_cst_prepare_receive_onchain_request *frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_onchain_request(void);
struct wire_cst_prepare_receive_request *frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request(void);
struct wire_cst_prepare_receive_response *frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_response(void);
struct wire_cst_prepare_refund_request *frbgen_breez_liquid_cst_new_box_autoadd_prepare_refund_request(void);
struct wire_cst_prepare_send_request *frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_request(void);
struct wire_cst_prepare_send_response *frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_response(void);
struct wire_cst_receive_onchain_request *frbgen_breez_liquid_cst_new_box_autoadd_receive_onchain_request(void);
struct wire_cst_refund_request *frbgen_breez_liquid_cst_new_box_autoadd_refund_request(void);
struct wire_cst_restore_request *frbgen_breez_liquid_cst_new_box_autoadd_restore_request(void);
struct wire_cst_success_action_processed *frbgen_breez_liquid_cst_new_box_autoadd_success_action_processed(void);
@@ -760,6 +839,8 @@ struct wire_cst_list_payment *frbgen_breez_liquid_cst_new_list_payment(int32_t l
struct wire_cst_list_prim_u_8_strict *frbgen_breez_liquid_cst_new_list_prim_u_8_strict(int32_t len);
struct wire_cst_list_refundable_swap *frbgen_breez_liquid_cst_new_list_refundable_swap(int32_t len);
struct wire_cst_list_route_hint *frbgen_breez_liquid_cst_new_list_route_hint(int32_t len);
struct wire_cst_list_route_hint_hop *frbgen_breez_liquid_cst_new_list_route_hint_hop(int32_t len);
@@ -786,16 +867,21 @@ static int64_t dummy_method_to_enforce_bundling(void) {
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_pay_onchain_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_payment);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_pay_onchain_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_onchain_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_response);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_refund_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_response);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_receive_onchain_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_refund_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_restore_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_success_action_processed);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_u_64);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_url_success_action_data);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_list_payment);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_list_prim_u_8_strict);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_list_refundable_swap);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_list_route_hint);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_list_route_hint_hop);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_rust_arc_decrement_strong_count_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk);
@@ -806,14 +892,19 @@ static int64_t dummy_method_to_enforce_bundling(void) {
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_empty_wallet_cache);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_get_info);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_list_payments);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_list_refundables);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_lnurl_auth);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_lnurl_pay);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_lnurl_withdraw);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_pay_onchain);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_pay_onchain);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchain);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_receive_payment);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_refund);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_send_payment);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_receive_onchain);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_receive_payment);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_refund);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_restore);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_send_payment);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_sync);

View File

@@ -312,6 +312,24 @@ dictionary PayOnchainRequest {
PreparePayOnchainResponse prepare_res;
};
dictionary PrepareReceiveOnchainRequest {
u64 amount_sat;
};
dictionary PrepareReceiveOnchainResponse {
u64 amount_sat;
u64 fees_sat;
};
dictionary ReceiveOnchainRequest {
PrepareReceiveOnchainResponse prepare_res;
};
dictionary ReceiveOnchainResponse {
string address;
string bip21;
};
dictionary BackupRequest {
string? backup_path = null;
};
@@ -345,6 +363,34 @@ enum PaymentState {
"Complete",
"Failed",
"TimedOut",
"Refundable",
};
dictionary RefundableSwap {
string swap_address;
u32 timestamp;
u64 amount_sat;
};
dictionary PrepareRefundRequest {
string swap_address;
string refund_address;
u32 sat_per_vbyte;
};
dictionary PrepareRefundResponse {
u32 refund_tx_vsize;
u64 refund_tx_fee_sat;
};
dictionary RefundRequest {
string swap_address;
string refund_address;
u32 sat_per_vbyte;
};
dictionary RefundResponse {
string refund_tx_id;
};
[Enum]
@@ -415,9 +461,24 @@ interface BindingLiquidSdk {
[Throws=PaymentError]
SendPaymentResponse pay_onchain(PayOnchainRequest req);
[Throws=PaymentError]
PrepareReceiveOnchainResponse prepare_receive_onchain(PrepareReceiveOnchainRequest req);
[Throws=PaymentError]
ReceiveOnchainResponse receive_onchain(ReceiveOnchainRequest req);
[Throws=PaymentError]
sequence<Payment> list_payments();
[Throws=LiquidSdkError]
sequence<RefundableSwap> list_refundables();
[Throws=LiquidSdkError]
PrepareRefundResponse prepare_refund(PrepareRefundRequest req);
[Throws=PaymentError]
RefundResponse refund(RefundRequest req);
[Throws=LiquidSdkError]
void sync();

View File

@@ -132,6 +132,20 @@ impl BindingLiquidSdk {
rt().block_on(self.sdk.pay_onchain(&req))
}
pub fn prepare_receive_onchain(
&self,
req: PrepareReceiveOnchainRequest,
) -> Result<PrepareReceiveOnchainResponse, PaymentError> {
rt().block_on(self.sdk.prepare_receive_onchain(&req))
}
pub fn receive_onchain(
&self,
req: ReceiveOnchainRequest,
) -> Result<ReceiveOnchainResponse, PaymentError> {
rt().block_on(self.sdk.receive_onchain(&req))
}
pub fn list_payments(&self) -> Result<Vec<Payment>, PaymentError> {
rt().block_on(self.sdk.list_payments())
}
@@ -155,6 +169,21 @@ impl BindingLiquidSdk {
rt().block_on(self.sdk.lnurl_auth(req_data))
}
pub fn list_refundables(&self) -> LiquidSdkResult<Vec<RefundableSwap>> {
rt().block_on(self.sdk.list_refundables())
}
pub fn prepare_refund(
&self,
req: PrepareRefundRequest,
) -> LiquidSdkResult<PrepareRefundResponse> {
rt().block_on(self.sdk.prepare_refund(&req))
}
pub fn refund(&self, req: RefundRequest) -> Result<RefundResponse, PaymentError> {
rt().block_on(self.sdk.refund(&req))
}
pub fn sync(&self) -> LiquidSdkResult<()> {
rt().block_on(self.sdk.sync()).map_err(Into::into)
}

View File

@@ -15,7 +15,7 @@ frb = ["dep:flutter_rust_bridge"]
anyhow = { workspace = true }
bip39 = { version = "2.0.0", features = ["serde"] }
#boltz-client = { git = "https://github.com/SatoshiPortal/boltz-rust", rev = "a05731cc33030ada9ae14afcafe0cded22842ba6" }
boltz-client = { git = "https://github.com/dangeross/boltz-rust", rev = "cb2cb02d44fb81cc8ce5d8000346f52cc26b3fc1" }
boltz-client = { git = "https://github.com/dangeross/boltz-rust", branch = "savage-chain-swaps" }
chrono = "0.4"
env_logger = "0.11"
flutter_rust_bridge = { version = "=2.0.0", features = ["chrono"], optional = true }
@@ -23,7 +23,8 @@ log = { workspace = true }
lwk_common = "0.5.1"
lwk_signer = "0.5.1"
# Switch back to published version once this PR is merged and included in release: https://github.com/Blockstream/lwk/pull/34 (ETA in v0.5.2)
lwk_wollet = { git = "https://github.com/Blockstream/lwk", rev = "ffd793d0a1b1122c9bba7de23ccb73033eded98c" }
#lwk_wollet = { git = "https://github.com/Blockstream/lwk", rev = "ffd793d0a1b1122c9bba7de23ccb73033eded98c" }
lwk_wollet = { git = "https://github.com/dangeross/lwk", branch = "savage-try-headers-subscribe" }
#lwk_wollet = "0.5.1"
rusqlite = { version = "0.31", features = ["backup", "bundled"] }
rusqlite_migration = "1.0"

View File

@@ -139,6 +139,20 @@ impl BindingLiquidSdk {
self.sdk.pay_onchain(&req).await
}
pub async fn prepare_receive_onchain(
&self,
req: PrepareReceiveOnchainRequest,
) -> Result<PrepareReceiveOnchainResponse, PaymentError> {
self.sdk.prepare_receive_onchain(&req).await
}
pub async fn receive_onchain(
&self,
req: ReceiveOnchainRequest,
) -> Result<ReceiveOnchainResponse, PaymentError> {
self.sdk.receive_onchain(&req).await
}
pub async fn list_payments(&self) -> Result<Vec<Payment>, PaymentError> {
self.sdk.list_payments().await
}
@@ -172,6 +186,21 @@ impl BindingLiquidSdk {
.map_err(Into::into)
}
pub async fn list_refundables(&self) -> Result<Vec<RefundableSwap>, LiquidSdkError> {
self.sdk.list_refundables().await
}
pub async fn prepare_refund(
&self,
req: PrepareRefundRequest,
) -> Result<PrepareRefundResponse, LiquidSdkError> {
self.sdk.prepare_refund(&req).await
}
pub async fn refund(&self, req: RefundRequest) -> Result<RefundResponse, PaymentError> {
self.sdk.refund(&req).await
}
pub async fn sync(&self) -> Result<(), LiquidSdkError> {
self.sdk.sync().await.map_err(Into::into)
}

View File

@@ -9,7 +9,7 @@ use lwk_wollet::{
consensus::{deserialize, serialize},
BlockHash, Script, Transaction, Txid,
},
ElectrumUrl, History,
ElectrumOptions, ElectrumUrl, Error, History,
};
type Height = u32;
@@ -44,8 +44,13 @@ pub(crate) struct ElectrumClient {
tip: HeaderNotification,
}
impl ElectrumClient {
pub fn new(url: &ElectrumUrl) -> Result<Self> {
let client = url.build_client()?;
pub fn new(url: &ElectrumUrl) -> Result<Self, Error> {
Self::with_options(url, ElectrumOptions::default())
}
/// Creates an Electrum client specifying non default options like timeout
pub fn with_options(url: &ElectrumUrl, options: ElectrumOptions) -> Result<Self, Error> {
let client = url.build_client(&options)?;
let header = client.block_headers_subscribe_raw()?;
let tip: HeaderNotification = header.try_into()?;
@@ -60,9 +65,21 @@ impl BitcoinChainService for ElectrumClient {
maybe_popped_header = Some(header)
}
if let Some(popped_header) = maybe_popped_header {
let tip: HeaderNotification = popped_header.try_into()?;
self.tip = tip;
match maybe_popped_header {
Some(popped_header) => {
let tip: HeaderNotification = popped_header.try_into()?;
self.tip = tip;
}
None => {
// https://github.com/bitcoindevkit/rust-electrum-client/issues/124
// It might be that the client has reconnected and subscriptions don't persist
// across connections. Calling `client.ping()` won't help here because the
// successful retry will prevent us knowing about the reconnect.
if let Ok(header) = self.client.block_headers_subscribe_raw() {
let tip: HeaderNotification = header.try_into()?;
self.tip = tip;
}
}
}
Ok(self.tip.clone())

View File

@@ -121,6 +121,7 @@ impl From<EsploraTx> for History {
txid: value.txid,
height: status.block_height.unwrap_or_default(),
block_hash: status.block_hash,
block_timestamp: None,
}
}
}

View File

@@ -5,13 +5,13 @@ use boltz_client::swaps::boltzv2;
use boltz_client::swaps::{boltz::ChainSwapStates, boltzv2::CreateChainResponse};
use log::{debug, error, info, warn};
use lwk_wollet::elements::Transaction;
use lwk_wollet::ElectrumUrl;
use tokio::sync::{broadcast, Mutex};
use crate::chain::bitcoin::{BitcoinChainService, ElectrumClient};
use crate::chain::bitcoin::BitcoinChainService;
use crate::chain::liquid::LiquidChainService;
use crate::model::PaymentState::{Complete, Created, Failed, Pending, TimedOut};
use crate::model::{ChainSwap, Config, Direction, PaymentTxData, PaymentType};
use crate::error::{LiquidSdkError, LiquidSdkResult};
use crate::model::PaymentState::{Complete, Created, Failed, Pending, Refundable, TimedOut};
use crate::model::{ChainSwap, Direction, PaymentTxData, PaymentType};
use crate::swapper::Swapper;
use crate::wallet::OnchainWallet;
use crate::{error::PaymentError, model::PaymentState, persist::Persister};
@@ -27,18 +27,13 @@ pub(crate) struct ChainSwapStateHandler {
impl ChainSwapStateHandler {
pub(crate) fn new(
config: Config,
onchain_wallet: Arc<dyn OnchainWallet>,
persister: Arc<Persister>,
swapper: Arc<dyn Swapper>,
liquid_chain_service: Arc<Mutex<dyn LiquidChainService>>,
bitcoin_chain_service: Arc<Mutex<dyn BitcoinChainService>>,
) -> Result<Self> {
let (subscription_notifier, _) = broadcast::channel::<String>(30);
let bitcoin_chain_service = Arc::new(Mutex::new(ElectrumClient::new(&ElectrumUrl::new(
&config.bitcoin_electrum_url,
true,
true,
))?));
Ok(Self {
onchain_wallet,
persister,
@@ -139,14 +134,19 @@ impl ChainSwapStateHandler {
match swap.refund_tx_id.clone() {
None => {
warn!("Chain Swap {id} is in an unrecoverable state: {swap_state:?}");
match swap.user_lockup_tx_id.clone() {
// If there is a lockup tx when receiving we need to refund to a sender address
// TODO: Set the chain swap to refundable
Some(_) => {}
// No user lockup tx was broadcast when sending or receiving
None => {
warn!("Chain Swap {id} user lockup tx was never broadcast. Resolving payment as failed.");
match (swap.user_lockup_tx_id.clone(), swap_state) {
(Some(_), _) => {
info!("Chain Swap {id} user lockup tx was broadcast. Setting the swap to refundable.");
self.update_swap_info(id, Refundable, None, None, None, None)
.await?;
}
(None, ChainSwapStates::TransactionLockupFailed) => {
info!("Chain Swap {id} user lockup tx was broadcast but lockup has failed. Setting the swap to refundable.");
self.update_swap_info(id, Refundable, None, None, None, None)
.await?;
}
(None, _) => {
info!("Chain Swap {id} user lockup tx was never broadcast. Resolving payment as failed.");
self.update_swap_info(id, Failed, None, None, None, None)
.await?;
}
@@ -273,7 +273,7 @@ impl ChainSwapStateHandler {
match swap.user_lockup_tx_id.clone() {
Some(_) => {
warn!("Chain Swap {id} user lockup tx has been broadcast. Attempting refund.");
let refund_tx_id = self.refund(swap).await?;
let refund_tx_id = self.refund_outgoing_swap(swap).await?;
info!("Broadcast refund tx for Chain Swap {id}. Tx id: {refund_tx_id}");
self.update_swap_info(
id,
@@ -360,9 +360,12 @@ impl ChainSwapStateHandler {
.ok_or(PaymentError::Generic {
err: format!("Chain Swap not found {swap_id}"),
})?;
let payment_id = user_lockup_tx_id
.map(|c| c.to_string())
.or(swap.user_lockup_tx_id);
let payment_id = match swap.direction {
Direction::Incoming => claim_tx_id.map(|c| c.to_string()).or(swap.claim_tx_id),
Direction::Outgoing => user_lockup_tx_id
.map(|c| c.to_string())
.or(swap.user_lockup_tx_id),
};
Self::validate_state_transition(swap.state, to_state)?;
self.persister.try_handle_chain_swap_update(
@@ -381,8 +384,7 @@ impl ChainSwapStateHandler {
async fn claim(&self, chain_swap: &ChainSwap) -> Result<(), PaymentError> {
debug!("Initiating claim for Chain Swap {}", &chain_swap.id);
let refund_address = self.onchain_wallet.next_unused_address().await?.to_string();
let claim_tx_id = self.swapper.claim_chain_swap(chain_swap, refund_address)?;
let claim_tx_id = self.swapper.claim_chain_swap(chain_swap)?;
if chain_swap.direction == Direction::Incoming {
// We insert a pseudo-claim-tx in case LWK fails to pick up the new mempool tx for a while
@@ -409,58 +411,132 @@ impl ChainSwapStateHandler {
Ok(())
}
async fn refund(&self, swap: &ChainSwap) -> Result<String, PaymentError> {
let amount_sat = swap.receiver_amount_sat;
let output_address = self.onchain_wallet.next_unused_address().await?.to_string();
let fee = self
.onchain_wallet
.build_tx(None, &output_address, amount_sat)
.await?
.all_fees()
.values()
.sum();
let refund_res = self
.swapper
.refund_chain_swap_cooperative(swap, &output_address, fee);
match refund_res {
Ok(res) => Ok(res),
Err(e) => {
warn!("Cooperative refund failed: {:?}", e);
self.refund_non_cooperative(swap, fee).await
pub fn prepare_refund(
&self,
lockup_address: &str,
output_address: &str,
sat_per_vbyte: u32,
) -> LiquidSdkResult<(u32, u64)> {
let swap = self
.persister
.fetch_chain_swap_by_lockup_address(lockup_address)?
.ok_or(LiquidSdkError::Generic {
err: format!("Swap {} not found", lockup_address),
})?;
match swap.refund_tx_id {
Some(refund_tx_id) => Err(LiquidSdkError::Generic {
err: format!(
"Refund tx for Chain Swap {} was already broadcast: txid {refund_tx_id}",
swap.id
),
}),
None => {
self.swapper
.prepare_chain_swap_refund(&swap, output_address, sat_per_vbyte as f32)
}
}
}
async fn refund_non_cooperative(
pub(crate) async fn refund_incoming_swap(
&self,
lockup_address: &str,
output_address: &str,
sat_per_vbyte: u32,
) -> Result<String, PaymentError> {
let swap = self
.persister
.fetch_chain_swap_by_lockup_address(lockup_address)?
.ok_or(PaymentError::Generic {
err: format!("Swap {} not found", lockup_address),
})?;
match swap.refund_tx_id {
Some(refund_tx_id) => Err(PaymentError::Generic {
err: format!(
"Refund tx for Chain Swap {} was already broadcast: txid {refund_tx_id}",
swap.id
),
}),
None => {
let (_, broadcast_fees_sat) = self.swapper.prepare_chain_swap_refund(
&swap,
output_address,
sat_per_vbyte as f32,
)?;
let refund_res = self.swapper.refund_chain_swap_cooperative(
&swap,
output_address,
broadcast_fees_sat,
);
let refund_tx_id = match refund_res {
Ok(res) => Ok(res),
Err(e) => {
warn!("Cooperative refund failed: {:?}", e);
let current_height =
self.bitcoin_chain_service.lock().await.tip()?.height as u32;
self.swapper.refund_chain_swap_non_cooperative(
&swap,
broadcast_fees_sat,
output_address,
current_height,
)
}
}?;
info!(
"Broadcast refund tx for Chain Swap {}. Tx id: {refund_tx_id}",
swap.id
);
self.update_swap_info(&swap.id, Pending, None, None, None, Some(&refund_tx_id))
.await?;
Ok(refund_tx_id)
}
}
}
pub(crate) async fn refund_outgoing_swap(
&self,
swap: &ChainSwap,
broadcast_fees_sat: u64,
) -> Result<String, PaymentError> {
info!(
"Initiating non-cooperative refund for Chain Swap {}",
&swap.id
);
match swap.refund_tx_id.clone() {
Some(refund_tx_id) => Err(PaymentError::Generic {
err: format!(
"Refund tx for Chain Swap {} was already broadcast: txid {refund_tx_id}",
swap.id
),
}),
None => {
let output_address = self.onchain_wallet.next_unused_address().await?.to_string();
let (_, broadcast_fees_sat) =
self.swapper
.prepare_chain_swap_refund(swap, &output_address, 0.1)?;
let refund_res = self.swapper.refund_chain_swap_cooperative(
swap,
&output_address,
broadcast_fees_sat,
);
let refund_tx_id = match refund_res {
Ok(res) => Ok(res),
Err(e) => {
warn!("Cooperative refund failed: {:?}", e);
let current_height = self.liquid_chain_service.lock().await.tip().await?;
self.swapper.refund_chain_swap_non_cooperative(
swap,
broadcast_fees_sat,
&output_address,
current_height,
)
}
}?;
let current_height = match swap.direction {
Direction::Incoming => self.bitcoin_chain_service.lock().await.tip()?.height as u32,
Direction::Outgoing => self.liquid_chain_service.lock().await.tip().await?,
};
let output_address = self.onchain_wallet.next_unused_address().await?.to_string();
let refund_tx_id = self.swapper.refund_chain_swap_non_cooperative(
swap,
broadcast_fees_sat,
&output_address,
current_height,
)?;
info!(
"Successfully broadcast non-cooperative refund for Chain Swap {}, tx: {}",
swap.id, refund_tx_id
);
Ok(refund_tx_id)
info!(
"Broadcast refund tx for Chain Swap {}. Tx id: {refund_tx_id}",
swap.id
);
self.update_swap_info(&swap.id, Pending, None, None, None, Some(&refund_tx_id))
.await?;
Ok(refund_tx_id)
}
}
}
fn validate_state_transition(
@@ -472,13 +548,13 @@ impl ChainSwapStateHandler {
err: "Cannot transition to Created state".to_string(),
}),
(Created | Pending, Pending) => Ok(()),
(Complete | Failed | TimedOut, Pending) => Err(PaymentError::Generic {
(Created | Pending | Refundable, Pending) => Ok(()),
(_, Pending) => Err(PaymentError::Generic {
err: format!("Cannot transition from {from_state:?} to Pending state"),
}),
(Created | Pending, Complete) => Ok(()),
(Complete | Failed | TimedOut, Complete) => Err(PaymentError::Generic {
(_, Complete) => Err(PaymentError::Generic {
err: format!("Cannot transition from {from_state:?} to Complete state"),
}),
@@ -487,9 +563,15 @@ impl ChainSwapStateHandler {
err: format!("Cannot transition from {from_state:?} to TimedOut state"),
}),
(Created | Pending, Refundable) => Ok(()),
(_, Refundable) => Err(PaymentError::Generic {
err: format!("Cannot transition from {from_state:?} to Refundable state"),
}),
(Complete, Failed) => Err(PaymentError::Generic {
err: format!("Cannot transition from {from_state:?} to Failed state"),
}),
(_, Failed) => Ok(()),
}
}
@@ -521,11 +603,15 @@ mod tests {
let valid_combinations = HashMap::from([
(
Created,
HashSet::from([Pending, Complete, TimedOut, Failed]),
HashSet::from([Pending, Complete, TimedOut, Refundable, Failed]),
),
(
Pending,
HashSet::from([Pending, Complete, Refundable, Failed]),
),
(Pending, HashSet::from([Pending, Complete, Failed])),
(TimedOut, HashSet::from([Failed])),
(Complete, HashSet::from([])),
(Refundable, HashSet::from([Pending, Failed])),
(Failed, HashSet::from([Failed])),
]);

View File

@@ -1,4 +1,5 @@
use anyhow::Error;
use lwk_wollet::secp256k1;
use sdk_common::prelude::LnUrlAuthError;
pub type LiquidSdkResult<T, E = LiquidSdkError> = Result<T, E>;
@@ -34,6 +35,27 @@ impl From<anyhow::Error> for LiquidSdkError {
}
}
impl From<boltz_client::error::Error> for LiquidSdkError {
fn from(err: boltz_client::error::Error) -> Self {
match err {
boltz_client::error::Error::HTTP(e) => LiquidSdkError::Generic {
err: format!("Could not contact servers: {e:?}"),
},
_ => LiquidSdkError::Generic {
err: format!("{err:?}"),
},
}
}
}
impl From<secp256k1::Error> for LiquidSdkError {
fn from(err: secp256k1::Error) -> Self {
LiquidSdkError::Generic {
err: format!("{err:?}"),
}
}
}
#[derive(thiserror::Error, Debug)]
pub enum PaymentError {
#[error("The specified funds have already been claimed")]

View File

@@ -301,6 +301,15 @@ impl CstDecode<crate::model::PreparePayOnchainRequest>
CstDecode::<crate::model::PreparePayOnchainRequest>::cst_decode(*wrap).into()
}
}
impl CstDecode<crate::model::PrepareReceiveOnchainRequest>
for *mut wire_cst_prepare_receive_onchain_request
{
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::PrepareReceiveOnchainRequest {
let wrap = unsafe { flutter_rust_bridge::for_generated::box_from_leak_ptr(self) };
CstDecode::<crate::model::PrepareReceiveOnchainRequest>::cst_decode(*wrap).into()
}
}
impl CstDecode<crate::model::PrepareReceiveRequest> for *mut wire_cst_prepare_receive_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::PrepareReceiveRequest {
@@ -315,6 +324,13 @@ impl CstDecode<crate::model::PrepareReceiveResponse> for *mut wire_cst_prepare_r
CstDecode::<crate::model::PrepareReceiveResponse>::cst_decode(*wrap).into()
}
}
impl CstDecode<crate::model::PrepareRefundRequest> for *mut wire_cst_prepare_refund_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::PrepareRefundRequest {
let wrap = unsafe { flutter_rust_bridge::for_generated::box_from_leak_ptr(self) };
CstDecode::<crate::model::PrepareRefundRequest>::cst_decode(*wrap).into()
}
}
impl CstDecode<crate::model::PrepareSendRequest> for *mut wire_cst_prepare_send_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::PrepareSendRequest {
@@ -329,6 +345,20 @@ impl CstDecode<crate::model::PrepareSendResponse> for *mut wire_cst_prepare_send
CstDecode::<crate::model::PrepareSendResponse>::cst_decode(*wrap).into()
}
}
impl CstDecode<crate::model::ReceiveOnchainRequest> for *mut wire_cst_receive_onchain_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::ReceiveOnchainRequest {
let wrap = unsafe { flutter_rust_bridge::for_generated::box_from_leak_ptr(self) };
CstDecode::<crate::model::ReceiveOnchainRequest>::cst_decode(*wrap).into()
}
}
impl CstDecode<crate::model::RefundRequest> for *mut wire_cst_refund_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::RefundRequest {
let wrap = unsafe { flutter_rust_bridge::for_generated::box_from_leak_ptr(self) };
CstDecode::<crate::model::RefundRequest>::cst_decode(*wrap).into()
}
}
impl CstDecode<crate::model::RestoreRequest> for *mut wire_cst_restore_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::RestoreRequest {
@@ -533,6 +563,16 @@ impl CstDecode<Vec<u8>> for *mut wire_cst_list_prim_u_8_strict {
}
}
}
impl CstDecode<Vec<crate::model::RefundableSwap>> for *mut wire_cst_list_refundable_swap {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> Vec<crate::model::RefundableSwap> {
let vec = unsafe {
let wrap = flutter_rust_bridge::for_generated::box_from_leak_ptr(self);
flutter_rust_bridge::for_generated::vec_from_leak_ptr(wrap.ptr, wrap.len)
};
vec.into_iter().map(CstDecode::cst_decode).collect()
}
}
impl CstDecode<Vec<crate::bindings::RouteHint>> for *mut wire_cst_list_route_hint {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> Vec<crate::bindings::RouteHint> {
@@ -1003,6 +1043,27 @@ impl CstDecode<crate::model::PreparePayOnchainResponse> for wire_cst_prepare_pay
}
}
}
impl CstDecode<crate::model::PrepareReceiveOnchainRequest>
for wire_cst_prepare_receive_onchain_request
{
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::PrepareReceiveOnchainRequest {
crate::model::PrepareReceiveOnchainRequest {
amount_sat: self.amount_sat.cst_decode(),
}
}
}
impl CstDecode<crate::model::PrepareReceiveOnchainResponse>
for wire_cst_prepare_receive_onchain_response
{
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::PrepareReceiveOnchainResponse {
crate::model::PrepareReceiveOnchainResponse {
amount_sat: self.amount_sat.cst_decode(),
fees_sat: self.fees_sat.cst_decode(),
}
}
}
impl CstDecode<crate::model::PrepareReceiveRequest> for wire_cst_prepare_receive_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::PrepareReceiveRequest {
@@ -1020,6 +1081,25 @@ impl CstDecode<crate::model::PrepareReceiveResponse> for wire_cst_prepare_receiv
}
}
}
impl CstDecode<crate::model::PrepareRefundRequest> for wire_cst_prepare_refund_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::PrepareRefundRequest {
crate::model::PrepareRefundRequest {
swap_address: self.swap_address.cst_decode(),
refund_address: self.refund_address.cst_decode(),
sat_per_vbyte: self.sat_per_vbyte.cst_decode(),
}
}
}
impl CstDecode<crate::model::PrepareRefundResponse> for wire_cst_prepare_refund_response {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::PrepareRefundResponse {
crate::model::PrepareRefundResponse {
refund_tx_vsize: self.refund_tx_vsize.cst_decode(),
refund_tx_fee_sat: self.refund_tx_fee_sat.cst_decode(),
}
}
}
impl CstDecode<crate::model::PrepareSendRequest> for wire_cst_prepare_send_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::PrepareSendRequest {
@@ -1037,6 +1117,23 @@ impl CstDecode<crate::model::PrepareSendResponse> for wire_cst_prepare_send_resp
}
}
}
impl CstDecode<crate::model::ReceiveOnchainRequest> for wire_cst_receive_onchain_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::ReceiveOnchainRequest {
crate::model::ReceiveOnchainRequest {
prepare_res: self.prepare_res.cst_decode(),
}
}
}
impl CstDecode<crate::model::ReceiveOnchainResponse> for wire_cst_receive_onchain_response {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::ReceiveOnchainResponse {
crate::model::ReceiveOnchainResponse {
address: self.address.cst_decode(),
bip21: self.bip21.cst_decode(),
}
}
}
impl CstDecode<crate::model::ReceivePaymentResponse> for wire_cst_receive_payment_response {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::ReceivePaymentResponse {
@@ -1046,6 +1143,34 @@ impl CstDecode<crate::model::ReceivePaymentResponse> for wire_cst_receive_paymen
}
}
}
impl CstDecode<crate::model::RefundRequest> for wire_cst_refund_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::RefundRequest {
crate::model::RefundRequest {
swap_address: self.swap_address.cst_decode(),
refund_address: self.refund_address.cst_decode(),
sat_per_vbyte: self.sat_per_vbyte.cst_decode(),
}
}
}
impl CstDecode<crate::model::RefundResponse> for wire_cst_refund_response {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::RefundResponse {
crate::model::RefundResponse {
refund_tx_id: self.refund_tx_id.cst_decode(),
}
}
}
impl CstDecode<crate::model::RefundableSwap> for wire_cst_refundable_swap {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::RefundableSwap {
crate::model::RefundableSwap {
swap_address: self.swap_address.cst_decode(),
timestamp: self.timestamp.cst_decode(),
amount_sat: self.amount_sat.cst_decode(),
}
}
}
impl CstDecode<crate::model::RestoreRequest> for wire_cst_restore_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::RestoreRequest {
@@ -1600,6 +1725,31 @@ impl Default for wire_cst_prepare_pay_onchain_response {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_prepare_receive_onchain_request {
fn new_with_null_ptr() -> Self {
Self {
amount_sat: Default::default(),
}
}
}
impl Default for wire_cst_prepare_receive_onchain_request {
fn default() -> Self {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_prepare_receive_onchain_response {
fn new_with_null_ptr() -> Self {
Self {
amount_sat: Default::default(),
fees_sat: Default::default(),
}
}
}
impl Default for wire_cst_prepare_receive_onchain_response {
fn default() -> Self {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_prepare_receive_request {
fn new_with_null_ptr() -> Self {
Self {
@@ -1625,6 +1775,33 @@ impl Default for wire_cst_prepare_receive_response {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_prepare_refund_request {
fn new_with_null_ptr() -> Self {
Self {
swap_address: core::ptr::null_mut(),
refund_address: core::ptr::null_mut(),
sat_per_vbyte: Default::default(),
}
}
}
impl Default for wire_cst_prepare_refund_request {
fn default() -> Self {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_prepare_refund_response {
fn new_with_null_ptr() -> Self {
Self {
refund_tx_vsize: Default::default(),
refund_tx_fee_sat: Default::default(),
}
}
}
impl Default for wire_cst_prepare_refund_response {
fn default() -> Self {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_prepare_send_request {
fn new_with_null_ptr() -> Self {
Self {
@@ -1650,6 +1827,31 @@ impl Default for wire_cst_prepare_send_response {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_receive_onchain_request {
fn new_with_null_ptr() -> Self {
Self {
prepare_res: Default::default(),
}
}
}
impl Default for wire_cst_receive_onchain_request {
fn default() -> Self {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_receive_onchain_response {
fn new_with_null_ptr() -> Self {
Self {
address: core::ptr::null_mut(),
bip21: core::ptr::null_mut(),
}
}
}
impl Default for wire_cst_receive_onchain_response {
fn default() -> Self {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_receive_payment_response {
fn new_with_null_ptr() -> Self {
Self {
@@ -1663,6 +1865,46 @@ impl Default for wire_cst_receive_payment_response {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_refund_request {
fn new_with_null_ptr() -> Self {
Self {
swap_address: core::ptr::null_mut(),
refund_address: core::ptr::null_mut(),
sat_per_vbyte: Default::default(),
}
}
}
impl Default for wire_cst_refund_request {
fn default() -> Self {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_refund_response {
fn new_with_null_ptr() -> Self {
Self {
refund_tx_id: core::ptr::null_mut(),
}
}
}
impl Default for wire_cst_refund_response {
fn default() -> Self {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_refundable_swap {
fn new_with_null_ptr() -> Self {
Self {
swap_address: core::ptr::null_mut(),
timestamp: Default::default(),
amount_sat: Default::default(),
}
}
}
impl Default for wire_cst_refundable_swap {
fn default() -> Self {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_restore_request {
fn new_with_null_ptr() -> Self {
Self {
@@ -1792,6 +2034,14 @@ pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_li
wire__crate__bindings__BindingLiquidSdk_list_payments_impl(port_, that)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_list_refundables(
port_: i64,
that: usize,
) {
wire__crate__bindings__BindingLiquidSdk_list_refundables_impl(port_, that)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_lnurl_auth(
port_: i64,
@@ -1837,6 +2087,15 @@ pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_pr
wire__crate__bindings__BindingLiquidSdk_prepare_pay_onchain_impl(port_, that, req)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchain(
port_: i64,
that: usize,
req: *mut wire_cst_prepare_receive_onchain_request,
) {
wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchain_impl(port_, that, req)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_receive_payment(
port_: i64,
@@ -1846,6 +2105,15 @@ pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_pr
wire__crate__bindings__BindingLiquidSdk_prepare_receive_payment_impl(port_, that, req)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_refund(
port_: i64,
that: usize,
req: *mut wire_cst_prepare_refund_request,
) {
wire__crate__bindings__BindingLiquidSdk_prepare_refund_impl(port_, that, req)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_send_payment(
port_: i64,
@@ -1855,6 +2123,15 @@ pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_pr
wire__crate__bindings__BindingLiquidSdk_prepare_send_payment_impl(port_, that, req)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_receive_onchain(
port_: i64,
that: usize,
req: *mut wire_cst_receive_onchain_request,
) {
wire__crate__bindings__BindingLiquidSdk_receive_onchain_impl(port_, that, req)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_receive_payment(
port_: i64,
@@ -1864,6 +2141,15 @@ pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_re
wire__crate__bindings__BindingLiquidSdk_receive_payment_impl(port_, that, req)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_refund(
port_: i64,
that: usize,
req: *mut wire_cst_refund_request,
) {
wire__crate__bindings__BindingLiquidSdk_refund_impl(port_, that, req)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_restore(
that: usize,
@@ -2116,6 +2402,14 @@ pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_prepare_pay_onchain_re
)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_onchain_request(
) -> *mut wire_cst_prepare_receive_onchain_request {
flutter_rust_bridge::for_generated::new_leak_box_ptr(
wire_cst_prepare_receive_onchain_request::new_with_null_ptr(),
)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request(
) -> *mut wire_cst_prepare_receive_request {
@@ -2132,6 +2426,14 @@ pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_respon
)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_prepare_refund_request(
) -> *mut wire_cst_prepare_refund_request {
flutter_rust_bridge::for_generated::new_leak_box_ptr(
wire_cst_prepare_refund_request::new_with_null_ptr(),
)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_request(
) -> *mut wire_cst_prepare_send_request {
@@ -2148,6 +2450,22 @@ pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_response(
)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_receive_onchain_request(
) -> *mut wire_cst_receive_onchain_request {
flutter_rust_bridge::for_generated::new_leak_box_ptr(
wire_cst_receive_onchain_request::new_with_null_ptr(),
)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_refund_request(
) -> *mut wire_cst_refund_request {
flutter_rust_bridge::for_generated::new_leak_box_ptr(
wire_cst_refund_request::new_with_null_ptr(),
)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_restore_request(
) -> *mut wire_cst_restore_request {
@@ -2200,6 +2518,20 @@ pub extern "C" fn frbgen_breez_liquid_cst_new_list_prim_u_8_strict(
flutter_rust_bridge::for_generated::new_leak_box_ptr(ans)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_list_refundable_swap(
len: i32,
) -> *mut wire_cst_list_refundable_swap {
let wrap = wire_cst_list_refundable_swap {
ptr: flutter_rust_bridge::for_generated::new_leak_vec_ptr(
<wire_cst_refundable_swap>::new_with_null_ptr(),
len,
),
len,
};
flutter_rust_bridge::for_generated::new_leak_box_ptr(wrap)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_list_route_hint(
len: i32,
@@ -2445,6 +2777,12 @@ pub struct wire_cst_list_prim_u_8_strict {
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_list_refundable_swap {
ptr: *mut wire_cst_refundable_swap,
len: i32,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_list_route_hint {
ptr: *mut wire_cst_route_hint,
len: i32,
@@ -2859,6 +3197,17 @@ pub struct wire_cst_prepare_pay_onchain_response {
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_prepare_receive_onchain_request {
amount_sat: u64,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_prepare_receive_onchain_response {
amount_sat: u64,
fees_sat: u64,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_prepare_receive_request {
payer_amount_sat: u64,
}
@@ -2870,6 +3219,19 @@ pub struct wire_cst_prepare_receive_response {
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_prepare_refund_request {
swap_address: *mut wire_cst_list_prim_u_8_strict,
refund_address: *mut wire_cst_list_prim_u_8_strict,
sat_per_vbyte: u32,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_prepare_refund_response {
refund_tx_vsize: u32,
refund_tx_fee_sat: u64,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_prepare_send_request {
invoice: *mut wire_cst_list_prim_u_8_strict,
}
@@ -2881,12 +3243,42 @@ pub struct wire_cst_prepare_send_response {
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_receive_onchain_request {
prepare_res: wire_cst_prepare_receive_onchain_response,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_receive_onchain_response {
address: *mut wire_cst_list_prim_u_8_strict,
bip21: *mut wire_cst_list_prim_u_8_strict,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_receive_payment_response {
id: *mut wire_cst_list_prim_u_8_strict,
invoice: *mut wire_cst_list_prim_u_8_strict,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_refund_request {
swap_address: *mut wire_cst_list_prim_u_8_strict,
refund_address: *mut wire_cst_list_prim_u_8_strict,
sat_per_vbyte: u32,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_refund_response {
refund_tx_id: *mut wire_cst_list_prim_u_8_strict,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_refundable_swap {
swap_address: *mut wire_cst_list_prim_u_8_strict,
timestamp: u32,
amount_sat: u64,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_restore_request {
backup_path: *mut wire_cst_list_prim_u_8_strict,
}

View File

@@ -39,7 +39,7 @@ flutter_rust_bridge::frb_generated_boilerplate!(
default_rust_auto_opaque = RustAutoOpaqueNom,
);
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_VERSION: &str = "2.0.0";
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 540580972;
pub(crate) const FLUTTER_RUST_BRIDGE_CODEGEN_CONTENT_HASH: i32 = 671987080;
// Section: executor
@@ -303,6 +303,51 @@ fn wire__crate__bindings__BindingLiquidSdk_list_payments_impl(
},
)
}
fn wire__crate__bindings__BindingLiquidSdk_list_refundables_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
that: impl CstDecode<
RustOpaqueNom<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BindingLiquidSdk>>,
>,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::DcoCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "BindingLiquidSdk_list_refundables",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let api_that = that.cst_decode();
move |context| async move {
transform_result_dco::<_, _, crate::error::LiquidSdkError>(
(move || async move {
let mut api_that_guard = None;
let decode_indices_ =
flutter_rust_bridge::for_generated::lockable_compute_decode_order(
vec![flutter_rust_bridge::for_generated::LockableOrderInfo::new(
&api_that, 0, false,
)],
);
for i in decode_indices_ {
match i {
0 => {
api_that_guard =
Some(api_that.lockable_decode_async_ref().await)
}
_ => unreachable!(),
}
}
let api_that_guard = api_that_guard.unwrap();
let output_ok =
crate::bindings::BindingLiquidSdk::list_refundables(&*api_that_guard)
.await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__bindings__BindingLiquidSdk_lnurl_auth_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
that: impl CstDecode<
@@ -546,6 +591,55 @@ fn wire__crate__bindings__BindingLiquidSdk_prepare_pay_onchain_impl(
},
)
}
fn wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchain_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
that: impl CstDecode<
RustOpaqueNom<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BindingLiquidSdk>>,
>,
req: impl CstDecode<crate::model::PrepareReceiveOnchainRequest>,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::DcoCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "BindingLiquidSdk_prepare_receive_onchain",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let api_that = that.cst_decode();
let api_req = req.cst_decode();
move |context| async move {
transform_result_dco::<_, _, crate::error::PaymentError>(
(move || async move {
let mut api_that_guard = None;
let decode_indices_ =
flutter_rust_bridge::for_generated::lockable_compute_decode_order(
vec![flutter_rust_bridge::for_generated::LockableOrderInfo::new(
&api_that, 0, false,
)],
);
for i in decode_indices_ {
match i {
0 => {
api_that_guard =
Some(api_that.lockable_decode_async_ref().await)
}
_ => unreachable!(),
}
}
let api_that_guard = api_that_guard.unwrap();
let output_ok = crate::bindings::BindingLiquidSdk::prepare_receive_onchain(
&*api_that_guard,
api_req,
)
.await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__bindings__BindingLiquidSdk_prepare_receive_payment_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
that: impl CstDecode<
@@ -595,6 +689,55 @@ fn wire__crate__bindings__BindingLiquidSdk_prepare_receive_payment_impl(
},
)
}
fn wire__crate__bindings__BindingLiquidSdk_prepare_refund_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
that: impl CstDecode<
RustOpaqueNom<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BindingLiquidSdk>>,
>,
req: impl CstDecode<crate::model::PrepareRefundRequest>,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::DcoCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "BindingLiquidSdk_prepare_refund",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let api_that = that.cst_decode();
let api_req = req.cst_decode();
move |context| async move {
transform_result_dco::<_, _, crate::error::LiquidSdkError>(
(move || async move {
let mut api_that_guard = None;
let decode_indices_ =
flutter_rust_bridge::for_generated::lockable_compute_decode_order(
vec![flutter_rust_bridge::for_generated::LockableOrderInfo::new(
&api_that, 0, false,
)],
);
for i in decode_indices_ {
match i {
0 => {
api_that_guard =
Some(api_that.lockable_decode_async_ref().await)
}
_ => unreachable!(),
}
}
let api_that_guard = api_that_guard.unwrap();
let output_ok = crate::bindings::BindingLiquidSdk::prepare_refund(
&*api_that_guard,
api_req,
)
.await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__bindings__BindingLiquidSdk_prepare_send_payment_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
that: impl CstDecode<
@@ -644,6 +787,55 @@ fn wire__crate__bindings__BindingLiquidSdk_prepare_send_payment_impl(
},
)
}
fn wire__crate__bindings__BindingLiquidSdk_receive_onchain_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
that: impl CstDecode<
RustOpaqueNom<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BindingLiquidSdk>>,
>,
req: impl CstDecode<crate::model::ReceiveOnchainRequest>,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::DcoCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "BindingLiquidSdk_receive_onchain",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let api_that = that.cst_decode();
let api_req = req.cst_decode();
move |context| async move {
transform_result_dco::<_, _, crate::error::PaymentError>(
(move || async move {
let mut api_that_guard = None;
let decode_indices_ =
flutter_rust_bridge::for_generated::lockable_compute_decode_order(
vec![flutter_rust_bridge::for_generated::LockableOrderInfo::new(
&api_that, 0, false,
)],
);
for i in decode_indices_ {
match i {
0 => {
api_that_guard =
Some(api_that.lockable_decode_async_ref().await)
}
_ => unreachable!(),
}
}
let api_that_guard = api_that_guard.unwrap();
let output_ok = crate::bindings::BindingLiquidSdk::receive_onchain(
&*api_that_guard,
api_req,
)
.await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__bindings__BindingLiquidSdk_receive_payment_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
that: impl CstDecode<
@@ -693,6 +885,53 @@ fn wire__crate__bindings__BindingLiquidSdk_receive_payment_impl(
},
)
}
fn wire__crate__bindings__BindingLiquidSdk_refund_impl(
port_: flutter_rust_bridge::for_generated::MessagePort,
that: impl CstDecode<
RustOpaqueNom<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BindingLiquidSdk>>,
>,
req: impl CstDecode<crate::model::RefundRequest>,
) {
FLUTTER_RUST_BRIDGE_HANDLER.wrap_async::<flutter_rust_bridge::for_generated::DcoCodec, _, _, _>(
flutter_rust_bridge::for_generated::TaskInfo {
debug_name: "BindingLiquidSdk_refund",
port: Some(port_),
mode: flutter_rust_bridge::for_generated::FfiCallMode::Normal,
},
move || {
let api_that = that.cst_decode();
let api_req = req.cst_decode();
move |context| async move {
transform_result_dco::<_, _, crate::error::PaymentError>(
(move || async move {
let mut api_that_guard = None;
let decode_indices_ =
flutter_rust_bridge::for_generated::lockable_compute_decode_order(
vec![flutter_rust_bridge::for_generated::LockableOrderInfo::new(
&api_that, 0, false,
)],
);
for i in decode_indices_ {
match i {
0 => {
api_that_guard =
Some(api_that.lockable_decode_async_ref().await)
}
_ => unreachable!(),
}
}
let api_that_guard = api_that_guard.unwrap();
let output_ok =
crate::bindings::BindingLiquidSdk::refund(&*api_that_guard, api_req)
.await?;
Ok(output_ok)
})()
.await,
)
}
},
)
}
fn wire__crate__bindings__BindingLiquidSdk_restore_impl(
that: impl CstDecode<
RustOpaqueNom<flutter_rust_bridge::for_generated::RustAutoOpaqueInner<BindingLiquidSdk>>,
@@ -1159,6 +1398,7 @@ impl CstDecode<crate::model::PaymentState> for i32 {
2 => crate::model::PaymentState::Complete,
3 => crate::model::PaymentState::Failed,
4 => crate::model::PaymentState::TimedOut,
5 => crate::model::PaymentState::Refundable,
_ => unreachable!("Invalid variant for PaymentState: {}", self),
}
}
@@ -1572,6 +1812,18 @@ impl SseDecode for Vec<u8> {
}
}
impl SseDecode for Vec<crate::model::RefundableSwap> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut len_ = <i32>::sse_decode(deserializer);
let mut ans_ = vec![];
for idx_ in 0..len_ {
ans_.push(<crate::model::RefundableSwap>::sse_decode(deserializer));
}
return ans_;
}
}
impl SseDecode for Vec<crate::bindings::RouteHint> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -2167,6 +2419,7 @@ impl SseDecode for crate::model::PaymentState {
2 => crate::model::PaymentState::Complete,
3 => crate::model::PaymentState::Failed,
4 => crate::model::PaymentState::TimedOut,
5 => crate::model::PaymentState::Refundable,
_ => unreachable!("Invalid variant for PaymentState: {}", inner),
};
}
@@ -2206,6 +2459,28 @@ impl SseDecode for crate::model::PreparePayOnchainResponse {
}
}
impl SseDecode for crate::model::PrepareReceiveOnchainRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_amountSat = <u64>::sse_decode(deserializer);
return crate::model::PrepareReceiveOnchainRequest {
amount_sat: var_amountSat,
};
}
}
impl SseDecode for crate::model::PrepareReceiveOnchainResponse {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_amountSat = <u64>::sse_decode(deserializer);
let mut var_feesSat = <u64>::sse_decode(deserializer);
return crate::model::PrepareReceiveOnchainResponse {
amount_sat: var_amountSat,
fees_sat: var_feesSat,
};
}
}
impl SseDecode for crate::model::PrepareReceiveRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -2228,6 +2503,32 @@ impl SseDecode for crate::model::PrepareReceiveResponse {
}
}
impl SseDecode for crate::model::PrepareRefundRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_swapAddress = <String>::sse_decode(deserializer);
let mut var_refundAddress = <String>::sse_decode(deserializer);
let mut var_satPerVbyte = <u32>::sse_decode(deserializer);
return crate::model::PrepareRefundRequest {
swap_address: var_swapAddress,
refund_address: var_refundAddress,
sat_per_vbyte: var_satPerVbyte,
};
}
}
impl SseDecode for crate::model::PrepareRefundResponse {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_refundTxVsize = <u32>::sse_decode(deserializer);
let mut var_refundTxFeeSat = <u64>::sse_decode(deserializer);
return crate::model::PrepareRefundResponse {
refund_tx_vsize: var_refundTxVsize,
refund_tx_fee_sat: var_refundTxFeeSat,
};
}
}
impl SseDecode for crate::model::PrepareSendRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -2250,6 +2551,29 @@ impl SseDecode for crate::model::PrepareSendResponse {
}
}
impl SseDecode for crate::model::ReceiveOnchainRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_prepareRes =
<crate::model::PrepareReceiveOnchainResponse>::sse_decode(deserializer);
return crate::model::ReceiveOnchainRequest {
prepare_res: var_prepareRes,
};
}
}
impl SseDecode for crate::model::ReceiveOnchainResponse {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_address = <String>::sse_decode(deserializer);
let mut var_bip21 = <String>::sse_decode(deserializer);
return crate::model::ReceiveOnchainResponse {
address: var_address,
bip21: var_bip21,
};
}
}
impl SseDecode for crate::model::ReceivePaymentResponse {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -2262,6 +2586,44 @@ impl SseDecode for crate::model::ReceivePaymentResponse {
}
}
impl SseDecode for crate::model::RefundRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_swapAddress = <String>::sse_decode(deserializer);
let mut var_refundAddress = <String>::sse_decode(deserializer);
let mut var_satPerVbyte = <u32>::sse_decode(deserializer);
return crate::model::RefundRequest {
swap_address: var_swapAddress,
refund_address: var_refundAddress,
sat_per_vbyte: var_satPerVbyte,
};
}
}
impl SseDecode for crate::model::RefundResponse {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_refundTxId = <String>::sse_decode(deserializer);
return crate::model::RefundResponse {
refund_tx_id: var_refundTxId,
};
}
}
impl SseDecode for crate::model::RefundableSwap {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_swapAddress = <String>::sse_decode(deserializer);
let mut var_timestamp = <u32>::sse_decode(deserializer);
let mut var_amountSat = <u64>::sse_decode(deserializer);
return crate::model::RefundableSwap {
swap_address: var_swapAddress,
timestamp: var_timestamp,
amount_sat: var_amountSat,
};
}
}
impl SseDecode for crate::model::RestoreRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -3317,6 +3679,7 @@ impl flutter_rust_bridge::IntoDart for crate::model::PaymentState {
Self::Complete => 2.into_dart(),
Self::Failed => 3.into_dart(),
Self::TimedOut => 4.into_dart(),
Self::Refundable => 5.into_dart(),
_ => unreachable!(),
}
}
@@ -3382,6 +3745,44 @@ impl flutter_rust_bridge::IntoIntoDart<crate::model::PreparePayOnchainResponse>
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::PrepareReceiveOnchainRequest {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[self.amount_sat.into_into_dart().into_dart()].into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
for crate::model::PrepareReceiveOnchainRequest
{
}
impl flutter_rust_bridge::IntoIntoDart<crate::model::PrepareReceiveOnchainRequest>
for crate::model::PrepareReceiveOnchainRequest
{
fn into_into_dart(self) -> crate::model::PrepareReceiveOnchainRequest {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::PrepareReceiveOnchainResponse {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.amount_sat.into_into_dart().into_dart(),
self.fees_sat.into_into_dart().into_dart(),
]
.into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
for crate::model::PrepareReceiveOnchainResponse
{
}
impl flutter_rust_bridge::IntoIntoDart<crate::model::PrepareReceiveOnchainResponse>
for crate::model::PrepareReceiveOnchainResponse
{
fn into_into_dart(self) -> crate::model::PrepareReceiveOnchainResponse {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::PrepareReceiveRequest {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[self.payer_amount_sat.into_into_dart().into_dart()].into_dart()
@@ -3420,6 +3821,49 @@ impl flutter_rust_bridge::IntoIntoDart<crate::model::PrepareReceiveResponse>
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::PrepareRefundRequest {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.swap_address.into_into_dart().into_dart(),
self.refund_address.into_into_dart().into_dart(),
self.sat_per_vbyte.into_into_dart().into_dart(),
]
.into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
for crate::model::PrepareRefundRequest
{
}
impl flutter_rust_bridge::IntoIntoDart<crate::model::PrepareRefundRequest>
for crate::model::PrepareRefundRequest
{
fn into_into_dart(self) -> crate::model::PrepareRefundRequest {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::PrepareRefundResponse {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.refund_tx_vsize.into_into_dart().into_dart(),
self.refund_tx_fee_sat.into_into_dart().into_dart(),
]
.into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
for crate::model::PrepareRefundResponse
{
}
impl flutter_rust_bridge::IntoIntoDart<crate::model::PrepareRefundResponse>
for crate::model::PrepareRefundResponse
{
fn into_into_dart(self) -> crate::model::PrepareRefundResponse {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::PrepareSendRequest {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[self.invoice.into_into_dart().into_dart()].into_dart()
@@ -3458,6 +3902,44 @@ impl flutter_rust_bridge::IntoIntoDart<crate::model::PrepareSendResponse>
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::ReceiveOnchainRequest {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[self.prepare_res.into_into_dart().into_dart()].into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
for crate::model::ReceiveOnchainRequest
{
}
impl flutter_rust_bridge::IntoIntoDart<crate::model::ReceiveOnchainRequest>
for crate::model::ReceiveOnchainRequest
{
fn into_into_dart(self) -> crate::model::ReceiveOnchainRequest {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::ReceiveOnchainResponse {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.address.into_into_dart().into_dart(),
self.bip21.into_into_dart().into_dart(),
]
.into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive
for crate::model::ReceiveOnchainResponse
{
}
impl flutter_rust_bridge::IntoIntoDart<crate::model::ReceiveOnchainResponse>
for crate::model::ReceiveOnchainResponse
{
fn into_into_dart(self) -> crate::model::ReceiveOnchainResponse {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::ReceivePaymentResponse {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
@@ -3479,6 +3961,58 @@ impl flutter_rust_bridge::IntoIntoDart<crate::model::ReceivePaymentResponse>
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::RefundRequest {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.swap_address.into_into_dart().into_dart(),
self.refund_address.into_into_dart().into_dart(),
self.sat_per_vbyte.into_into_dart().into_dart(),
]
.into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::model::RefundRequest {}
impl flutter_rust_bridge::IntoIntoDart<crate::model::RefundRequest>
for crate::model::RefundRequest
{
fn into_into_dart(self) -> crate::model::RefundRequest {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::RefundResponse {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[self.refund_tx_id.into_into_dart().into_dart()].into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::model::RefundResponse {}
impl flutter_rust_bridge::IntoIntoDart<crate::model::RefundResponse>
for crate::model::RefundResponse
{
fn into_into_dart(self) -> crate::model::RefundResponse {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::RefundableSwap {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.swap_address.into_into_dart().into_dart(),
self.timestamp.into_into_dart().into_dart(),
self.amount_sat.into_into_dart().into_dart(),
]
.into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::model::RefundableSwap {}
impl flutter_rust_bridge::IntoIntoDart<crate::model::RefundableSwap>
for crate::model::RefundableSwap
{
fn into_into_dart(self) -> crate::model::RefundableSwap {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::RestoreRequest {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[self.backup_path.into_into_dart().into_dart()].into_dart()
@@ -3904,6 +4438,16 @@ impl SseEncode for Vec<u8> {
}
}
impl SseEncode for Vec<crate::model::RefundableSwap> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<i32>::sse_encode(self.len() as _, serializer);
for item in self {
<crate::model::RefundableSwap>::sse_encode(item, serializer);
}
}
}
impl SseEncode for Vec<crate::bindings::RouteHint> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@@ -4379,6 +4923,7 @@ impl SseEncode for crate::model::PaymentState {
crate::model::PaymentState::Complete => 2,
crate::model::PaymentState::Failed => 3,
crate::model::PaymentState::TimedOut => 4,
crate::model::PaymentState::Refundable => 5,
_ => {
unimplemented!("");
}
@@ -4419,6 +4964,21 @@ impl SseEncode for crate::model::PreparePayOnchainResponse {
}
}
impl SseEncode for crate::model::PrepareReceiveOnchainRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<u64>::sse_encode(self.amount_sat, serializer);
}
}
impl SseEncode for crate::model::PrepareReceiveOnchainResponse {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<u64>::sse_encode(self.amount_sat, serializer);
<u64>::sse_encode(self.fees_sat, serializer);
}
}
impl SseEncode for crate::model::PrepareReceiveRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@@ -4434,6 +4994,23 @@ impl SseEncode for crate::model::PrepareReceiveResponse {
}
}
impl SseEncode for crate::model::PrepareRefundRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<String>::sse_encode(self.swap_address, serializer);
<String>::sse_encode(self.refund_address, serializer);
<u32>::sse_encode(self.sat_per_vbyte, serializer);
}
}
impl SseEncode for crate::model::PrepareRefundResponse {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<u32>::sse_encode(self.refund_tx_vsize, serializer);
<u64>::sse_encode(self.refund_tx_fee_sat, serializer);
}
}
impl SseEncode for crate::model::PrepareSendRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@@ -4449,6 +5026,21 @@ impl SseEncode for crate::model::PrepareSendResponse {
}
}
impl SseEncode for crate::model::ReceiveOnchainRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<crate::model::PrepareReceiveOnchainResponse>::sse_encode(self.prepare_res, serializer);
}
}
impl SseEncode for crate::model::ReceiveOnchainResponse {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<String>::sse_encode(self.address, serializer);
<String>::sse_encode(self.bip21, serializer);
}
}
impl SseEncode for crate::model::ReceivePaymentResponse {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@@ -4457,6 +5049,31 @@ impl SseEncode for crate::model::ReceivePaymentResponse {
}
}
impl SseEncode for crate::model::RefundRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<String>::sse_encode(self.swap_address, serializer);
<String>::sse_encode(self.refund_address, serializer);
<u32>::sse_encode(self.sat_per_vbyte, serializer);
}
}
impl SseEncode for crate::model::RefundResponse {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<String>::sse_encode(self.refund_tx_id, serializer);
}
}
impl SseEncode for crate::model::RefundableSwap {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<String>::sse_encode(self.swap_address, serializer);
<u32>::sse_encode(self.timestamp, serializer);
<u64>::sse_encode(self.amount_sat, serializer);
}
}
impl SseEncode for crate::model::RestoreRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {

View File

@@ -11,7 +11,7 @@ use rusqlite::ToSql;
use sdk_common::prelude::*;
use serde::{Deserialize, Serialize};
use crate::error::PaymentError;
use crate::error::{LiquidSdkResult, PaymentError};
use crate::receive_swap::{
DEFAULT_ZERO_CONF_MAX_SAT, DEFAULT_ZERO_CONF_MIN_FEE_RATE_MAINNET,
DEFAULT_ZERO_CONF_MIN_FEE_RATE_TESTNET,
@@ -213,6 +213,59 @@ pub struct PayOnchainRequest {
pub prepare_res: PreparePayOnchainResponse,
}
#[derive(Debug, Serialize, Clone)]
pub struct PrepareReceiveOnchainRequest {
pub amount_sat: u64,
}
#[derive(Debug, Serialize, Clone)]
pub struct PrepareReceiveOnchainResponse {
pub amount_sat: u64,
pub fees_sat: u64,
}
#[derive(Debug, Serialize)]
pub struct ReceiveOnchainRequest {
pub prepare_res: PrepareReceiveOnchainResponse,
}
#[derive(Debug, Serialize)]
pub struct ReceiveOnchainResponse {
pub address: String,
pub bip21: String,
}
#[derive(Debug, Serialize)]
pub struct PrepareRefundRequest {
// The address where the swap funds are locked up
pub swap_address: String,
// The address to refund the swap funds to
pub refund_address: String,
// The fee rate in sat/vB for the refund transaction
pub sat_per_vbyte: u32,
}
#[derive(Debug, Serialize)]
pub struct PrepareRefundResponse {
pub refund_tx_vsize: u32,
pub refund_tx_fee_sat: u64,
}
#[derive(Debug, Serialize)]
pub struct RefundRequest {
// The address where the swap funds are locked up
pub swap_address: String,
// The address to refund the swap funds to
pub refund_address: String,
// The fee rate in sat/vB for the refund transaction
pub sat_per_vbyte: u32,
}
#[derive(Debug, Serialize)]
pub struct RefundResponse {
pub refund_tx_id: String,
}
#[derive(Debug, Serialize)]
pub struct GetInfoResponse {
/// Usable balance. This is the confirmed onchain balance minus `pending_send_sat`.
@@ -325,7 +378,9 @@ impl FromSql for Direction {
pub(crate) struct ChainSwap {
pub(crate) id: String,
pub(crate) direction: Direction,
pub(crate) address: String,
pub(crate) claim_address: String,
pub(crate) lockup_address: String,
pub(crate) timeout_block_height: u32,
pub(crate) preimage: String,
pub(crate) payer_amount_sat: u64,
pub(crate) receiver_amount_sat: u64,
@@ -347,11 +402,11 @@ pub(crate) struct ChainSwap {
pub(crate) refund_private_key: String,
}
impl ChainSwap {
pub(crate) fn get_claim_keypair(&self) -> Result<Keypair, PaymentError> {
pub(crate) fn get_claim_keypair(&self) -> LiquidSdkResult<Keypair> {
utils::decode_keypair(&self.claim_private_key).map_err(Into::into)
}
pub(crate) fn get_refund_keypair(&self) -> Result<Keypair, PaymentError> {
pub(crate) fn get_refund_keypair(&self) -> LiquidSdkResult<Keypair> {
utils::decode_keypair(&self.refund_private_key).map_err(Into::into)
}
@@ -368,7 +423,7 @@ impl ChainSwap {
})
}
pub(crate) fn get_claim_swap_script(&self) -> Result<SwapScriptV2, PaymentError> {
pub(crate) fn get_claim_swap_script(&self) -> LiquidSdkResult<SwapScriptV2> {
let chain_swap_details = self.get_boltz_create_response()?.claim_details;
let our_pubkey = self.get_claim_keypair()?.public_key();
let swap_script = match self.direction {
@@ -386,7 +441,7 @@ impl ChainSwap {
Ok(swap_script)
}
pub(crate) fn get_lockup_swap_script(&self) -> Result<SwapScriptV2, PaymentError> {
pub(crate) fn get_lockup_swap_script(&self) -> LiquidSdkResult<SwapScriptV2> {
let chain_swap_details = self.get_boltz_create_response()?.lockup_details;
let our_pubkey = self.get_refund_keypair()?.public_key();
let swap_script = match self.direction {
@@ -593,6 +648,22 @@ impl ReceiveSwap {
}
}
#[derive(Clone, Debug, PartialEq, Serialize)]
pub struct RefundableSwap {
pub swap_address: String,
pub timestamp: u32,
pub amount_sat: u64,
}
impl From<ChainSwap> for RefundableSwap {
fn from(swap: ChainSwap) -> Self {
Self {
swap_address: swap.lockup_address,
timestamp: swap.created_at,
amount_sat: swap.payer_amount_sat,
}
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize, Hash)]
pub enum PaymentState {
Created = 0,
@@ -645,6 +716,12 @@ pub enum PaymentState {
/// This covers the case when the swap state is still Created and the swap fails to reach the
/// Pending state in time. The TimedOut state indicates the lockup tx should never be broadcast.
TimedOut = 4,
/// ## Incoming Chain Swaps
///
/// This covers the case when the swap failed for any reason and there is a user lockup tx.
/// The swap in this case has to be manually refunded with a provided Bitcoin address
Refundable = 5,
}
impl ToSql for PaymentState {
fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
@@ -660,6 +737,7 @@ impl FromSql for PaymentState {
2 => Ok(PaymentState::Complete),
3 => Ok(PaymentState::Failed),
4 => Ok(PaymentState::TimedOut),
5 => Ok(PaymentState::Refundable),
_ => Err(FromSqlError::OutOfRange(i)),
},
_ => Err(FromSqlError::InvalidType),

View File

@@ -21,7 +21,9 @@ impl Persister {
INSERT INTO chain_swaps (
id,
direction,
address,
claim_address,
lockup_address,
timeout_block_height,
preimage,
payer_amount_sat,
receiver_amount_sat,
@@ -33,12 +35,14 @@ impl Persister {
created_at,
state
)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
)?;
_ = stmt.execute((
&chain_swap.id,
&chain_swap.direction,
&chain_swap.address,
&chain_swap.claim_address,
&chain_swap.lockup_address,
&chain_swap.timeout_block_height,
&chain_swap.preimage,
&chain_swap.payer_amount_sat,
&chain_swap.receiver_amount_sat,
@@ -84,7 +88,9 @@ impl Persister {
SELECT
id,
direction,
address,
claim_address,
lockup_address,
timeout_block_height,
preimage,
payer_amount_sat,
receiver_amount_sat,
@@ -114,25 +120,38 @@ impl Persister {
Ok(res.ok())
}
pub(crate) fn fetch_chain_swap_by_lockup_address(
&self,
lockup_address: &str,
) -> Result<Option<ChainSwap>> {
let con: Connection = self.get_connection()?;
let query = Self::list_chain_swaps_query(vec!["lockup_address = ?1".to_string()]);
let res = con.query_row(&query, [lockup_address], Self::sql_row_to_chain_swap);
Ok(res.ok())
}
fn sql_row_to_chain_swap(row: &Row) -> rusqlite::Result<ChainSwap> {
Ok(ChainSwap {
id: row.get(0)?,
direction: row.get(1)?,
address: row.get(2)?,
preimage: row.get(3)?,
payer_amount_sat: row.get(4)?,
receiver_amount_sat: row.get(5)?,
accept_zero_conf: row.get(6)?,
create_response_json: row.get(7)?,
claim_private_key: row.get(8)?,
refund_private_key: row.get(9)?,
server_lockup_tx_id: row.get(10)?,
user_lockup_tx_id: row.get(11)?,
claim_fees_sat: row.get(12)?,
claim_tx_id: row.get(13)?,
refund_tx_id: row.get(14)?,
created_at: row.get(15)?,
state: row.get(16)?,
claim_address: row.get(2)?,
lockup_address: row.get(3)?,
timeout_block_height: row.get(4)?,
preimage: row.get(5)?,
payer_amount_sat: row.get(6)?,
receiver_amount_sat: row.get(7)?,
accept_zero_conf: row.get(8)?,
create_response_json: row.get(9)?,
claim_private_key: row.get(10)?,
refund_private_key: row.get(11)?,
server_lockup_tx_id: row.get(12)?,
user_lockup_tx_id: row.get(13)?,
claim_fees_sat: row.get(14)?,
claim_tx_id: row.get(15)?,
refund_tx_id: row.get(16)?,
created_at: row.get(17)?,
state: row.get(18)?,
})
}
@@ -195,6 +214,20 @@ impl Persister {
Ok(res)
}
pub(crate) fn list_refundable_chain_swaps(&self) -> Result<Vec<ChainSwap>> {
let con: Connection = self.get_connection()?;
let query = Self::list_chain_swaps_query(vec!["state = ?1".to_string()]);
let res = con
.prepare(&query)?
.query_map(
params![PaymentState::Refundable],
Self::sql_row_to_chain_swap,
)?
.map(|i| i.unwrap())
.collect();
Ok(res)
}
pub(crate) fn update_chain_swap_accept_zero_conf(
&self,
swap_id: &str,

View File

@@ -38,7 +38,9 @@ pub(crate) fn current_migrations() -> Vec<&'static str> {
"CREATE TABLE IF NOT EXISTS chain_swaps (
id TEXT NOT NULL PRIMARY KEY,
direction INTEGER NOT NULL,
address TEXT NOT NULL,
claim_address TEXT NOT NULL,
lockup_address TEXT NOT NULL,
timeout_block_height INTEGER NOT NULL,
preimage TEXT NOT NULL,
payer_amount_sat INTEGER NOT NULL,
receiver_amount_sat INTEGER NOT NULL,

View File

@@ -12,7 +12,7 @@ use lwk_wollet::History;
use tokio::sync::{broadcast, Mutex};
use crate::chain::liquid::LiquidChainService;
use crate::model::PaymentState::{Complete, Created, Failed, Pending, TimedOut};
use crate::model::PaymentState::{Complete, Created, Failed, Pending, Refundable, TimedOut};
use crate::model::{Config, PaymentTxData, PaymentType, ReceiveSwap};
use crate::{ensure_sdk, utils};
use crate::{
@@ -287,12 +287,12 @@ impl ReceiveSwapStateHandler {
}),
(Created | Pending, Pending) => Ok(()),
(Complete | Failed | TimedOut, Pending) => Err(PaymentError::Generic {
(_, Pending) => Err(PaymentError::Generic {
err: format!("Cannot transition from {from_state:?} to Pending state"),
}),
(Created | Pending, Complete) => Ok(()),
(Complete | Failed | TimedOut, Complete) => Err(PaymentError::Generic {
(_, Complete) => Err(PaymentError::Generic {
err: format!("Cannot transition from {from_state:?} to Complete state"),
}),
@@ -301,6 +301,10 @@ impl ReceiveSwapStateHandler {
err: format!("Cannot transition from {from_state:?} to TimedOut state"),
}),
(_, Refundable) => Err(PaymentError::Generic {
err: format!("Cannot transition from {from_state:?} to Refundable state"),
}),
(Complete, Failed) => Err(PaymentError::Generic {
err: format!("Cannot transition from {from_state:?} to Failed state"),
}),
@@ -416,6 +420,7 @@ mod tests {
(Pending, HashSet::from([Pending, Complete, Failed])),
(TimedOut, HashSet::from([TimedOut, Failed])),
(Complete, HashSet::from([])),
(Refundable, HashSet::from([Failed])),
(Failed, HashSet::from([Failed])),
]);

View File

@@ -4,15 +4,16 @@ use std::{fs, path::PathBuf, str::FromStr, sync::Arc, time::Duration};
use anyhow::Result;
use async_trait::async_trait;
use boltz_client::ToHex;
use boltz_client::{swaps::boltzv2::*, util::secrets::Preimage, Bolt11Invoice};
use boltz_client::{LockTime, ToHex};
use chain::liquid::{HybridLiquidChainService, LiquidChainService};
use futures_util::stream::select_all;
use futures_util::StreamExt;
use log::{debug, error, info, warn};
use lwk_wollet::bitcoin::hex::DisplayHex;
use lwk_wollet::hashes::{sha256, Hash};
use lwk_wollet::secp256k1::ThirtyTwoByteHash;
use lwk_wollet::{elements::LockTime, ElementsNetwork};
use lwk_wollet::{elements, ElectrumUrl, ElementsNetwork};
use sdk_common::bitcoin::secp256k1::Secp256k1;
use sdk_common::bitcoin::util::bip32::ChildNumber;
use tokio::sync::{watch, Mutex, RwLock};
@@ -20,7 +21,7 @@ use tokio::time::MissedTickBehavior;
use tokio_stream::wrappers::BroadcastStream;
use url::Url;
use crate::chain::liquid::{HybridLiquidChainService, LiquidChainService};
use crate::chain::bitcoin::{self, BitcoinChainService};
use crate::chain_swap::ChainSwapStateHandler;
use crate::error::LiquidSdkError;
use crate::model::PaymentState::*;
@@ -45,7 +46,8 @@ pub struct LiquidSdk {
event_manager: Arc<EventManager>,
status_stream: Arc<dyn SwapperStatusStream>,
swapper: Arc<dyn Swapper>,
chain_service: Arc<Mutex<dyn LiquidChainService>>,
liquid_chain_service: Arc<Mutex<dyn LiquidChainService>>,
bitcoin_chain_service: Arc<Mutex<dyn BitcoinChainService>>,
is_started: RwLock<bool>,
shutdown_sender: watch::Sender<()>,
shutdown_receiver: watch::Receiver<()>,
@@ -75,7 +77,11 @@ impl LiquidSdk {
let swapper = Arc::new(BoltzSwapper::new(config.clone()));
let status_stream = Arc::<dyn SwapperStatusStream>::from(swapper.create_status_stream());
let chain_service = Arc::new(Mutex::new(HybridLiquidChainService::new(config.clone())?));
let liquid_chain_service =
Arc::new(Mutex::new(HybridLiquidChainService::new(config.clone())?));
let bitcoin_chain_service = Arc::new(Mutex::new(bitcoin::ElectrumClient::new(
&ElectrumUrl::new(&config.bitcoin_electrum_url, true, true),
)?));
let onchain_wallet = Arc::new(LiquidOnchainWallet::new(mnemonic, config.clone())?);
@@ -84,7 +90,7 @@ impl LiquidSdk {
onchain_wallet.clone(),
persister.clone(),
swapper.clone(),
chain_service.clone(),
liquid_chain_service.clone(),
);
let receive_swap_state_handler = ReceiveSwapStateHandler::new(
@@ -92,15 +98,15 @@ impl LiquidSdk {
onchain_wallet.clone(),
persister.clone(),
swapper.clone(),
chain_service.clone(),
liquid_chain_service.clone(),
);
let chain_swap_state_handler = ChainSwapStateHandler::new(
config.clone(),
onchain_wallet.clone(),
persister.clone(),
swapper.clone(),
chain_service.clone(),
liquid_chain_service.clone(),
bitcoin_chain_service.clone(),
)?;
let sdk = Arc::new(LiquidSdk {
@@ -110,7 +116,8 @@ impl LiquidSdk {
event_manager,
status_stream: status_stream.clone(),
swapper,
chain_service,
bitcoin_chain_service,
liquid_chain_service,
is_started: RwLock::new(false),
shutdown_sender,
shutdown_receiver,
@@ -144,6 +151,7 @@ impl LiquidSdk {
/// Internal method. Should only be used as part of [LiquidSdk::start].
async fn start_background_tasks(self: &Arc<LiquidSdk>) -> LiquidSdkResult<()> {
// Periodically run sync() in the background
// TODO: Check the bitcoin chain for confirmed refund txs
let sdk_clone = self.clone();
let mut shutdown_rx_sync_loop = self.shutdown_receiver.clone();
tokio::spawn(async move {
@@ -297,27 +305,39 @@ impl LiquidSdk {
async fn check_chain_swap_expiration(&self, chain_swap: &ChainSwap) -> Result<()> {
if chain_swap.user_lockup_tx_id.is_some() && chain_swap.refund_tx_id.is_none() {
match chain_swap.direction {
Direction::Outgoing => {
let swap_script = chain_swap.get_lockup_swap_script()?.as_liquid_script()?;
let current_height = self.chain_service.lock().await.tip().await?;
let locktime_from_height = LockTime::from_height(current_height)?;
Direction::Incoming => {
let swap_script = chain_swap.get_lockup_swap_script()?.as_bitcoin_script()?;
let current_height =
self.bitcoin_chain_service.lock().await.tip()?.height as u32;
let locktime_from_height =
LockTime::from_height(current_height).map_err(|e| {
PaymentError::Generic {
err: format!(
"Error getting locktime from height {current_height:?}: {e}",
),
}
})?;
info!("Checking Chain Swap {} expiration: locktime_from_height = {locktime_from_height:?}, swap_script.locktime = {:?}", chain_swap.id, swap_script.locktime);
if utils::is_locktime_expired(locktime_from_height, swap_script.locktime) {
let id = &chain_swap.id;
let refund_tx_id = self.refund_chain(chain_swap).await?;
info!("Broadcast refund tx for Chain Swap {id}. Tx id: {refund_tx_id}");
if swap_script.locktime.is_implied_by(locktime_from_height) {
let id: &String = &chain_swap.id;
info!("Chain Swap {} user lockup tx was broadcast. Setting the swap to refundable.", id);
self.chain_swap_state_handler
.update_swap_info(id, Pending, None, None, None, Some(&refund_tx_id))
.update_swap_info(id, Refundable, None, None, None, None)
.await?;
}
}
_ => {
// TODO: Set the chain swap to refundable when it expires
info!(
"Not checking receive Chain Swap {} expiration",
chain_swap.id
)
Direction::Outgoing => {
let swap_script = chain_swap.get_lockup_swap_script()?.as_liquid_script()?;
let current_height = self.liquid_chain_service.lock().await.tip().await?;
let locktime_from_height = elements::LockTime::from_height(current_height)?;
info!("Checking Chain Swap {} expiration: locktime_from_height = {locktime_from_height:?}, swap_script.locktime = {:?}", chain_swap.id, swap_script.locktime);
if utils::is_locktime_expired(locktime_from_height, swap_script.locktime) {
self.chain_swap_state_handler
.refund_outgoing_swap(chain_swap)
.await?;
}
}
}
}
@@ -327,8 +347,8 @@ impl LiquidSdk {
async fn check_send_swap_expiration(&self, send_swap: &SendSwap) -> Result<()> {
if send_swap.lockup_tx_id.is_some() && send_swap.refund_tx_id.is_none() {
let swap_script = send_swap.get_swap_script()?;
let current_height = self.chain_service.lock().await.tip().await?;
let locktime_from_height = LockTime::from_height(current_height)?;
let current_height = self.liquid_chain_service.lock().await.tip().await?;
let locktime_from_height = elements::LockTime::from_height(current_height)?;
info!("Checking Send Swap {} expiration: locktime_from_height = {locktime_from_height:?}, swap_script.locktime = {:?}", send_swap.id, swap_script.locktime);
if utils::is_locktime_expired(locktime_from_height, swap_script.locktime) {
@@ -476,12 +496,12 @@ impl LiquidSdk {
None => pending_send_sat += p.amount_sat,
},
Created => pending_send_sat += p.amount_sat,
TimedOut => {}
Refundable | TimedOut => {}
},
PaymentType::Receive => match p.status {
Complete => confirmed_received_sat += p.amount_sat,
Failed => {}
_ => pending_receive_sat += p.amount_sat,
Pending => pending_receive_sat += p.amount_sat,
Created | Refundable | Failed | TimedOut => {}
},
}
}
@@ -614,6 +634,12 @@ impl LiquidSdk {
}
};
let payer_amount_sat = receiver_amount_sat + fees_sat;
ensure_sdk!(
payer_amount_sat <= self.get_info().await?.balance_sat,
PaymentError::InsufficientFunds
);
Ok(PrepareSendResponse {
invoice: req.invoice.clone(),
fees_sat,
@@ -646,50 +672,6 @@ impl LiquidSdk {
Ok(refund_tx_id)
}
async fn refund_chain_non_cooperative(
&self,
swap: &ChainSwap,
broadcast_fees_sat: u64,
) -> Result<String, PaymentError> {
info!(
"Initiating non-cooperative refund for Chain Swap {}",
&swap.id
);
let current_height = self.onchain_wallet.tip().await.height();
let output_address = self.onchain_wallet.next_unused_address().await?.to_string();
let refund_tx_id = self.swapper.refund_chain_swap_non_cooperative(
swap,
broadcast_fees_sat,
&output_address,
current_height,
)?;
info!(
"Successfully broadcast non-cooperative refund for Chain Swap {}, tx: {}",
swap.id, refund_tx_id
);
Ok(refund_tx_id)
}
async fn refund_chain(&self, swap: &ChainSwap) -> Result<String, PaymentError> {
let output_address = self.onchain_wallet.next_unused_address().await?.to_string();
let refund_tx_fees_sat = self
.estimate_onchain_tx_fee(swap.receiver_amount_sat, &output_address)
.await?;
let refund_res =
self.swapper
.refund_chain_swap_cooperative(swap, &output_address, refund_tx_fees_sat);
match refund_res {
Ok(res) => Ok(res),
Err(e) => {
warn!("Cooperative refund failed: {:?}", e);
self.refund_chain_non_cooperative(swap, refund_tx_fees_sat)
.await
}
}
}
async fn refund_send(&self, swap: &SendSwap) -> Result<String, PaymentError> {
let amount_sat = get_invoice_amount!(swap.invoice);
let output_address = self.onchain_wallet.next_unused_address().await?.to_string();
@@ -732,6 +714,13 @@ impl LiquidSdk {
self.ensure_send_is_not_self_transfer(&req.invoice)?;
self.validate_invoice(&req.invoice)?;
let amount_sat = get_invoice_amount!(&req.invoice);
let payer_amount_sat = amount_sat + req.fees_sat;
ensure_sdk!(
payer_amount_sat <= self.get_info().await?.balance_sat,
PaymentError::InsufficientFunds
);
match self.swapper.check_for_mrh(&req.invoice)? {
// If we find a valid MRH, extract the BIP21 amount and address, then pay via onchain tx
Some((address, amount_btc)) => {
@@ -865,15 +854,27 @@ impl LiquidSdk {
let amount_sat = req.amount_sat;
let pair = self.validate_chain_pairs(Direction::Outgoing, amount_sat)?;
let claim_fees_sat = pair.fees.claim_estimate();
let server_fees_sat = pair.fees.server();
let server_lockup_amount_sat = amount_sat + claim_fees_sat;
let lockup_fees_sat = self
.estimate_lockup_tx_fee(server_lockup_amount_sat)
.await?;
Ok(PreparePayOnchainResponse {
let res = PreparePayOnchainResponse {
amount_sat,
fees_sat: pair.fees.boltz(amount_sat) + lockup_fees_sat + claim_fees_sat,
})
fees_sat: pair.fees.boltz(server_lockup_amount_sat)
+ lockup_fees_sat
+ claim_fees_sat
+ server_fees_sat,
};
let payer_amount_sat = res.amount_sat + res.fees_sat;
ensure_sdk!(
payer_amount_sat <= self.get_info().await?.balance_sat,
PaymentError::InsufficientFunds
);
Ok(res)
}
pub async fn pay_onchain(
@@ -885,6 +886,7 @@ impl LiquidSdk {
let receiver_amount_sat = req.prepare_res.amount_sat;
let pair = self.validate_chain_pairs(Direction::Outgoing, receiver_amount_sat)?;
let claim_fees_sat = pair.fees.claim_estimate();
let server_fees_sat = pair.fees.server();
let server_lockup_amount_sat = receiver_amount_sat + claim_fees_sat;
let lockup_fees_sat = self
.estimate_lockup_tx_fee(server_lockup_amount_sat)
@@ -892,10 +894,19 @@ impl LiquidSdk {
ensure_sdk!(
req.prepare_res.fees_sat
== pair.fees.boltz(receiver_amount_sat) + lockup_fees_sat + claim_fees_sat,
== pair.fees.boltz(server_lockup_amount_sat)
+ lockup_fees_sat
+ claim_fees_sat
+ server_fees_sat,
PaymentError::InvalidOrExpiredFees
);
let payer_amount_sat = req.prepare_res.fees_sat + receiver_amount_sat;
ensure_sdk!(
payer_amount_sat <= self.get_info().await?.balance_sat,
PaymentError::InsufficientFunds
);
let preimage = Preimage::new();
let preimage_str = preimage.to_string().ok_or(PaymentError::InvalidPreimage)?;
@@ -926,11 +937,14 @@ impl LiquidSdk {
let accept_zero_conf = server_lockup_amount_sat <= pair.limits.maximal_zero_conf;
let payer_amount_sat = req.prepare_res.fees_sat + receiver_amount_sat;
let claim_address = req.address.clone();
let swap = ChainSwap {
id: swap_id.clone(),
direction: Direction::Outgoing,
address: req.address.clone(),
claim_address,
lockup_address: create_response.lockup_details.lockup_address,
timeout_block_height: create_response.lockup_details.timeout_block_height,
preimage: preimage_str,
payer_amount_sat,
receiver_amount_sat,
@@ -1150,6 +1164,139 @@ impl LiquidSdk {
})
}
pub async fn prepare_receive_onchain(
&self,
req: &PrepareReceiveOnchainRequest,
) -> Result<PrepareReceiveOnchainResponse, PaymentError> {
self.ensure_is_started().await?;
let amount_sat = req.amount_sat;
let pair = self.validate_chain_pairs(Direction::Incoming, amount_sat)?;
let claim_fees_sat = pair.fees.claim_estimate();
let server_fees_sat = pair.fees.server();
Ok(PrepareReceiveOnchainResponse {
amount_sat,
fees_sat: pair.fees.boltz(amount_sat) + claim_fees_sat + server_fees_sat,
})
}
pub async fn receive_onchain(
&self,
req: &ReceiveOnchainRequest,
) -> Result<ReceiveOnchainResponse, PaymentError> {
self.ensure_is_started().await?;
let payer_amount_sat = req.prepare_res.amount_sat;
let pair = self.validate_chain_pairs(Direction::Incoming, payer_amount_sat)?;
let claim_fees_sat = pair.fees.claim_estimate();
let server_fees_sat = pair.fees.server();
ensure_sdk!(
req.prepare_res.fees_sat
== pair.fees.boltz(payer_amount_sat) + claim_fees_sat + server_fees_sat,
PaymentError::InvalidOrExpiredFees
);
let preimage = Preimage::new();
let preimage_str = preimage.to_string().ok_or(PaymentError::InvalidPreimage)?;
let claim_keypair = utils::generate_keypair();
let claim_public_key = boltz_client::PublicKey {
compressed: true,
inner: claim_keypair.public_key(),
};
let refund_keypair = utils::generate_keypair();
let refund_public_key = boltz_client::PublicKey {
compressed: true,
inner: refund_keypair.public_key(),
};
let create_response = self.swapper.create_chain_swap(CreateChainRequest {
from: "BTC".to_string(),
to: "L-BTC".to_string(),
preimage_hash: preimage.sha256,
claim_public_key: Some(claim_public_key),
refund_public_key: Some(refund_public_key),
user_lock_amount: Some(payer_amount_sat as u32), // TODO update our model
server_lock_amount: None,
pair_hash: Some(pair.hash),
referral_id: None,
})?;
let swap_id = create_response.id.clone();
let create_response_json =
ChainSwap::from_boltz_struct_to_json(&create_response, &swap_id)?;
let accept_zero_conf = payer_amount_sat <= pair.limits.maximal_zero_conf;
let receiver_amount_sat = payer_amount_sat - req.prepare_res.fees_sat;
let claim_address = self.onchain_wallet.next_unused_address().await?.to_string();
let lockup_address = create_response.lockup_details.lockup_address;
let swap = ChainSwap {
id: swap_id.clone(),
direction: Direction::Incoming,
claim_address,
lockup_address: lockup_address.clone(),
timeout_block_height: create_response.lockup_details.timeout_block_height,
preimage: preimage_str,
payer_amount_sat,
receiver_amount_sat,
claim_fees_sat,
accept_zero_conf,
create_response_json,
claim_private_key: claim_keypair.display_secret().to_string(),
refund_private_key: refund_keypair.display_secret().to_string(),
server_lockup_tx_id: None,
user_lockup_tx_id: None,
claim_tx_id: None,
refund_tx_id: None,
created_at: utils::now(),
state: PaymentState::Created,
};
self.persister.insert_chain_swap(&swap)?;
self.status_stream.track_swap_id(&swap.id)?;
let address = lockup_address;
let amount = create_response.lockup_details.amount as f64 / 100_000_000.0;
let bip21 = create_response.lockup_details.bip21.unwrap_or(format!(
"bitcoin:{address}?amount={amount}&label=Send%20to%20L-BTC%20address"
));
Ok(ReceiveOnchainResponse { address, bip21 })
}
pub async fn list_refundables(&self) -> LiquidSdkResult<Vec<RefundableSwap>> {
Ok(self
.persister
.list_refundable_chain_swaps()?
.into_iter()
.map(Into::into)
.collect())
}
pub async fn prepare_refund(
&self,
req: &PrepareRefundRequest,
) -> LiquidSdkResult<PrepareRefundResponse> {
let (refund_tx_vsize, refund_tx_fee_sat) = self.chain_swap_state_handler.prepare_refund(
&req.swap_address,
&req.refund_address,
req.sat_per_vbyte,
)?;
Ok(PrepareRefundResponse {
refund_tx_vsize,
refund_tx_fee_sat,
})
}
pub async fn refund(&self, req: &RefundRequest) -> Result<RefundResponse, PaymentError> {
let refund_tx_id = self
.chain_swap_state_handler
.refund_incoming_swap(&req.swap_address, &req.refund_address, req.sat_per_vbyte)
.await?;
Ok(RefundResponse { refund_tx_id })
}
/// This method fetches the chain tx data (onchain and mempool) using LWK. For every wallet tx,
/// it inserts or updates a corresponding entry in our Payments table.
async fn sync_payments_with_chain_data(&self, with_scan: bool) -> Result<()> {

View File

@@ -12,7 +12,7 @@ use lwk_wollet::hashes::{sha256, Hash};
use tokio::sync::{broadcast, Mutex};
use crate::chain::liquid::LiquidChainService;
use crate::model::PaymentState::{Complete, Created, Failed, Pending, TimedOut};
use crate::model::PaymentState::{Complete, Created, Failed, Pending, Refundable, TimedOut};
use crate::model::{Config, SendSwap, LOWBALL_FEE_RATE_SAT_PER_VBYTE};
use crate::swapper::Swapper;
use crate::wallet::OnchainWallet;
@@ -410,12 +410,12 @@ impl SendSwapStateHandler {
}),
(Created | Pending, Pending) => Ok(()),
(Complete | Failed | TimedOut, Pending) => Err(PaymentError::Generic {
(_, Pending) => Err(PaymentError::Generic {
err: format!("Cannot transition from {from_state:?} to Pending state"),
}),
(Created | Pending, Complete) => Ok(()),
(Complete | Failed | TimedOut, Complete) => Err(PaymentError::Generic {
(_, Complete) => Err(PaymentError::Generic {
err: format!("Cannot transition from {from_state:?} to Complete state"),
}),
@@ -424,6 +424,10 @@ impl SendSwapStateHandler {
err: format!("Cannot transition from {from_state:?} to TimedOut state"),
}),
(_, Refundable) => Err(PaymentError::Generic {
err: format!("Cannot transition from {from_state:?} to Refundable state"),
}),
(Complete, Failed) => Err(PaymentError::Generic {
err: format!("Cannot transition from {from_state:?} to Failed state"),
}),
@@ -464,7 +468,6 @@ mod tests {
async fn test_send_swap_state_transitions() -> Result<()> {
let (_temp_dir, storage) = new_persister()?;
let storage = Arc::new(storage);
let send_swap_state_handler = new_send_swap_state_handler(storage.clone())?;
// Test valid combinations of states
@@ -476,6 +479,7 @@ mod tests {
(Pending, HashSet::from([Pending, Complete, Failed])),
(TimedOut, HashSet::from([TimedOut, Failed])),
(Complete, HashSet::from([])),
(Refundable, HashSet::from([Failed])),
(Failed, HashSet::from([Failed])),
]);

View File

@@ -5,6 +5,7 @@ use std::sync::Arc;
use anyhow::Result;
use async_trait::async_trait;
use boltz_client::elements::secp256k1_zkp::{MusigPartialSignature, MusigPubNonce};
use boltz_client::error::Error;
use boltz_client::network::electrum::ElectrumConfig;
use boltz_client::network::Chain;
@@ -21,7 +22,7 @@ use lwk_wollet::elements;
use serde_json::Value;
use tokio::sync::{broadcast, watch};
use crate::error::PaymentError;
use crate::error::{LiquidSdkError, PaymentError};
use crate::model::{
ChainSwap, Config, Direction, LiquidNetwork, ReceiveSwap, SendSwap, SwapScriptV2, SwapTxV2,
};
@@ -62,7 +63,15 @@ pub trait Swapper: Send + Sync {
/// Get a submarine pair information
fn get_submarine_pairs(&self) -> Result<Option<SubmarinePair>, PaymentError>;
/// Refund a cooperatively chain swap
/// Prepare the chain swap refund
fn prepare_chain_swap_refund(
&self,
swap: &ChainSwap,
output_address: &str,
sat_per_vbyte: f32,
) -> Result<(u32, u64), LiquidSdkError>;
/// Refund a cooperatively chain swap
fn refund_chain_swap_cooperative(
&self,
swap: &ChainSwap,
@@ -105,11 +114,7 @@ pub trait Swapper: Send + Sync {
) -> Result<SubmarineClaimTxResponse, PaymentError>;
/// Claim chain swap.
fn claim_chain_swap(
&self,
swap: &ChainSwap,
refund_address: String,
) -> Result<String, PaymentError>;
fn claim_chain_swap(&self, swap: &ChainSwap) -> Result<String, PaymentError>;
/// Claim send swap cooperatively. Here the remote swapper is the one that claims.
/// We are helping to use key spend path for cheaper fees.
@@ -179,7 +184,7 @@ impl BoltzSwapper {
swap_id: String,
swap_script: SwapScriptV2,
refund_address: &String,
) -> Result<SwapTxV2, PaymentError> {
) -> Result<SwapTxV2, LiquidSdkError> {
let swap_tx = match swap_script {
SwapScriptV2::Bitcoin(swap_script) => SwapTxV2::Bitcoin(BtcSwapTxV2::new_refund(
swap_script.clone(),
@@ -220,31 +225,45 @@ impl BoltzSwapper {
.ok_or(PaymentError::InvalidPreimage)
}
fn claim_outgoing_chain_swap(
fn get_claim_partial_sig(
&self,
swap: &ChainSwap,
refund_address: String,
) -> Result<String, PaymentError> {
) -> Result<(MusigPartialSignature, MusigPubNonce), PaymentError> {
let refund_keypair = swap.get_refund_keypair()?;
let lockup_swap_script = swap.get_lockup_swap_script()?;
// Create a temporary refund tx to an address from the swap lockup chain
// We need it to calculate the musig partial sig for the claim tx from the other chain
let lockup_address = &swap.lockup_address;
let refund_tx_wrapper =
self.new_refund_tx(swap.id.clone(), lockup_swap_script, lockup_address)?;
let claim_tx_details = self.client.get_chain_claim_tx_details(&swap.id)?;
match swap.direction {
Direction::Incoming => refund_tx_wrapper.as_bitcoin_tx()?.partial_sig(
&refund_keypair,
&claim_tx_details.pub_nonce,
&claim_tx_details.transaction_hash,
),
Direction::Outgoing => refund_tx_wrapper.as_liquid_tx()?.partial_sig(
&refund_keypair,
&claim_tx_details.pub_nonce,
&claim_tx_details.transaction_hash,
),
}
.map_err(Into::into)
}
fn claim_outgoing_chain_swap(&self, swap: &ChainSwap) -> Result<String, PaymentError> {
let claim_keypair = swap.get_claim_keypair()?;
let claim_swap_script = swap.get_claim_swap_script()?.as_bitcoin_script()?;
let claim_tx_wrapper = BtcSwapTxV2::new_claim(
claim_swap_script,
swap.address.clone(),
swap.claim_address.clone(),
&self.bitcoin_electrum_config,
)?;
let refund_keypair = swap.get_refund_keypair()?;
let lockup_swap_script = swap.get_lockup_swap_script()?;
let refund_tx = self
.new_refund_tx(swap.id.clone(), lockup_swap_script, &refund_address)?
.as_liquid_tx()?;
let claim_tx_response = self.client.get_chain_claim_tx_details(&swap.id)?;
let (partial_sig, pub_nonce) = refund_tx.partial_sig(
&refund_keypair,
&claim_tx_response.pub_nonce,
&claim_tx_response.transaction_hash,
)?;
let (partial_sig, pub_nonce) = self.get_claim_partial_sig(swap)?;
let claim_tx = claim_tx_wrapper.sign_claim(
&claim_keypair,
@@ -265,33 +284,18 @@ impl BoltzSwapper {
Ok(claim_tx_id)
}
fn claim_incoming_chain_swap(
&self,
swap: &ChainSwap,
refund_address: String,
) -> Result<String, PaymentError> {
fn claim_incoming_chain_swap(&self, swap: &ChainSwap) -> Result<String, PaymentError> {
let claim_keypair = swap.get_claim_keypair()?;
let swap_script = swap.get_claim_swap_script()?.as_liquid_script()?;
let claim_tx_wrapper = LBtcSwapTxV2::new_claim(
swap_script,
swap.address.clone(),
swap.claim_address.clone(),
&self.liquid_electrum_config,
self.config.boltz_url.clone(),
swap.id.clone(),
)?;
let refund_keypair = swap.get_refund_keypair()?;
let lockup_swap_script = swap.get_lockup_swap_script()?;
let refund_tx = self
.new_refund_tx(swap.id.clone(), lockup_swap_script, &refund_address)?
.as_bitcoin_tx()?;
let claim_tx_response = self.client.get_chain_claim_tx_details(&swap.id)?;
let (partial_sig, pub_nonce) = refund_tx.partial_sig(
&refund_keypair,
&claim_tx_response.pub_nonce,
&claim_tx_response.transaction_hash,
)?;
let (partial_sig, pub_nonce) = self.get_claim_partial_sig(swap)?;
let claim_tx = claim_tx_wrapper.sign_claim(
&claim_keypair,
@@ -471,7 +475,35 @@ impl Swapper for BoltzSwapper {
Ok(self.client.get_submarine_pairs()?.get_lbtc_to_btc_pair())
}
/// Refund a cooperatively chain swap
/// Prepare the chain swap refund
fn prepare_chain_swap_refund(
&self,
swap: &ChainSwap,
output_address: &str,
sat_per_vbyte: f32,
) -> Result<(u32, u64), LiquidSdkError> {
let refund_keypair = swap.get_refund_keypair()?;
let preimage = Preimage::from_str(&swap.preimage)?;
let swap_script = swap.get_lockup_swap_script()?;
let refund_tx_vsize = match swap.direction {
Direction::Incoming => {
let refund_tx = self
.new_refund_tx(swap.id.clone(), swap_script, &output_address.into())?
.as_bitcoin_tx()?;
refund_tx.size(&refund_keypair, &preimage)? as u32
}
Direction::Outgoing => {
let refund_tx = self
.new_refund_tx(swap.id.clone(), swap_script, &output_address.into())?
.as_liquid_tx()?;
refund_tx.size(&refund_keypair, &preimage)? as u32
}
};
let refund_tx_fee_sat = (refund_tx_vsize as f32 * sat_per_vbyte).ceil() as u64;
Ok((refund_tx_vsize, refund_tx_fee_sat))
}
/// Refund a cooperatively chain swap
fn refund_chain_swap_cooperative(
&self,
swap: &ChainSwap,
@@ -568,14 +600,10 @@ impl Swapper for BoltzSwapper {
}
/// Claim chain swap.
fn claim_chain_swap(
&self,
swap: &ChainSwap,
refund_address: String,
) -> Result<String, PaymentError> {
fn claim_chain_swap(&self, swap: &ChainSwap) -> Result<String, PaymentError> {
let claim_tx_id = match swap.direction {
Direction::Incoming => self.claim_incoming_chain_swap(swap, refund_address),
Direction::Outgoing => self.claim_outgoing_chain_swap(swap, refund_address),
Direction::Incoming => self.claim_incoming_chain_swap(swap),
Direction::Outgoing => self.claim_outgoing_chain_swap(swap),
}?;
info!(
"Successfully broadcast claim tx {claim_tx_id} for Chain Swap {}",

View File

@@ -2,7 +2,7 @@
use std::sync::Arc;
use crate::{
chain::liquid::HybridLiquidChainService,
chain::{bitcoin, liquid::HybridLiquidChainService},
chain_swap::ChainSwapStateHandler,
model::{
ChainSwap, Config, Direction, LiquidNetwork, PaymentState, PaymentTxData, PaymentType,
@@ -18,6 +18,7 @@ use crate::{
use anyhow::{anyhow, Result};
use bip39::rand::{self, distributions::Alphanumeric, Rng};
use lwk_wollet::ElectrumUrl;
use tempdir::TempDir;
use tokio::sync::Mutex;
@@ -65,13 +66,16 @@ pub(crate) fn new_chain_swap_state_handler(
let onchain_wallet = Arc::new(new_onchain_wallet(&config)?);
let swapper = Arc::new(BoltzSwapper::new(config.clone()));
let liquid_chain_service = Arc::new(Mutex::new(HybridLiquidChainService::new(config.clone())?));
let bitcoin_chain_service = Arc::new(Mutex::new(bitcoin::ElectrumClient::new(
&ElectrumUrl::new(&config.bitcoin_electrum_url, true, true),
)?));
ChainSwapStateHandler::new(
config,
onchain_wallet,
persister,
swapper,
liquid_chain_service,
bitcoin_chain_service,
)
}
@@ -131,7 +135,9 @@ pub(crate) fn new_chain_swap(payment_state: Option<PaymentState>) -> ChainSwap {
ChainSwap {
id,
direction: Direction::Incoming,
address: "".to_string(),
claim_address: "".to_string(),
lockup_address: "".to_string(),
timeout_block_height: 0,
preimage: "".to_string(),
create_response_json: "{}".to_string(),
claim_private_key: "".to_string(),

View File

@@ -1,7 +1,7 @@
use std::str::FromStr;
use std::time::{SystemTime, UNIX_EPOCH};
use crate::error::PaymentError;
use crate::error::{LiquidSdkResult, PaymentError};
use anyhow::{anyhow, Result};
use lwk_wollet::elements::encode::deserialize;
use lwk_wollet::elements::hex::FromHex;
@@ -30,7 +30,7 @@ pub(crate) fn generate_keypair() -> boltz_client::Keypair {
boltz_client::Keypair::from_secret_key(&secp, &secret_key)
}
pub(crate) fn decode_keypair(secret_key: &str) -> Result<boltz_client::Keypair, lwk_wollet::Error> {
pub(crate) fn decode_keypair(secret_key: &str) -> LiquidSdkResult<boltz_client::Keypair> {
let secp = boltz_client::Secp256k1::new();
let secret_key = lwk_wollet::secp256k1::SecretKey::from_str(secret_key)?;
Ok(boltz_client::Keypair::from_secret_key(&secp, &secret_key))

View File

@@ -43,6 +43,8 @@ abstract class BindingLiquidSdk implements RustOpaqueInterface {
Future<List<Payment>> listPayments();
Future<List<RefundableSwap>> listRefundables();
Future<LnUrlCallbackStatus> lnurlAuth({required LnUrlAuthRequestData reqData});
Future<LnUrlPayResult> lnurlPay({required LnUrlPayRequest req});
@@ -53,12 +55,20 @@ abstract class BindingLiquidSdk implements RustOpaqueInterface {
Future<PreparePayOnchainResponse> preparePayOnchain({required PreparePayOnchainRequest req});
Future<PrepareReceiveOnchainResponse> prepareReceiveOnchain({required PrepareReceiveOnchainRequest req});
Future<PrepareReceiveResponse> prepareReceivePayment({required PrepareReceiveRequest req});
Future<PrepareRefundResponse> prepareRefund({required PrepareRefundRequest req});
Future<PrepareSendResponse> prepareSendPayment({required PrepareSendRequest req});
Future<ReceiveOnchainResponse> receiveOnchain({required ReceiveOnchainRequest req});
Future<ReceivePaymentResponse> receivePayment({required PrepareReceiveResponse req});
Future<RefundResponse> refund({required RefundRequest req});
void restore({required RestoreRequest req});
Future<SendPaymentResponse> sendPayment({required PrepareSendResponse req});

View File

@@ -55,7 +55,7 @@ class RustLib extends BaseEntrypoint<RustLibApi, RustLibApiImpl, RustLibWire> {
String get codegenVersion => '2.0.0';
@override
int get rustContentHash => 540580972;
int get rustContentHash => 671987080;
static const kDefaultExternalLibraryLoaderConfig = ExternalLibraryLoaderConfig(
stem: 'breez_liquid_sdk',
@@ -77,6 +77,8 @@ abstract class RustLibApi extends BaseApi {
Future<List<Payment>> crateBindingsBindingLiquidSdkListPayments({required BindingLiquidSdk that});
Future<List<RefundableSwap>> crateBindingsBindingLiquidSdkListRefundables({required BindingLiquidSdk that});
Future<LnUrlCallbackStatus> crateBindingsBindingLiquidSdkLnurlAuth(
{required BindingLiquidSdk that, required LnUrlAuthRequestData reqData});
@@ -92,15 +94,27 @@ abstract class RustLibApi extends BaseApi {
Future<PreparePayOnchainResponse> crateBindingsBindingLiquidSdkPreparePayOnchain(
{required BindingLiquidSdk that, required PreparePayOnchainRequest req});
Future<PrepareReceiveOnchainResponse> crateBindingsBindingLiquidSdkPrepareReceiveOnchain(
{required BindingLiquidSdk that, required PrepareReceiveOnchainRequest req});
Future<PrepareReceiveResponse> crateBindingsBindingLiquidSdkPrepareReceivePayment(
{required BindingLiquidSdk that, required PrepareReceiveRequest req});
Future<PrepareRefundResponse> crateBindingsBindingLiquidSdkPrepareRefund(
{required BindingLiquidSdk that, required PrepareRefundRequest req});
Future<PrepareSendResponse> crateBindingsBindingLiquidSdkPrepareSendPayment(
{required BindingLiquidSdk that, required PrepareSendRequest req});
Future<ReceiveOnchainResponse> crateBindingsBindingLiquidSdkReceiveOnchain(
{required BindingLiquidSdk that, required ReceiveOnchainRequest req});
Future<ReceivePaymentResponse> crateBindingsBindingLiquidSdkReceivePayment(
{required BindingLiquidSdk that, required PrepareReceiveResponse req});
Future<RefundResponse> crateBindingsBindingLiquidSdkRefund(
{required BindingLiquidSdk that, required RefundRequest req});
void crateBindingsBindingLiquidSdkRestore({required BindingLiquidSdk that, required RestoreRequest req});
Future<SendPaymentResponse> crateBindingsBindingLiquidSdkSendPayment(
@@ -284,6 +298,31 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
argNames: ["that"],
);
@override
Future<List<RefundableSwap>> crateBindingsBindingLiquidSdkListRefundables(
{required BindingLiquidSdk that}) {
return handler.executeNormal(NormalTask(
callFfi: (port_) {
var arg0 =
cst_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
that);
return wire.wire__crate__bindings__BindingLiquidSdk_list_refundables(port_, arg0);
},
codec: DcoCodec(
decodeSuccessData: dco_decode_list_refundable_swap,
decodeErrorData: dco_decode_liquid_sdk_error,
),
constMeta: kCrateBindingsBindingLiquidSdkListRefundablesConstMeta,
argValues: [that],
apiImpl: this,
));
}
TaskConstMeta get kCrateBindingsBindingLiquidSdkListRefundablesConstMeta => const TaskConstMeta(
debugName: "BindingLiquidSdk_list_refundables",
argNames: ["that"],
);
@override
Future<LnUrlCallbackStatus> crateBindingsBindingLiquidSdkLnurlAuth(
{required BindingLiquidSdk that, required LnUrlAuthRequestData reqData}) {
@@ -414,6 +453,32 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
argNames: ["that", "req"],
);
@override
Future<PrepareReceiveOnchainResponse> crateBindingsBindingLiquidSdkPrepareReceiveOnchain(
{required BindingLiquidSdk that, required PrepareReceiveOnchainRequest req}) {
return handler.executeNormal(NormalTask(
callFfi: (port_) {
var arg0 =
cst_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
that);
var arg1 = cst_encode_box_autoadd_prepare_receive_onchain_request(req);
return wire.wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchain(port_, arg0, arg1);
},
codec: DcoCodec(
decodeSuccessData: dco_decode_prepare_receive_onchain_response,
decodeErrorData: dco_decode_payment_error,
),
constMeta: kCrateBindingsBindingLiquidSdkPrepareReceiveOnchainConstMeta,
argValues: [that, req],
apiImpl: this,
));
}
TaskConstMeta get kCrateBindingsBindingLiquidSdkPrepareReceiveOnchainConstMeta => const TaskConstMeta(
debugName: "BindingLiquidSdk_prepare_receive_onchain",
argNames: ["that", "req"],
);
@override
Future<PrepareReceiveResponse> crateBindingsBindingLiquidSdkPrepareReceivePayment(
{required BindingLiquidSdk that, required PrepareReceiveRequest req}) {
@@ -440,6 +505,32 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
argNames: ["that", "req"],
);
@override
Future<PrepareRefundResponse> crateBindingsBindingLiquidSdkPrepareRefund(
{required BindingLiquidSdk that, required PrepareRefundRequest req}) {
return handler.executeNormal(NormalTask(
callFfi: (port_) {
var arg0 =
cst_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
that);
var arg1 = cst_encode_box_autoadd_prepare_refund_request(req);
return wire.wire__crate__bindings__BindingLiquidSdk_prepare_refund(port_, arg0, arg1);
},
codec: DcoCodec(
decodeSuccessData: dco_decode_prepare_refund_response,
decodeErrorData: dco_decode_liquid_sdk_error,
),
constMeta: kCrateBindingsBindingLiquidSdkPrepareRefundConstMeta,
argValues: [that, req],
apiImpl: this,
));
}
TaskConstMeta get kCrateBindingsBindingLiquidSdkPrepareRefundConstMeta => const TaskConstMeta(
debugName: "BindingLiquidSdk_prepare_refund",
argNames: ["that", "req"],
);
@override
Future<PrepareSendResponse> crateBindingsBindingLiquidSdkPrepareSendPayment(
{required BindingLiquidSdk that, required PrepareSendRequest req}) {
@@ -466,6 +557,32 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
argNames: ["that", "req"],
);
@override
Future<ReceiveOnchainResponse> crateBindingsBindingLiquidSdkReceiveOnchain(
{required BindingLiquidSdk that, required ReceiveOnchainRequest req}) {
return handler.executeNormal(NormalTask(
callFfi: (port_) {
var arg0 =
cst_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
that);
var arg1 = cst_encode_box_autoadd_receive_onchain_request(req);
return wire.wire__crate__bindings__BindingLiquidSdk_receive_onchain(port_, arg0, arg1);
},
codec: DcoCodec(
decodeSuccessData: dco_decode_receive_onchain_response,
decodeErrorData: dco_decode_payment_error,
),
constMeta: kCrateBindingsBindingLiquidSdkReceiveOnchainConstMeta,
argValues: [that, req],
apiImpl: this,
));
}
TaskConstMeta get kCrateBindingsBindingLiquidSdkReceiveOnchainConstMeta => const TaskConstMeta(
debugName: "BindingLiquidSdk_receive_onchain",
argNames: ["that", "req"],
);
@override
Future<ReceivePaymentResponse> crateBindingsBindingLiquidSdkReceivePayment(
{required BindingLiquidSdk that, required PrepareReceiveResponse req}) {
@@ -492,6 +609,32 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
argNames: ["that", "req"],
);
@override
Future<RefundResponse> crateBindingsBindingLiquidSdkRefund(
{required BindingLiquidSdk that, required RefundRequest req}) {
return handler.executeNormal(NormalTask(
callFfi: (port_) {
var arg0 =
cst_encode_Auto_Ref_RustOpaque_flutter_rust_bridgefor_generatedRustAutoOpaqueInnerBindingLiquidSdk(
that);
var arg1 = cst_encode_box_autoadd_refund_request(req);
return wire.wire__crate__bindings__BindingLiquidSdk_refund(port_, arg0, arg1);
},
codec: DcoCodec(
decodeSuccessData: dco_decode_refund_response,
decodeErrorData: dco_decode_payment_error,
),
constMeta: kCrateBindingsBindingLiquidSdkRefundConstMeta,
argValues: [that, req],
apiImpl: this,
));
}
TaskConstMeta get kCrateBindingsBindingLiquidSdkRefundConstMeta => const TaskConstMeta(
debugName: "BindingLiquidSdk_refund",
argNames: ["that", "req"],
);
@override
void crateBindingsBindingLiquidSdkRestore({required BindingLiquidSdk that, required RestoreRequest req}) {
return handler.executeSync(SyncTask(
@@ -951,6 +1094,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return dco_decode_prepare_pay_onchain_request(raw);
}
@protected
PrepareReceiveOnchainRequest dco_decode_box_autoadd_prepare_receive_onchain_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return dco_decode_prepare_receive_onchain_request(raw);
}
@protected
PrepareReceiveRequest dco_decode_box_autoadd_prepare_receive_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -963,6 +1112,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return dco_decode_prepare_receive_response(raw);
}
@protected
PrepareRefundRequest dco_decode_box_autoadd_prepare_refund_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return dco_decode_prepare_refund_request(raw);
}
@protected
PrepareSendRequest dco_decode_box_autoadd_prepare_send_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -975,6 +1130,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return dco_decode_prepare_send_response(raw);
}
@protected
ReceiveOnchainRequest dco_decode_box_autoadd_receive_onchain_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return dco_decode_receive_onchain_request(raw);
}
@protected
RefundRequest dco_decode_box_autoadd_refund_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return dco_decode_refund_request(raw);
}
@protected
RestoreRequest dco_decode_box_autoadd_restore_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -1167,6 +1334,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return raw as Uint8List;
}
@protected
List<RefundableSwap> dco_decode_list_refundable_swap(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return (raw as List<dynamic>).map(dco_decode_refundable_swap).toList();
}
@protected
List<RouteHint> dco_decode_list_route_hint(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -1643,6 +1816,27 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
);
}
@protected
PrepareReceiveOnchainRequest dco_decode_prepare_receive_onchain_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 1) throw Exception('unexpected arr length: expect 1 but see ${arr.length}');
return PrepareReceiveOnchainRequest(
amountSat: dco_decode_u_64(arr[0]),
);
}
@protected
PrepareReceiveOnchainResponse dco_decode_prepare_receive_onchain_response(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}');
return PrepareReceiveOnchainResponse(
amountSat: dco_decode_u_64(arr[0]),
feesSat: dco_decode_u_64(arr[1]),
);
}
@protected
PrepareReceiveRequest dco_decode_prepare_receive_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -1664,6 +1858,29 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
);
}
@protected
PrepareRefundRequest dco_decode_prepare_refund_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 3) throw Exception('unexpected arr length: expect 3 but see ${arr.length}');
return PrepareRefundRequest(
swapAddress: dco_decode_String(arr[0]),
refundAddress: dco_decode_String(arr[1]),
satPerVbyte: dco_decode_u_32(arr[2]),
);
}
@protected
PrepareRefundResponse dco_decode_prepare_refund_response(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}');
return PrepareRefundResponse(
refundTxVsize: dco_decode_u_32(arr[0]),
refundTxFeeSat: dco_decode_u_64(arr[1]),
);
}
@protected
PrepareSendRequest dco_decode_prepare_send_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -1685,6 +1902,27 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
);
}
@protected
ReceiveOnchainRequest dco_decode_receive_onchain_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 1) throw Exception('unexpected arr length: expect 1 but see ${arr.length}');
return ReceiveOnchainRequest(
prepareRes: dco_decode_prepare_receive_onchain_response(arr[0]),
);
}
@protected
ReceiveOnchainResponse dco_decode_receive_onchain_response(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}');
return ReceiveOnchainResponse(
address: dco_decode_String(arr[0]),
bip21: dco_decode_String(arr[1]),
);
}
@protected
ReceivePaymentResponse dco_decode_receive_payment_response(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -1696,6 +1934,40 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
);
}
@protected
RefundRequest dco_decode_refund_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 3) throw Exception('unexpected arr length: expect 3 but see ${arr.length}');
return RefundRequest(
swapAddress: dco_decode_String(arr[0]),
refundAddress: dco_decode_String(arr[1]),
satPerVbyte: dco_decode_u_32(arr[2]),
);
}
@protected
RefundResponse dco_decode_refund_response(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 1) throw Exception('unexpected arr length: expect 1 but see ${arr.length}');
return RefundResponse(
refundTxId: dco_decode_String(arr[0]),
);
}
@protected
RefundableSwap dco_decode_refundable_swap(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 3) throw Exception('unexpected arr length: expect 3 but see ${arr.length}');
return RefundableSwap(
swapAddress: dco_decode_String(arr[0]),
timestamp: dco_decode_u_32(arr[1]),
amountSat: dco_decode_u_64(arr[2]),
);
}
@protected
RestoreRequest dco_decode_restore_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -2051,6 +2323,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return (sse_decode_prepare_pay_onchain_request(deserializer));
}
@protected
PrepareReceiveOnchainRequest sse_decode_box_autoadd_prepare_receive_onchain_request(
SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
return (sse_decode_prepare_receive_onchain_request(deserializer));
}
@protected
PrepareReceiveRequest sse_decode_box_autoadd_prepare_receive_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -2063,6 +2342,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return (sse_decode_prepare_receive_response(deserializer));
}
@protected
PrepareRefundRequest sse_decode_box_autoadd_prepare_refund_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
return (sse_decode_prepare_refund_request(deserializer));
}
@protected
PrepareSendRequest sse_decode_box_autoadd_prepare_send_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -2075,6 +2360,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return (sse_decode_prepare_send_response(deserializer));
}
@protected
ReceiveOnchainRequest sse_decode_box_autoadd_receive_onchain_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
return (sse_decode_receive_onchain_request(deserializer));
}
@protected
RefundRequest sse_decode_box_autoadd_refund_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
return (sse_decode_refund_request(deserializer));
}
@protected
RestoreRequest sse_decode_box_autoadd_restore_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -2268,6 +2565,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return deserializer.buffer.getUint8List(len_);
}
@protected
List<RefundableSwap> sse_decode_list_refundable_swap(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var len_ = sse_decode_i_32(deserializer);
var ans_ = <RefundableSwap>[];
for (var idx_ = 0; idx_ < len_; ++idx_) {
ans_.add(sse_decode_refundable_swap(deserializer));
}
return ans_;
}
@protected
List<RouteHint> sse_decode_list_route_hint(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -2745,6 +3054,21 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return PreparePayOnchainResponse(amountSat: var_amountSat, feesSat: var_feesSat);
}
@protected
PrepareReceiveOnchainRequest sse_decode_prepare_receive_onchain_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_amountSat = sse_decode_u_64(deserializer);
return PrepareReceiveOnchainRequest(amountSat: var_amountSat);
}
@protected
PrepareReceiveOnchainResponse sse_decode_prepare_receive_onchain_response(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_amountSat = sse_decode_u_64(deserializer);
var var_feesSat = sse_decode_u_64(deserializer);
return PrepareReceiveOnchainResponse(amountSat: var_amountSat, feesSat: var_feesSat);
}
@protected
PrepareReceiveRequest sse_decode_prepare_receive_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -2760,6 +3084,24 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return PrepareReceiveResponse(payerAmountSat: var_payerAmountSat, feesSat: var_feesSat);
}
@protected
PrepareRefundRequest sse_decode_prepare_refund_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_swapAddress = sse_decode_String(deserializer);
var var_refundAddress = sse_decode_String(deserializer);
var var_satPerVbyte = sse_decode_u_32(deserializer);
return PrepareRefundRequest(
swapAddress: var_swapAddress, refundAddress: var_refundAddress, satPerVbyte: var_satPerVbyte);
}
@protected
PrepareRefundResponse sse_decode_prepare_refund_response(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_refundTxVsize = sse_decode_u_32(deserializer);
var var_refundTxFeeSat = sse_decode_u_64(deserializer);
return PrepareRefundResponse(refundTxVsize: var_refundTxVsize, refundTxFeeSat: var_refundTxFeeSat);
}
@protected
PrepareSendRequest sse_decode_prepare_send_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -2775,6 +3117,21 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return PrepareSendResponse(invoice: var_invoice, feesSat: var_feesSat);
}
@protected
ReceiveOnchainRequest sse_decode_receive_onchain_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_prepareRes = sse_decode_prepare_receive_onchain_response(deserializer);
return ReceiveOnchainRequest(prepareRes: var_prepareRes);
}
@protected
ReceiveOnchainResponse sse_decode_receive_onchain_response(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_address = sse_decode_String(deserializer);
var var_bip21 = sse_decode_String(deserializer);
return ReceiveOnchainResponse(address: var_address, bip21: var_bip21);
}
@protected
ReceivePaymentResponse sse_decode_receive_payment_response(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -2783,6 +3140,32 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return ReceivePaymentResponse(id: var_id, invoice: var_invoice);
}
@protected
RefundRequest sse_decode_refund_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_swapAddress = sse_decode_String(deserializer);
var var_refundAddress = sse_decode_String(deserializer);
var var_satPerVbyte = sse_decode_u_32(deserializer);
return RefundRequest(
swapAddress: var_swapAddress, refundAddress: var_refundAddress, satPerVbyte: var_satPerVbyte);
}
@protected
RefundResponse sse_decode_refund_response(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_refundTxId = sse_decode_String(deserializer);
return RefundResponse(refundTxId: var_refundTxId);
}
@protected
RefundableSwap sse_decode_refundable_swap(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_swapAddress = sse_decode_String(deserializer);
var var_timestamp = sse_decode_u_32(deserializer);
var var_amountSat = sse_decode_u_64(deserializer);
return RefundableSwap(swapAddress: var_swapAddress, timestamp: var_timestamp, amountSat: var_amountSat);
}
@protected
RestoreRequest sse_decode_restore_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -3218,6 +3601,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_prepare_pay_onchain_request(self, serializer);
}
@protected
void sse_encode_box_autoadd_prepare_receive_onchain_request(
PrepareReceiveOnchainRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_prepare_receive_onchain_request(self, serializer);
}
@protected
void sse_encode_box_autoadd_prepare_receive_request(PrepareReceiveRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -3231,6 +3621,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_prepare_receive_response(self, serializer);
}
@protected
void sse_encode_box_autoadd_prepare_refund_request(PrepareRefundRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_prepare_refund_request(self, serializer);
}
@protected
void sse_encode_box_autoadd_prepare_send_request(PrepareSendRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -3243,6 +3639,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_prepare_send_response(self, serializer);
}
@protected
void sse_encode_box_autoadd_receive_onchain_request(ReceiveOnchainRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_receive_onchain_request(self, serializer);
}
@protected
void sse_encode_box_autoadd_refund_request(RefundRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_refund_request(self, serializer);
}
@protected
void sse_encode_box_autoadd_restore_request(RestoreRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -3412,6 +3820,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
serializer.buffer.putUint8List(self);
}
@protected
void sse_encode_list_refundable_swap(List<RefundableSwap> self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_i_32(self.length, serializer);
for (final item in self) {
sse_encode_refundable_swap(item, serializer);
}
}
@protected
void sse_encode_list_route_hint(List<RouteHint> self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -3810,6 +4227,21 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_u_64(self.feesSat, serializer);
}
@protected
void sse_encode_prepare_receive_onchain_request(
PrepareReceiveOnchainRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_u_64(self.amountSat, serializer);
}
@protected
void sse_encode_prepare_receive_onchain_response(
PrepareReceiveOnchainResponse self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_u_64(self.amountSat, serializer);
sse_encode_u_64(self.feesSat, serializer);
}
@protected
void sse_encode_prepare_receive_request(PrepareReceiveRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -3823,6 +4255,21 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_u_64(self.feesSat, serializer);
}
@protected
void sse_encode_prepare_refund_request(PrepareRefundRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_String(self.swapAddress, serializer);
sse_encode_String(self.refundAddress, serializer);
sse_encode_u_32(self.satPerVbyte, serializer);
}
@protected
void sse_encode_prepare_refund_response(PrepareRefundResponse self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_u_32(self.refundTxVsize, serializer);
sse_encode_u_64(self.refundTxFeeSat, serializer);
}
@protected
void sse_encode_prepare_send_request(PrepareSendRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -3836,6 +4283,19 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_u_64(self.feesSat, serializer);
}
@protected
void sse_encode_receive_onchain_request(ReceiveOnchainRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_prepare_receive_onchain_response(self.prepareRes, serializer);
}
@protected
void sse_encode_receive_onchain_response(ReceiveOnchainResponse self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_String(self.address, serializer);
sse_encode_String(self.bip21, serializer);
}
@protected
void sse_encode_receive_payment_response(ReceivePaymentResponse self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -3843,6 +4303,28 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_String(self.invoice, serializer);
}
@protected
void sse_encode_refund_request(RefundRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_String(self.swapAddress, serializer);
sse_encode_String(self.refundAddress, serializer);
sse_encode_u_32(self.satPerVbyte, serializer);
}
@protected
void sse_encode_refund_response(RefundResponse self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_String(self.refundTxId, serializer);
}
@protected
void sse_encode_refundable_swap(RefundableSwap self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_String(self.swapAddress, serializer);
sse_encode_u_32(self.timestamp, serializer);
sse_encode_u_64(self.amountSat, serializer);
}
@protected
void sse_encode_restore_request(RestoreRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -3974,6 +4456,11 @@ class BindingLiquidSdkImpl extends RustOpaque implements BindingLiquidSdk {
that: this,
);
Future<List<RefundableSwap>> listRefundables() =>
RustLib.instance.api.crateBindingsBindingLiquidSdkListRefundables(
that: this,
);
Future<LnUrlCallbackStatus> lnurlAuth({required LnUrlAuthRequestData reqData}) =>
RustLib.instance.api.crateBindingsBindingLiquidSdkLnurlAuth(that: this, reqData: reqData);
@@ -3989,15 +4476,27 @@ class BindingLiquidSdkImpl extends RustOpaque implements BindingLiquidSdk {
Future<PreparePayOnchainResponse> preparePayOnchain({required PreparePayOnchainRequest req}) =>
RustLib.instance.api.crateBindingsBindingLiquidSdkPreparePayOnchain(that: this, req: req);
Future<PrepareReceiveOnchainResponse> prepareReceiveOnchain({required PrepareReceiveOnchainRequest req}) =>
RustLib.instance.api.crateBindingsBindingLiquidSdkPrepareReceiveOnchain(that: this, req: req);
Future<PrepareReceiveResponse> prepareReceivePayment({required PrepareReceiveRequest req}) =>
RustLib.instance.api.crateBindingsBindingLiquidSdkPrepareReceivePayment(that: this, req: req);
Future<PrepareRefundResponse> prepareRefund({required PrepareRefundRequest req}) =>
RustLib.instance.api.crateBindingsBindingLiquidSdkPrepareRefund(that: this, req: req);
Future<PrepareSendResponse> prepareSendPayment({required PrepareSendRequest req}) =>
RustLib.instance.api.crateBindingsBindingLiquidSdkPrepareSendPayment(that: this, req: req);
Future<ReceiveOnchainResponse> receiveOnchain({required ReceiveOnchainRequest req}) =>
RustLib.instance.api.crateBindingsBindingLiquidSdkReceiveOnchain(that: this, req: req);
Future<ReceivePaymentResponse> receivePayment({required PrepareReceiveResponse req}) =>
RustLib.instance.api.crateBindingsBindingLiquidSdkReceivePayment(that: this, req: req);
Future<RefundResponse> refund({required RefundRequest req}) =>
RustLib.instance.api.crateBindingsBindingLiquidSdkRefund(that: this, req: req);
void restore({required RestoreRequest req}) =>
RustLib.instance.api.crateBindingsBindingLiquidSdkRestore(that: this, req: req);

View File

@@ -131,18 +131,30 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
PreparePayOnchainRequest dco_decode_box_autoadd_prepare_pay_onchain_request(dynamic raw);
@protected
PrepareReceiveOnchainRequest dco_decode_box_autoadd_prepare_receive_onchain_request(dynamic raw);
@protected
PrepareReceiveRequest dco_decode_box_autoadd_prepare_receive_request(dynamic raw);
@protected
PrepareReceiveResponse dco_decode_box_autoadd_prepare_receive_response(dynamic raw);
@protected
PrepareRefundRequest dco_decode_box_autoadd_prepare_refund_request(dynamic raw);
@protected
PrepareSendRequest dco_decode_box_autoadd_prepare_send_request(dynamic raw);
@protected
PrepareSendResponse dco_decode_box_autoadd_prepare_send_response(dynamic raw);
@protected
ReceiveOnchainRequest dco_decode_box_autoadd_receive_onchain_request(dynamic raw);
@protected
RefundRequest dco_decode_box_autoadd_refund_request(dynamic raw);
@protected
RestoreRequest dco_decode_box_autoadd_restore_request(dynamic raw);
@@ -188,6 +200,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
Uint8List dco_decode_list_prim_u_8_strict(dynamic raw);
@protected
List<RefundableSwap> dco_decode_list_refundable_swap(dynamic raw);
@protected
List<RouteHint> dco_decode_list_route_hint(dynamic raw);
@@ -281,21 +296,48 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
PreparePayOnchainResponse dco_decode_prepare_pay_onchain_response(dynamic raw);
@protected
PrepareReceiveOnchainRequest dco_decode_prepare_receive_onchain_request(dynamic raw);
@protected
PrepareReceiveOnchainResponse dco_decode_prepare_receive_onchain_response(dynamic raw);
@protected
PrepareReceiveRequest dco_decode_prepare_receive_request(dynamic raw);
@protected
PrepareReceiveResponse dco_decode_prepare_receive_response(dynamic raw);
@protected
PrepareRefundRequest dco_decode_prepare_refund_request(dynamic raw);
@protected
PrepareRefundResponse dco_decode_prepare_refund_response(dynamic raw);
@protected
PrepareSendRequest dco_decode_prepare_send_request(dynamic raw);
@protected
PrepareSendResponse dco_decode_prepare_send_response(dynamic raw);
@protected
ReceiveOnchainRequest dco_decode_receive_onchain_request(dynamic raw);
@protected
ReceiveOnchainResponse dco_decode_receive_onchain_response(dynamic raw);
@protected
ReceivePaymentResponse dco_decode_receive_payment_response(dynamic raw);
@protected
RefundRequest dco_decode_refund_request(dynamic raw);
@protected
RefundResponse dco_decode_refund_response(dynamic raw);
@protected
RefundableSwap dco_decode_refundable_swap(dynamic raw);
@protected
RestoreRequest dco_decode_restore_request(dynamic raw);
@@ -441,18 +483,31 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
PreparePayOnchainRequest sse_decode_box_autoadd_prepare_pay_onchain_request(SseDeserializer deserializer);
@protected
PrepareReceiveOnchainRequest sse_decode_box_autoadd_prepare_receive_onchain_request(
SseDeserializer deserializer);
@protected
PrepareReceiveRequest sse_decode_box_autoadd_prepare_receive_request(SseDeserializer deserializer);
@protected
PrepareReceiveResponse sse_decode_box_autoadd_prepare_receive_response(SseDeserializer deserializer);
@protected
PrepareRefundRequest sse_decode_box_autoadd_prepare_refund_request(SseDeserializer deserializer);
@protected
PrepareSendRequest sse_decode_box_autoadd_prepare_send_request(SseDeserializer deserializer);
@protected
PrepareSendResponse sse_decode_box_autoadd_prepare_send_response(SseDeserializer deserializer);
@protected
ReceiveOnchainRequest sse_decode_box_autoadd_receive_onchain_request(SseDeserializer deserializer);
@protected
RefundRequest sse_decode_box_autoadd_refund_request(SseDeserializer deserializer);
@protected
RestoreRequest sse_decode_box_autoadd_restore_request(SseDeserializer deserializer);
@@ -498,6 +553,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
Uint8List sse_decode_list_prim_u_8_strict(SseDeserializer deserializer);
@protected
List<RefundableSwap> sse_decode_list_refundable_swap(SseDeserializer deserializer);
@protected
List<RouteHint> sse_decode_list_route_hint(SseDeserializer deserializer);
@@ -591,21 +649,48 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
PreparePayOnchainResponse sse_decode_prepare_pay_onchain_response(SseDeserializer deserializer);
@protected
PrepareReceiveOnchainRequest sse_decode_prepare_receive_onchain_request(SseDeserializer deserializer);
@protected
PrepareReceiveOnchainResponse sse_decode_prepare_receive_onchain_response(SseDeserializer deserializer);
@protected
PrepareReceiveRequest sse_decode_prepare_receive_request(SseDeserializer deserializer);
@protected
PrepareReceiveResponse sse_decode_prepare_receive_response(SseDeserializer deserializer);
@protected
PrepareRefundRequest sse_decode_prepare_refund_request(SseDeserializer deserializer);
@protected
PrepareRefundResponse sse_decode_prepare_refund_response(SseDeserializer deserializer);
@protected
PrepareSendRequest sse_decode_prepare_send_request(SseDeserializer deserializer);
@protected
PrepareSendResponse sse_decode_prepare_send_response(SseDeserializer deserializer);
@protected
ReceiveOnchainRequest sse_decode_receive_onchain_request(SseDeserializer deserializer);
@protected
ReceiveOnchainResponse sse_decode_receive_onchain_response(SseDeserializer deserializer);
@protected
ReceivePaymentResponse sse_decode_receive_payment_response(SseDeserializer deserializer);
@protected
RefundRequest sse_decode_refund_request(SseDeserializer deserializer);
@protected
RefundResponse sse_decode_refund_response(SseDeserializer deserializer);
@protected
RefundableSwap sse_decode_refundable_swap(SseDeserializer deserializer);
@protected
RestoreRequest sse_decode_restore_request(SseDeserializer deserializer);
@@ -858,6 +943,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
return ptr;
}
@protected
ffi.Pointer<wire_cst_prepare_receive_onchain_request>
cst_encode_box_autoadd_prepare_receive_onchain_request(PrepareReceiveOnchainRequest raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
final ptr = wire.cst_new_box_autoadd_prepare_receive_onchain_request();
cst_api_fill_to_wire_prepare_receive_onchain_request(raw, ptr.ref);
return ptr;
}
@protected
ffi.Pointer<wire_cst_prepare_receive_request> cst_encode_box_autoadd_prepare_receive_request(
PrepareReceiveRequest raw) {
@@ -876,6 +970,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
return ptr;
}
@protected
ffi.Pointer<wire_cst_prepare_refund_request> cst_encode_box_autoadd_prepare_refund_request(
PrepareRefundRequest raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
final ptr = wire.cst_new_box_autoadd_prepare_refund_request();
cst_api_fill_to_wire_prepare_refund_request(raw, ptr.ref);
return ptr;
}
@protected
ffi.Pointer<wire_cst_prepare_send_request> cst_encode_box_autoadd_prepare_send_request(
PrepareSendRequest raw) {
@@ -894,6 +997,23 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
return ptr;
}
@protected
ffi.Pointer<wire_cst_receive_onchain_request> cst_encode_box_autoadd_receive_onchain_request(
ReceiveOnchainRequest raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
final ptr = wire.cst_new_box_autoadd_receive_onchain_request();
cst_api_fill_to_wire_receive_onchain_request(raw, ptr.ref);
return ptr;
}
@protected
ffi.Pointer<wire_cst_refund_request> cst_encode_box_autoadd_refund_request(RefundRequest raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
final ptr = wire.cst_new_box_autoadd_refund_request();
cst_api_fill_to_wire_refund_request(raw, ptr.ref);
return ptr;
}
@protected
ffi.Pointer<wire_cst_restore_request> cst_encode_box_autoadd_restore_request(RestoreRequest raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
@@ -944,6 +1064,16 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
return ans;
}
@protected
ffi.Pointer<wire_cst_list_refundable_swap> cst_encode_list_refundable_swap(List<RefundableSwap> raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
final ans = wire.cst_new_list_refundable_swap(raw.length);
for (var i = 0; i < raw.length; ++i) {
cst_api_fill_to_wire_refundable_swap(raw[i], ans.ref.ptr[i]);
}
return ans;
}
@protected
ffi.Pointer<wire_cst_list_route_hint> cst_encode_list_route_hint(List<RouteHint> raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
@@ -1165,6 +1295,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
cst_api_fill_to_wire_prepare_pay_onchain_request(apiObj, wireObj.ref);
}
@protected
void cst_api_fill_to_wire_box_autoadd_prepare_receive_onchain_request(
PrepareReceiveOnchainRequest apiObj, ffi.Pointer<wire_cst_prepare_receive_onchain_request> wireObj) {
cst_api_fill_to_wire_prepare_receive_onchain_request(apiObj, wireObj.ref);
}
@protected
void cst_api_fill_to_wire_box_autoadd_prepare_receive_request(
PrepareReceiveRequest apiObj, ffi.Pointer<wire_cst_prepare_receive_request> wireObj) {
@@ -1177,6 +1313,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
cst_api_fill_to_wire_prepare_receive_response(apiObj, wireObj.ref);
}
@protected
void cst_api_fill_to_wire_box_autoadd_prepare_refund_request(
PrepareRefundRequest apiObj, ffi.Pointer<wire_cst_prepare_refund_request> wireObj) {
cst_api_fill_to_wire_prepare_refund_request(apiObj, wireObj.ref);
}
@protected
void cst_api_fill_to_wire_box_autoadd_prepare_send_request(
PrepareSendRequest apiObj, ffi.Pointer<wire_cst_prepare_send_request> wireObj) {
@@ -1189,6 +1331,18 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
cst_api_fill_to_wire_prepare_send_response(apiObj, wireObj.ref);
}
@protected
void cst_api_fill_to_wire_box_autoadd_receive_onchain_request(
ReceiveOnchainRequest apiObj, ffi.Pointer<wire_cst_receive_onchain_request> wireObj) {
cst_api_fill_to_wire_receive_onchain_request(apiObj, wireObj.ref);
}
@protected
void cst_api_fill_to_wire_box_autoadd_refund_request(
RefundRequest apiObj, ffi.Pointer<wire_cst_refund_request> wireObj) {
cst_api_fill_to_wire_refund_request(apiObj, wireObj.ref);
}
@protected
void cst_api_fill_to_wire_box_autoadd_restore_request(
RestoreRequest apiObj, ffi.Pointer<wire_cst_restore_request> wireObj) {
@@ -1773,6 +1927,19 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
wireObj.fees_sat = cst_encode_u_64(apiObj.feesSat);
}
@protected
void cst_api_fill_to_wire_prepare_receive_onchain_request(
PrepareReceiveOnchainRequest apiObj, wire_cst_prepare_receive_onchain_request wireObj) {
wireObj.amount_sat = cst_encode_u_64(apiObj.amountSat);
}
@protected
void cst_api_fill_to_wire_prepare_receive_onchain_response(
PrepareReceiveOnchainResponse apiObj, wire_cst_prepare_receive_onchain_response wireObj) {
wireObj.amount_sat = cst_encode_u_64(apiObj.amountSat);
wireObj.fees_sat = cst_encode_u_64(apiObj.feesSat);
}
@protected
void cst_api_fill_to_wire_prepare_receive_request(
PrepareReceiveRequest apiObj, wire_cst_prepare_receive_request wireObj) {
@@ -1786,6 +1953,21 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
wireObj.fees_sat = cst_encode_u_64(apiObj.feesSat);
}
@protected
void cst_api_fill_to_wire_prepare_refund_request(
PrepareRefundRequest apiObj, wire_cst_prepare_refund_request wireObj) {
wireObj.swap_address = cst_encode_String(apiObj.swapAddress);
wireObj.refund_address = cst_encode_String(apiObj.refundAddress);
wireObj.sat_per_vbyte = cst_encode_u_32(apiObj.satPerVbyte);
}
@protected
void cst_api_fill_to_wire_prepare_refund_response(
PrepareRefundResponse apiObj, wire_cst_prepare_refund_response wireObj) {
wireObj.refund_tx_vsize = cst_encode_u_32(apiObj.refundTxVsize);
wireObj.refund_tx_fee_sat = cst_encode_u_64(apiObj.refundTxFeeSat);
}
@protected
void cst_api_fill_to_wire_prepare_send_request(
PrepareSendRequest apiObj, wire_cst_prepare_send_request wireObj) {
@@ -1799,6 +1981,19 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
wireObj.fees_sat = cst_encode_u_64(apiObj.feesSat);
}
@protected
void cst_api_fill_to_wire_receive_onchain_request(
ReceiveOnchainRequest apiObj, wire_cst_receive_onchain_request wireObj) {
cst_api_fill_to_wire_prepare_receive_onchain_response(apiObj.prepareRes, wireObj.prepare_res);
}
@protected
void cst_api_fill_to_wire_receive_onchain_response(
ReceiveOnchainResponse apiObj, wire_cst_receive_onchain_response wireObj) {
wireObj.address = cst_encode_String(apiObj.address);
wireObj.bip21 = cst_encode_String(apiObj.bip21);
}
@protected
void cst_api_fill_to_wire_receive_payment_response(
ReceivePaymentResponse apiObj, wire_cst_receive_payment_response wireObj) {
@@ -1806,6 +2001,25 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
wireObj.invoice = cst_encode_String(apiObj.invoice);
}
@protected
void cst_api_fill_to_wire_refund_request(RefundRequest apiObj, wire_cst_refund_request wireObj) {
wireObj.swap_address = cst_encode_String(apiObj.swapAddress);
wireObj.refund_address = cst_encode_String(apiObj.refundAddress);
wireObj.sat_per_vbyte = cst_encode_u_32(apiObj.satPerVbyte);
}
@protected
void cst_api_fill_to_wire_refund_response(RefundResponse apiObj, wire_cst_refund_response wireObj) {
wireObj.refund_tx_id = cst_encode_String(apiObj.refundTxId);
}
@protected
void cst_api_fill_to_wire_refundable_swap(RefundableSwap apiObj, wire_cst_refundable_swap wireObj) {
wireObj.swap_address = cst_encode_String(apiObj.swapAddress);
wireObj.timestamp = cst_encode_u_32(apiObj.timestamp);
wireObj.amount_sat = cst_encode_u_64(apiObj.amountSat);
}
@protected
void cst_api_fill_to_wire_restore_request(RestoreRequest apiObj, wire_cst_restore_request wireObj) {
wireObj.backup_path = cst_encode_opt_String(apiObj.backupPath);
@@ -2021,18 +2235,31 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
void sse_encode_box_autoadd_prepare_pay_onchain_request(
PreparePayOnchainRequest self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_prepare_receive_onchain_request(
PrepareReceiveOnchainRequest self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_prepare_receive_request(PrepareReceiveRequest self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_prepare_receive_response(PrepareReceiveResponse self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_prepare_refund_request(PrepareRefundRequest self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_prepare_send_request(PrepareSendRequest self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_prepare_send_response(PrepareSendResponse self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_receive_onchain_request(ReceiveOnchainRequest self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_refund_request(RefundRequest self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_restore_request(RestoreRequest self, SseSerializer serializer);
@@ -2078,6 +2305,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_list_prim_u_8_strict(Uint8List self, SseSerializer serializer);
@protected
void sse_encode_list_refundable_swap(List<RefundableSwap> self, SseSerializer serializer);
@protected
void sse_encode_list_route_hint(List<RouteHint> self, SseSerializer serializer);
@@ -2172,21 +2402,50 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_prepare_pay_onchain_response(PreparePayOnchainResponse self, SseSerializer serializer);
@protected
void sse_encode_prepare_receive_onchain_request(
PrepareReceiveOnchainRequest self, SseSerializer serializer);
@protected
void sse_encode_prepare_receive_onchain_response(
PrepareReceiveOnchainResponse self, SseSerializer serializer);
@protected
void sse_encode_prepare_receive_request(PrepareReceiveRequest self, SseSerializer serializer);
@protected
void sse_encode_prepare_receive_response(PrepareReceiveResponse self, SseSerializer serializer);
@protected
void sse_encode_prepare_refund_request(PrepareRefundRequest self, SseSerializer serializer);
@protected
void sse_encode_prepare_refund_response(PrepareRefundResponse self, SseSerializer serializer);
@protected
void sse_encode_prepare_send_request(PrepareSendRequest self, SseSerializer serializer);
@protected
void sse_encode_prepare_send_response(PrepareSendResponse self, SseSerializer serializer);
@protected
void sse_encode_receive_onchain_request(ReceiveOnchainRequest self, SseSerializer serializer);
@protected
void sse_encode_receive_onchain_response(ReceiveOnchainResponse self, SseSerializer serializer);
@protected
void sse_encode_receive_payment_response(ReceivePaymentResponse self, SseSerializer serializer);
@protected
void sse_encode_refund_request(RefundRequest self, SseSerializer serializer);
@protected
void sse_encode_refund_response(RefundResponse self, SseSerializer serializer);
@protected
void sse_encode_refundable_swap(RefundableSwap self, SseSerializer serializer);
@protected
void sse_encode_restore_request(RestoreRequest self, SseSerializer serializer);
@@ -2360,6 +2619,22 @@ class RustLibWire implements BaseWire {
late final _wire__crate__bindings__BindingLiquidSdk_list_payments =
_wire__crate__bindings__BindingLiquidSdk_list_paymentsPtr.asFunction<void Function(int, int)>();
void wire__crate__bindings__BindingLiquidSdk_list_refundables(
int port_,
int that,
) {
return _wire__crate__bindings__BindingLiquidSdk_list_refundables(
port_,
that,
);
}
late final _wire__crate__bindings__BindingLiquidSdk_list_refundablesPtr =
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int64, ffi.UintPtr)>>(
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_list_refundables');
late final _wire__crate__bindings__BindingLiquidSdk_list_refundables =
_wire__crate__bindings__BindingLiquidSdk_list_refundablesPtr.asFunction<void Function(int, int)>();
void wire__crate__bindings__BindingLiquidSdk_lnurl_auth(
int port_,
int that,
@@ -2460,6 +2735,27 @@ class RustLibWire implements BaseWire {
_wire__crate__bindings__BindingLiquidSdk_prepare_pay_onchainPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_prepare_pay_onchain_request>)>();
void wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchain(
int port_,
int that,
ffi.Pointer<wire_cst_prepare_receive_onchain_request> req,
) {
return _wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchain(
port_,
that,
req,
);
}
late final _wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchainPtr = _lookup<
ffi.NativeFunction<
ffi.Void Function(
ffi.Int64, ffi.UintPtr, ffi.Pointer<wire_cst_prepare_receive_onchain_request>)>>(
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchain');
late final _wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchain =
_wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchainPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_prepare_receive_onchain_request>)>();
void wire__crate__bindings__BindingLiquidSdk_prepare_receive_payment(
int port_,
int that,
@@ -2480,6 +2776,26 @@ class RustLibWire implements BaseWire {
_wire__crate__bindings__BindingLiquidSdk_prepare_receive_paymentPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_prepare_receive_request>)>();
void wire__crate__bindings__BindingLiquidSdk_prepare_refund(
int port_,
int that,
ffi.Pointer<wire_cst_prepare_refund_request> req,
) {
return _wire__crate__bindings__BindingLiquidSdk_prepare_refund(
port_,
that,
req,
);
}
late final _wire__crate__bindings__BindingLiquidSdk_prepare_refundPtr = _lookup<
ffi.NativeFunction<
ffi.Void Function(ffi.Int64, ffi.UintPtr, ffi.Pointer<wire_cst_prepare_refund_request>)>>(
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_refund');
late final _wire__crate__bindings__BindingLiquidSdk_prepare_refund =
_wire__crate__bindings__BindingLiquidSdk_prepare_refundPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_prepare_refund_request>)>();
void wire__crate__bindings__BindingLiquidSdk_prepare_send_payment(
int port_,
int that,
@@ -2500,6 +2816,26 @@ class RustLibWire implements BaseWire {
_wire__crate__bindings__BindingLiquidSdk_prepare_send_paymentPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_prepare_send_request>)>();
void wire__crate__bindings__BindingLiquidSdk_receive_onchain(
int port_,
int that,
ffi.Pointer<wire_cst_receive_onchain_request> req,
) {
return _wire__crate__bindings__BindingLiquidSdk_receive_onchain(
port_,
that,
req,
);
}
late final _wire__crate__bindings__BindingLiquidSdk_receive_onchainPtr = _lookup<
ffi.NativeFunction<
ffi.Void Function(ffi.Int64, ffi.UintPtr, ffi.Pointer<wire_cst_receive_onchain_request>)>>(
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_receive_onchain');
late final _wire__crate__bindings__BindingLiquidSdk_receive_onchain =
_wire__crate__bindings__BindingLiquidSdk_receive_onchainPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_receive_onchain_request>)>();
void wire__crate__bindings__BindingLiquidSdk_receive_payment(
int port_,
int that,
@@ -2520,6 +2856,26 @@ class RustLibWire implements BaseWire {
_wire__crate__bindings__BindingLiquidSdk_receive_paymentPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_prepare_receive_response>)>();
void wire__crate__bindings__BindingLiquidSdk_refund(
int port_,
int that,
ffi.Pointer<wire_cst_refund_request> req,
) {
return _wire__crate__bindings__BindingLiquidSdk_refund(
port_,
that,
req,
);
}
late final _wire__crate__bindings__BindingLiquidSdk_refundPtr = _lookup<
ffi
.NativeFunction<ffi.Void Function(ffi.Int64, ffi.UintPtr, ffi.Pointer<wire_cst_refund_request>)>>(
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_refund');
late final _wire__crate__bindings__BindingLiquidSdk_refund =
_wire__crate__bindings__BindingLiquidSdk_refundPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_refund_request>)>();
WireSyncRust2DartDco wire__crate__bindings__BindingLiquidSdk_restore(
int that,
ffi.Pointer<wire_cst_restore_request> req,
@@ -2921,6 +3277,18 @@ class RustLibWire implements BaseWire {
_cst_new_box_autoadd_prepare_pay_onchain_requestPtr
.asFunction<ffi.Pointer<wire_cst_prepare_pay_onchain_request> Function()>();
ffi.Pointer<wire_cst_prepare_receive_onchain_request>
cst_new_box_autoadd_prepare_receive_onchain_request() {
return _cst_new_box_autoadd_prepare_receive_onchain_request();
}
late final _cst_new_box_autoadd_prepare_receive_onchain_requestPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_prepare_receive_onchain_request> Function()>>(
'frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_onchain_request');
late final _cst_new_box_autoadd_prepare_receive_onchain_request =
_cst_new_box_autoadd_prepare_receive_onchain_requestPtr
.asFunction<ffi.Pointer<wire_cst_prepare_receive_onchain_request> Function()>();
ffi.Pointer<wire_cst_prepare_receive_request> cst_new_box_autoadd_prepare_receive_request() {
return _cst_new_box_autoadd_prepare_receive_request();
}
@@ -2941,6 +3309,16 @@ class RustLibWire implements BaseWire {
late final _cst_new_box_autoadd_prepare_receive_response = _cst_new_box_autoadd_prepare_receive_responsePtr
.asFunction<ffi.Pointer<wire_cst_prepare_receive_response> Function()>();
ffi.Pointer<wire_cst_prepare_refund_request> cst_new_box_autoadd_prepare_refund_request() {
return _cst_new_box_autoadd_prepare_refund_request();
}
late final _cst_new_box_autoadd_prepare_refund_requestPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_prepare_refund_request> Function()>>(
'frbgen_breez_liquid_cst_new_box_autoadd_prepare_refund_request');
late final _cst_new_box_autoadd_prepare_refund_request = _cst_new_box_autoadd_prepare_refund_requestPtr
.asFunction<ffi.Pointer<wire_cst_prepare_refund_request> Function()>();
ffi.Pointer<wire_cst_prepare_send_request> cst_new_box_autoadd_prepare_send_request() {
return _cst_new_box_autoadd_prepare_send_request();
}
@@ -2961,6 +3339,26 @@ class RustLibWire implements BaseWire {
late final _cst_new_box_autoadd_prepare_send_response = _cst_new_box_autoadd_prepare_send_responsePtr
.asFunction<ffi.Pointer<wire_cst_prepare_send_response> Function()>();
ffi.Pointer<wire_cst_receive_onchain_request> cst_new_box_autoadd_receive_onchain_request() {
return _cst_new_box_autoadd_receive_onchain_request();
}
late final _cst_new_box_autoadd_receive_onchain_requestPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_receive_onchain_request> Function()>>(
'frbgen_breez_liquid_cst_new_box_autoadd_receive_onchain_request');
late final _cst_new_box_autoadd_receive_onchain_request = _cst_new_box_autoadd_receive_onchain_requestPtr
.asFunction<ffi.Pointer<wire_cst_receive_onchain_request> Function()>();
ffi.Pointer<wire_cst_refund_request> cst_new_box_autoadd_refund_request() {
return _cst_new_box_autoadd_refund_request();
}
late final _cst_new_box_autoadd_refund_requestPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_refund_request> Function()>>(
'frbgen_breez_liquid_cst_new_box_autoadd_refund_request');
late final _cst_new_box_autoadd_refund_request =
_cst_new_box_autoadd_refund_requestPtr.asFunction<ffi.Pointer<wire_cst_refund_request> Function()>();
ffi.Pointer<wire_cst_restore_request> cst_new_box_autoadd_restore_request() {
return _cst_new_box_autoadd_restore_request();
}
@@ -3033,6 +3431,20 @@ class RustLibWire implements BaseWire {
late final _cst_new_list_prim_u_8_strict =
_cst_new_list_prim_u_8_strictPtr.asFunction<ffi.Pointer<wire_cst_list_prim_u_8_strict> Function(int)>();
ffi.Pointer<wire_cst_list_refundable_swap> cst_new_list_refundable_swap(
int len,
) {
return _cst_new_list_refundable_swap(
len,
);
}
late final _cst_new_list_refundable_swapPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_list_refundable_swap> Function(ffi.Int32)>>(
'frbgen_breez_liquid_cst_new_list_refundable_swap');
late final _cst_new_list_refundable_swap =
_cst_new_list_refundable_swapPtr.asFunction<ffi.Pointer<wire_cst_list_refundable_swap> Function(int)>();
ffi.Pointer<wire_cst_list_route_hint> cst_new_list_route_hint(
int len,
) {
@@ -3176,15 +3588,41 @@ final class wire_cst_prepare_pay_onchain_request extends ffi.Struct {
external int amount_sat;
}
final class wire_cst_prepare_receive_onchain_request extends ffi.Struct {
@ffi.Uint64()
external int amount_sat;
}
final class wire_cst_prepare_receive_request extends ffi.Struct {
@ffi.Uint64()
external int payer_amount_sat;
}
final class wire_cst_prepare_refund_request extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> swap_address;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> refund_address;
@ffi.Uint32()
external int sat_per_vbyte;
}
final class wire_cst_prepare_send_request extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> invoice;
}
final class wire_cst_prepare_receive_onchain_response extends ffi.Struct {
@ffi.Uint64()
external int amount_sat;
@ffi.Uint64()
external int fees_sat;
}
final class wire_cst_receive_onchain_request extends ffi.Struct {
external wire_cst_prepare_receive_onchain_response prepare_res;
}
final class wire_cst_prepare_receive_response extends ffi.Struct {
@ffi.Uint64()
external int payer_amount_sat;
@@ -3193,6 +3631,15 @@ final class wire_cst_prepare_receive_response extends ffi.Struct {
external int fees_sat;
}
final class wire_cst_refund_request extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> swap_address;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> refund_address;
@ffi.Uint32()
external int sat_per_vbyte;
}
final class wire_cst_restore_request extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> backup_path;
}
@@ -3481,6 +3928,23 @@ final class wire_cst_list_payment extends ffi.Struct {
external int len;
}
final class wire_cst_refundable_swap extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> swap_address;
@ffi.Uint32()
external int timestamp;
@ffi.Uint64()
external int amount_sat;
}
final class wire_cst_list_refundable_swap extends ffi.Struct {
external ffi.Pointer<wire_cst_refundable_swap> ptr;
@ffi.Int32()
external int len;
}
final class wire_cst_get_info_response extends ffi.Struct {
@ffi.Uint64()
external int balance_sat;
@@ -3841,16 +4305,36 @@ final class wire_cst_payment_error extends ffi.Struct {
external PaymentErrorKind kind;
}
final class wire_cst_prepare_refund_response extends ffi.Struct {
@ffi.Uint32()
external int refund_tx_vsize;
@ffi.Uint64()
external int refund_tx_fee_sat;
}
final class wire_cst_receive_onchain_response extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> address;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> bip21;
}
final class wire_cst_receive_payment_response extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> id;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> invoice;
}
final class wire_cst_refund_response extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> refund_tx_id;
}
final class wire_cst_send_payment_response extends ffi.Struct {
external wire_cst_payment payment;
}
const double LOWBALL_FEE_RATE_SAT_PER_VBYTE = 0.01;
const double DEFAULT_ZERO_CONF_MIN_FEE_RATE_TESTNET = 0.1;
const double DEFAULT_ZERO_CONF_MIN_FEE_RATE_MAINNET = 0.01;

View File

@@ -409,6 +409,12 @@ enum PaymentState {
/// This covers the case when the swap state is still Created and the swap fails to reach the
/// Pending state in time. The TimedOut state indicates the lockup tx should never be broadcast.
timedOut,
/// ## Incoming Chain Swaps
///
/// This covers the case when the swap failed for any reason and there is a user lockup tx.
/// The swap in this case has to be manually refunded with a provided Bitcoin address
refundable,
;
}
@@ -455,6 +461,45 @@ class PreparePayOnchainResponse {
feesSat == other.feesSat;
}
class PrepareReceiveOnchainRequest {
final BigInt amountSat;
const PrepareReceiveOnchainRequest({
required this.amountSat,
});
@override
int get hashCode => amountSat.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is PrepareReceiveOnchainRequest &&
runtimeType == other.runtimeType &&
amountSat == other.amountSat;
}
class PrepareReceiveOnchainResponse {
final BigInt amountSat;
final BigInt feesSat;
const PrepareReceiveOnchainResponse({
required this.amountSat,
required this.feesSat,
});
@override
int get hashCode => amountSat.hashCode ^ feesSat.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is PrepareReceiveOnchainResponse &&
runtimeType == other.runtimeType &&
amountSat == other.amountSat &&
feesSat == other.feesSat;
}
class PrepareReceiveRequest {
final BigInt payerAmountSat;
@@ -494,6 +539,51 @@ class PrepareReceiveResponse {
feesSat == other.feesSat;
}
class PrepareRefundRequest {
final String swapAddress;
final String refundAddress;
final int satPerVbyte;
const PrepareRefundRequest({
required this.swapAddress,
required this.refundAddress,
required this.satPerVbyte,
});
@override
int get hashCode => swapAddress.hashCode ^ refundAddress.hashCode ^ satPerVbyte.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is PrepareRefundRequest &&
runtimeType == other.runtimeType &&
swapAddress == other.swapAddress &&
refundAddress == other.refundAddress &&
satPerVbyte == other.satPerVbyte;
}
class PrepareRefundResponse {
final int refundTxVsize;
final BigInt refundTxFeeSat;
const PrepareRefundResponse({
required this.refundTxVsize,
required this.refundTxFeeSat,
});
@override
int get hashCode => refundTxVsize.hashCode ^ refundTxFeeSat.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is PrepareRefundResponse &&
runtimeType == other.runtimeType &&
refundTxVsize == other.refundTxVsize &&
refundTxFeeSat == other.refundTxFeeSat;
}
class PrepareSendRequest {
final String invoice;
@@ -531,6 +621,43 @@ class PrepareSendResponse {
feesSat == other.feesSat;
}
class ReceiveOnchainRequest {
final PrepareReceiveOnchainResponse prepareRes;
const ReceiveOnchainRequest({
required this.prepareRes,
});
@override
int get hashCode => prepareRes.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is ReceiveOnchainRequest && runtimeType == other.runtimeType && prepareRes == other.prepareRes;
}
class ReceiveOnchainResponse {
final String address;
final String bip21;
const ReceiveOnchainResponse({
required this.address,
required this.bip21,
});
@override
int get hashCode => address.hashCode ^ bip21.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is ReceiveOnchainResponse &&
runtimeType == other.runtimeType &&
address == other.address &&
bip21 == other.bip21;
}
class ReceivePaymentResponse {
final String id;
final String invoice;
@@ -552,6 +679,70 @@ class ReceivePaymentResponse {
invoice == other.invoice;
}
class RefundRequest {
final String swapAddress;
final String refundAddress;
final int satPerVbyte;
const RefundRequest({
required this.swapAddress,
required this.refundAddress,
required this.satPerVbyte,
});
@override
int get hashCode => swapAddress.hashCode ^ refundAddress.hashCode ^ satPerVbyte.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is RefundRequest &&
runtimeType == other.runtimeType &&
swapAddress == other.swapAddress &&
refundAddress == other.refundAddress &&
satPerVbyte == other.satPerVbyte;
}
class RefundResponse {
final String refundTxId;
const RefundResponse({
required this.refundTxId,
});
@override
int get hashCode => refundTxId.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is RefundResponse && runtimeType == other.runtimeType && refundTxId == other.refundTxId;
}
class RefundableSwap {
final String swapAddress;
final int timestamp;
final BigInt amountSat;
const RefundableSwap({
required this.swapAddress,
required this.timestamp,
required this.amountSat,
});
@override
int get hashCode => swapAddress.hashCode ^ timestamp.hashCode ^ amountSat.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is RefundableSwap &&
runtimeType == other.runtimeType &&
swapAddress == other.swapAddress &&
timestamp == other.timestamp &&
amountSat == other.amountSat;
}
class RestoreRequest {
final String? backupPath;

View File

@@ -141,6 +141,23 @@ class FlutterBreezLiquidBindings {
_frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_list_paymentsPtr
.asFunction<void Function(int, int)>();
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_list_refundables(
int port_,
int that,
) {
return _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_list_refundables(
port_,
that,
);
}
late final _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_list_refundablesPtr =
_lookup<ffi.NativeFunction<ffi.Void Function(ffi.Int64, ffi.UintPtr)>>(
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_list_refundables');
late final _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_list_refundables =
_frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_list_refundablesPtr
.asFunction<void Function(int, int)>();
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_lnurl_auth(
int port_,
int that,
@@ -241,6 +258,28 @@ class FlutterBreezLiquidBindings {
_frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_pay_onchainPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_prepare_pay_onchain_request>)>();
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchain(
int port_,
int that,
ffi.Pointer<wire_cst_prepare_receive_onchain_request> req,
) {
return _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchain(
port_,
that,
req,
);
}
late final _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchainPtr =
_lookup<
ffi.NativeFunction<
ffi.Void Function(
ffi.Int64, ffi.UintPtr, ffi.Pointer<wire_cst_prepare_receive_onchain_request>)>>(
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchain');
late final _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchain =
_frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_receive_onchainPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_prepare_receive_onchain_request>)>();
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_receive_payment(
int port_,
int that,
@@ -262,6 +301,26 @@ class FlutterBreezLiquidBindings {
_frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_receive_paymentPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_prepare_receive_request>)>();
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_refund(
int port_,
int that,
ffi.Pointer<wire_cst_prepare_refund_request> req,
) {
return _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_refund(
port_,
that,
req,
);
}
late final _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_refundPtr = _lookup<
ffi.NativeFunction<
ffi.Void Function(ffi.Int64, ffi.UintPtr, ffi.Pointer<wire_cst_prepare_refund_request>)>>(
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_refund');
late final _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_refund =
_frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_refundPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_prepare_refund_request>)>();
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_send_payment(
int port_,
int that,
@@ -282,6 +341,26 @@ class FlutterBreezLiquidBindings {
_frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_prepare_send_paymentPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_prepare_send_request>)>();
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_receive_onchain(
int port_,
int that,
ffi.Pointer<wire_cst_receive_onchain_request> req,
) {
return _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_receive_onchain(
port_,
that,
req,
);
}
late final _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_receive_onchainPtr = _lookup<
ffi.NativeFunction<
ffi.Void Function(ffi.Int64, ffi.UintPtr, ffi.Pointer<wire_cst_receive_onchain_request>)>>(
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_receive_onchain');
late final _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_receive_onchain =
_frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_receive_onchainPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_receive_onchain_request>)>();
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_receive_payment(
int port_,
int that,
@@ -302,6 +381,26 @@ class FlutterBreezLiquidBindings {
_frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_receive_paymentPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_prepare_receive_response>)>();
void frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_refund(
int port_,
int that,
ffi.Pointer<wire_cst_refund_request> req,
) {
return _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_refund(
port_,
that,
req,
);
}
late final _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_refundPtr = _lookup<
ffi
.NativeFunction<ffi.Void Function(ffi.Int64, ffi.UintPtr, ffi.Pointer<wire_cst_refund_request>)>>(
'frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_refund');
late final _frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_refund =
_frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_refundPtr
.asFunction<void Function(int, int, ffi.Pointer<wire_cst_refund_request>)>();
WireSyncRust2DartDco frbgen_breez_liquid_wire__crate__bindings__BindingLiquidSdk_restore(
int that,
ffi.Pointer<wire_cst_restore_request> req,
@@ -735,6 +834,18 @@ class FlutterBreezLiquidBindings {
_frbgen_breez_liquid_cst_new_box_autoadd_prepare_pay_onchain_requestPtr
.asFunction<ffi.Pointer<wire_cst_prepare_pay_onchain_request> Function()>();
ffi.Pointer<wire_cst_prepare_receive_onchain_request>
frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_onchain_request() {
return _frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_onchain_request();
}
late final _frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_onchain_requestPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_prepare_receive_onchain_request> Function()>>(
'frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_onchain_request');
late final _frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_onchain_request =
_frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_onchain_requestPtr
.asFunction<ffi.Pointer<wire_cst_prepare_receive_onchain_request> Function()>();
ffi.Pointer<wire_cst_prepare_receive_request>
frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request() {
return _frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request();
@@ -759,6 +870,18 @@ class FlutterBreezLiquidBindings {
_frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_responsePtr
.asFunction<ffi.Pointer<wire_cst_prepare_receive_response> Function()>();
ffi.Pointer<wire_cst_prepare_refund_request>
frbgen_breez_liquid_cst_new_box_autoadd_prepare_refund_request() {
return _frbgen_breez_liquid_cst_new_box_autoadd_prepare_refund_request();
}
late final _frbgen_breez_liquid_cst_new_box_autoadd_prepare_refund_requestPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_prepare_refund_request> Function()>>(
'frbgen_breez_liquid_cst_new_box_autoadd_prepare_refund_request');
late final _frbgen_breez_liquid_cst_new_box_autoadd_prepare_refund_request =
_frbgen_breez_liquid_cst_new_box_autoadd_prepare_refund_requestPtr
.asFunction<ffi.Pointer<wire_cst_prepare_refund_request> Function()>();
ffi.Pointer<wire_cst_prepare_send_request> frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_request() {
return _frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_request();
}
@@ -782,6 +905,29 @@ class FlutterBreezLiquidBindings {
_frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_responsePtr
.asFunction<ffi.Pointer<wire_cst_prepare_send_response> Function()>();
ffi.Pointer<wire_cst_receive_onchain_request>
frbgen_breez_liquid_cst_new_box_autoadd_receive_onchain_request() {
return _frbgen_breez_liquid_cst_new_box_autoadd_receive_onchain_request();
}
late final _frbgen_breez_liquid_cst_new_box_autoadd_receive_onchain_requestPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_receive_onchain_request> Function()>>(
'frbgen_breez_liquid_cst_new_box_autoadd_receive_onchain_request');
late final _frbgen_breez_liquid_cst_new_box_autoadd_receive_onchain_request =
_frbgen_breez_liquid_cst_new_box_autoadd_receive_onchain_requestPtr
.asFunction<ffi.Pointer<wire_cst_receive_onchain_request> Function()>();
ffi.Pointer<wire_cst_refund_request> frbgen_breez_liquid_cst_new_box_autoadd_refund_request() {
return _frbgen_breez_liquid_cst_new_box_autoadd_refund_request();
}
late final _frbgen_breez_liquid_cst_new_box_autoadd_refund_requestPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_refund_request> Function()>>(
'frbgen_breez_liquid_cst_new_box_autoadd_refund_request');
late final _frbgen_breez_liquid_cst_new_box_autoadd_refund_request =
_frbgen_breez_liquid_cst_new_box_autoadd_refund_requestPtr
.asFunction<ffi.Pointer<wire_cst_refund_request> Function()>();
ffi.Pointer<wire_cst_restore_request> frbgen_breez_liquid_cst_new_box_autoadd_restore_request() {
return _frbgen_breez_liquid_cst_new_box_autoadd_restore_request();
}
@@ -860,6 +1006,21 @@ class FlutterBreezLiquidBindings {
_frbgen_breez_liquid_cst_new_list_prim_u_8_strictPtr
.asFunction<ffi.Pointer<wire_cst_list_prim_u_8_strict> Function(int)>();
ffi.Pointer<wire_cst_list_refundable_swap> frbgen_breez_liquid_cst_new_list_refundable_swap(
int len,
) {
return _frbgen_breez_liquid_cst_new_list_refundable_swap(
len,
);
}
late final _frbgen_breez_liquid_cst_new_list_refundable_swapPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_list_refundable_swap> Function(ffi.Int32)>>(
'frbgen_breez_liquid_cst_new_list_refundable_swap');
late final _frbgen_breez_liquid_cst_new_list_refundable_swap =
_frbgen_breez_liquid_cst_new_list_refundable_swapPtr
.asFunction<ffi.Pointer<wire_cst_list_refundable_swap> Function(int)>();
ffi.Pointer<wire_cst_list_route_hint> frbgen_breez_liquid_cst_new_list_route_hint(
int len,
) {
@@ -1015,15 +1176,41 @@ final class wire_cst_prepare_pay_onchain_request extends ffi.Struct {
external int amount_sat;
}
final class wire_cst_prepare_receive_onchain_request extends ffi.Struct {
@ffi.Uint64()
external int amount_sat;
}
final class wire_cst_prepare_receive_request extends ffi.Struct {
@ffi.Uint64()
external int payer_amount_sat;
}
final class wire_cst_prepare_refund_request extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> swap_address;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> refund_address;
@ffi.Uint32()
external int sat_per_vbyte;
}
final class wire_cst_prepare_send_request extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> invoice;
}
final class wire_cst_prepare_receive_onchain_response extends ffi.Struct {
@ffi.Uint64()
external int amount_sat;
@ffi.Uint64()
external int fees_sat;
}
final class wire_cst_receive_onchain_request extends ffi.Struct {
external wire_cst_prepare_receive_onchain_response prepare_res;
}
final class wire_cst_prepare_receive_response extends ffi.Struct {
@ffi.Uint64()
external int payer_amount_sat;
@@ -1032,6 +1219,15 @@ final class wire_cst_prepare_receive_response extends ffi.Struct {
external int fees_sat;
}
final class wire_cst_refund_request extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> swap_address;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> refund_address;
@ffi.Uint32()
external int sat_per_vbyte;
}
final class wire_cst_restore_request extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> backup_path;
}
@@ -1320,6 +1516,23 @@ final class wire_cst_list_payment extends ffi.Struct {
external int len;
}
final class wire_cst_refundable_swap extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> swap_address;
@ffi.Uint32()
external int timestamp;
@ffi.Uint64()
external int amount_sat;
}
final class wire_cst_list_refundable_swap extends ffi.Struct {
external ffi.Pointer<wire_cst_refundable_swap> ptr;
@ffi.Int32()
external int len;
}
final class wire_cst_get_info_response extends ffi.Struct {
@ffi.Uint64()
external int balance_sat;
@@ -1680,12 +1893,30 @@ final class wire_cst_payment_error extends ffi.Struct {
external PaymentErrorKind kind;
}
final class wire_cst_prepare_refund_response extends ffi.Struct {
@ffi.Uint32()
external int refund_tx_vsize;
@ffi.Uint64()
external int refund_tx_fee_sat;
}
final class wire_cst_receive_onchain_response extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> address;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> bip21;
}
final class wire_cst_receive_payment_response extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> id;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> invoice;
}
final class wire_cst_refund_response extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> refund_tx_id;
}
final class wire_cst_send_payment_response extends ffi.Struct {
external wire_cst_payment payment;
}
@@ -1693,6 +1924,8 @@ final class wire_cst_send_payment_response extends ffi.Struct {
/// EXTRA BEGIN
typedef WireSyncRust2DartDco = ffi.Pointer<DartCObject>;
const double LOWBALL_FEE_RATE_SAT_PER_VBYTE = 0.01;
const double DEFAULT_ZERO_CONF_MIN_FEE_RATE_TESTNET = 0.1;
const double DEFAULT_ZERO_CONF_MIN_FEE_RATE_MAINNET = 0.01;

View File

@@ -949,6 +949,74 @@ fun asPreparePayOnchainResponseList(arr: ReadableArray): List<PreparePayOnchainR
return list
}
fun asPrepareReceiveOnchainRequest(prepareReceiveOnchainRequest: ReadableMap): PrepareReceiveOnchainRequest? {
if (!validateMandatoryFields(
prepareReceiveOnchainRequest,
arrayOf(
"amountSat",
),
)
) {
return null
}
val amountSat = prepareReceiveOnchainRequest.getDouble("amountSat").toULong()
return PrepareReceiveOnchainRequest(
amountSat,
)
}
fun readableMapOf(prepareReceiveOnchainRequest: PrepareReceiveOnchainRequest): ReadableMap =
readableMapOf(
"amountSat" to prepareReceiveOnchainRequest.amountSat,
)
fun asPrepareReceiveOnchainRequestList(arr: ReadableArray): List<PrepareReceiveOnchainRequest> {
val list = ArrayList<PrepareReceiveOnchainRequest>()
for (value in arr.toArrayList()) {
when (value) {
is ReadableMap -> list.add(asPrepareReceiveOnchainRequest(value)!!)
else -> throw LiquidSdkException.Generic(errUnexpectedType("${value::class.java.name}"))
}
}
return list
}
fun asPrepareReceiveOnchainResponse(prepareReceiveOnchainResponse: ReadableMap): PrepareReceiveOnchainResponse? {
if (!validateMandatoryFields(
prepareReceiveOnchainResponse,
arrayOf(
"amountSat",
"feesSat",
),
)
) {
return null
}
val amountSat = prepareReceiveOnchainResponse.getDouble("amountSat").toULong()
val feesSat = prepareReceiveOnchainResponse.getDouble("feesSat").toULong()
return PrepareReceiveOnchainResponse(
amountSat,
feesSat,
)
}
fun readableMapOf(prepareReceiveOnchainResponse: PrepareReceiveOnchainResponse): ReadableMap =
readableMapOf(
"amountSat" to prepareReceiveOnchainResponse.amountSat,
"feesSat" to prepareReceiveOnchainResponse.feesSat,
)
fun asPrepareReceiveOnchainResponseList(arr: ReadableArray): List<PrepareReceiveOnchainResponse> {
val list = ArrayList<PrepareReceiveOnchainResponse>()
for (value in arr.toArrayList()) {
when (value) {
is ReadableMap -> list.add(asPrepareReceiveOnchainResponse(value)!!)
else -> throw LiquidSdkException.Generic(errUnexpectedType("${value::class.java.name}"))
}
}
return list
}
fun asPrepareReceiveRequest(prepareReceiveRequest: ReadableMap): PrepareReceiveRequest? {
if (!validateMandatoryFields(
prepareReceiveRequest,
@@ -1017,6 +1085,82 @@ fun asPrepareReceiveResponseList(arr: ReadableArray): List<PrepareReceiveRespons
return list
}
fun asPrepareRefundRequest(prepareRefundRequest: ReadableMap): PrepareRefundRequest? {
if (!validateMandatoryFields(
prepareRefundRequest,
arrayOf(
"swapAddress",
"refundAddress",
"satPerVbyte",
),
)
) {
return null
}
val swapAddress = prepareRefundRequest.getString("swapAddress")!!
val refundAddress = prepareRefundRequest.getString("refundAddress")!!
val satPerVbyte = prepareRefundRequest.getInt("satPerVbyte").toUInt()
return PrepareRefundRequest(
swapAddress,
refundAddress,
satPerVbyte,
)
}
fun readableMapOf(prepareRefundRequest: PrepareRefundRequest): ReadableMap =
readableMapOf(
"swapAddress" to prepareRefundRequest.swapAddress,
"refundAddress" to prepareRefundRequest.refundAddress,
"satPerVbyte" to prepareRefundRequest.satPerVbyte,
)
fun asPrepareRefundRequestList(arr: ReadableArray): List<PrepareRefundRequest> {
val list = ArrayList<PrepareRefundRequest>()
for (value in arr.toArrayList()) {
when (value) {
is ReadableMap -> list.add(asPrepareRefundRequest(value)!!)
else -> throw LiquidSdkException.Generic(errUnexpectedType("${value::class.java.name}"))
}
}
return list
}
fun asPrepareRefundResponse(prepareRefundResponse: ReadableMap): PrepareRefundResponse? {
if (!validateMandatoryFields(
prepareRefundResponse,
arrayOf(
"refundTxVsize",
"refundTxFeeSat",
),
)
) {
return null
}
val refundTxVsize = prepareRefundResponse.getInt("refundTxVsize").toUInt()
val refundTxFeeSat = prepareRefundResponse.getDouble("refundTxFeeSat").toULong()
return PrepareRefundResponse(
refundTxVsize,
refundTxFeeSat,
)
}
fun readableMapOf(prepareRefundResponse: PrepareRefundResponse): ReadableMap =
readableMapOf(
"refundTxVsize" to prepareRefundResponse.refundTxVsize,
"refundTxFeeSat" to prepareRefundResponse.refundTxFeeSat,
)
fun asPrepareRefundResponseList(arr: ReadableArray): List<PrepareRefundResponse> {
val list = ArrayList<PrepareRefundResponse>()
for (value in arr.toArrayList()) {
when (value) {
is ReadableMap -> list.add(asPrepareRefundResponse(value)!!)
else -> throw LiquidSdkException.Generic(errUnexpectedType("${value::class.java.name}"))
}
}
return list
}
fun asPrepareSendRequest(prepareSendRequest: ReadableMap): PrepareSendRequest? {
if (!validateMandatoryFields(
prepareSendRequest,
@@ -1085,6 +1229,74 @@ fun asPrepareSendResponseList(arr: ReadableArray): List<PrepareSendResponse> {
return list
}
fun asReceiveOnchainRequest(receiveOnchainRequest: ReadableMap): ReceiveOnchainRequest? {
if (!validateMandatoryFields(
receiveOnchainRequest,
arrayOf(
"prepareRes",
),
)
) {
return null
}
val prepareRes = receiveOnchainRequest.getMap("prepareRes")?.let { asPrepareReceiveOnchainResponse(it) }!!
return ReceiveOnchainRequest(
prepareRes,
)
}
fun readableMapOf(receiveOnchainRequest: ReceiveOnchainRequest): ReadableMap =
readableMapOf(
"prepareRes" to readableMapOf(receiveOnchainRequest.prepareRes),
)
fun asReceiveOnchainRequestList(arr: ReadableArray): List<ReceiveOnchainRequest> {
val list = ArrayList<ReceiveOnchainRequest>()
for (value in arr.toArrayList()) {
when (value) {
is ReadableMap -> list.add(asReceiveOnchainRequest(value)!!)
else -> throw LiquidSdkException.Generic(errUnexpectedType("${value::class.java.name}"))
}
}
return list
}
fun asReceiveOnchainResponse(receiveOnchainResponse: ReadableMap): ReceiveOnchainResponse? {
if (!validateMandatoryFields(
receiveOnchainResponse,
arrayOf(
"address",
"bip21",
),
)
) {
return null
}
val address = receiveOnchainResponse.getString("address")!!
val bip21 = receiveOnchainResponse.getString("bip21")!!
return ReceiveOnchainResponse(
address,
bip21,
)
}
fun readableMapOf(receiveOnchainResponse: ReceiveOnchainResponse): ReadableMap =
readableMapOf(
"address" to receiveOnchainResponse.address,
"bip21" to receiveOnchainResponse.bip21,
)
fun asReceiveOnchainResponseList(arr: ReadableArray): List<ReceiveOnchainResponse> {
val list = ArrayList<ReceiveOnchainResponse>()
for (value in arr.toArrayList()) {
when (value) {
is ReadableMap -> list.add(asReceiveOnchainResponse(value)!!)
else -> throw LiquidSdkException.Generic(errUnexpectedType("${value::class.java.name}"))
}
}
return list
}
fun asReceivePaymentResponse(receivePaymentResponse: ReadableMap): ReceivePaymentResponse? {
if (!validateMandatoryFields(
receivePaymentResponse,
@@ -1121,6 +1333,118 @@ fun asReceivePaymentResponseList(arr: ReadableArray): List<ReceivePaymentRespons
return list
}
fun asRefundRequest(refundRequest: ReadableMap): RefundRequest? {
if (!validateMandatoryFields(
refundRequest,
arrayOf(
"swapAddress",
"refundAddress",
"satPerVbyte",
),
)
) {
return null
}
val swapAddress = refundRequest.getString("swapAddress")!!
val refundAddress = refundRequest.getString("refundAddress")!!
val satPerVbyte = refundRequest.getInt("satPerVbyte").toUInt()
return RefundRequest(
swapAddress,
refundAddress,
satPerVbyte,
)
}
fun readableMapOf(refundRequest: RefundRequest): ReadableMap =
readableMapOf(
"swapAddress" to refundRequest.swapAddress,
"refundAddress" to refundRequest.refundAddress,
"satPerVbyte" to refundRequest.satPerVbyte,
)
fun asRefundRequestList(arr: ReadableArray): List<RefundRequest> {
val list = ArrayList<RefundRequest>()
for (value in arr.toArrayList()) {
when (value) {
is ReadableMap -> list.add(asRefundRequest(value)!!)
else -> throw LiquidSdkException.Generic(errUnexpectedType("${value::class.java.name}"))
}
}
return list
}
fun asRefundResponse(refundResponse: ReadableMap): RefundResponse? {
if (!validateMandatoryFields(
refundResponse,
arrayOf(
"refundTxId",
),
)
) {
return null
}
val refundTxId = refundResponse.getString("refundTxId")!!
return RefundResponse(
refundTxId,
)
}
fun readableMapOf(refundResponse: RefundResponse): ReadableMap =
readableMapOf(
"refundTxId" to refundResponse.refundTxId,
)
fun asRefundResponseList(arr: ReadableArray): List<RefundResponse> {
val list = ArrayList<RefundResponse>()
for (value in arr.toArrayList()) {
when (value) {
is ReadableMap -> list.add(asRefundResponse(value)!!)
else -> throw LiquidSdkException.Generic(errUnexpectedType("${value::class.java.name}"))
}
}
return list
}
fun asRefundableSwap(refundableSwap: ReadableMap): RefundableSwap? {
if (!validateMandatoryFields(
refundableSwap,
arrayOf(
"swapAddress",
"timestamp",
"amountSat",
),
)
) {
return null
}
val swapAddress = refundableSwap.getString("swapAddress")!!
val timestamp = refundableSwap.getInt("timestamp").toUInt()
val amountSat = refundableSwap.getDouble("amountSat").toULong()
return RefundableSwap(
swapAddress,
timestamp,
amountSat,
)
}
fun readableMapOf(refundableSwap: RefundableSwap): ReadableMap =
readableMapOf(
"swapAddress" to refundableSwap.swapAddress,
"timestamp" to refundableSwap.timestamp,
"amountSat" to refundableSwap.amountSat,
)
fun asRefundableSwapList(arr: ReadableArray): List<RefundableSwap> {
val list = ArrayList<RefundableSwap>()
for (value in arr.toArrayList()) {
when (value) {
is ReadableMap -> list.add(asRefundableSwap(value)!!)
else -> throw LiquidSdkException.Generic(errUnexpectedType("${value::class.java.name}"))
}
}
return list
}
fun asRestoreRequest(restoreRequest: ReadableMap): RestoreRequest? {
if (!validateMandatoryFields(
restoreRequest,
@@ -1745,6 +2069,7 @@ fun pushToArray(
when (value) {
null -> array.pushNull()
is Payment -> array.pushMap(readableMapOf(value))
is RefundableSwap -> array.pushMap(readableMapOf(value))
is RouteHint -> array.pushMap(readableMapOf(value))
is RouteHintHop -> array.pushMap(readableMapOf(value))
is UByte -> array.pushInt(value.toInt())

View File

@@ -294,6 +294,42 @@ class BreezLiquidSDKModule(
}
}
@ReactMethod
fun prepareReceiveOnchain(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val prepareReceiveOnchainRequest =
asPrepareReceiveOnchainRequest(req)
?: run { throw LiquidSdkException.Generic(errMissingMandatoryField("req", "PrepareReceiveOnchainRequest")) }
val res = getBindingLiquidSdk().prepareReceiveOnchain(prepareReceiveOnchainRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun receiveOnchain(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val receiveOnchainRequest =
asReceiveOnchainRequest(req)
?: run { throw LiquidSdkException.Generic(errMissingMandatoryField("req", "ReceiveOnchainRequest")) }
val res = getBindingLiquidSdk().receiveOnchain(receiveOnchainRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun listPayments(promise: Promise) {
executor.execute {
@@ -306,6 +342,53 @@ class BreezLiquidSDKModule(
}
}
@ReactMethod
fun listRefundables(promise: Promise) {
executor.execute {
try {
val res = getBindingLiquidSdk().listRefundables()
promise.resolve(readableArrayOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun prepareRefund(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val prepareRefundRequest =
asPrepareRefundRequest(req)
?: run { throw LiquidSdkException.Generic(errMissingMandatoryField("req", "PrepareRefundRequest")) }
val res = getBindingLiquidSdk().prepareRefund(prepareRefundRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun refund(
req: ReadableMap,
promise: Promise,
) {
executor.execute {
try {
val refundRequest =
asRefundRequest(req) ?: run { throw LiquidSdkException.Generic(errMissingMandatoryField("req", "RefundRequest")) }
val res = getBindingLiquidSdk().refund(refundRequest)
promise.resolve(readableMapOf(res))
} catch (e: Exception) {
promise.reject(e.javaClass.simpleName.replace("Exception", "Error"), e.message, e)
}
}
}
@ReactMethod
fun sync(promise: Promise) {
executor.execute {

View File

@@ -1135,6 +1135,76 @@ enum BreezLiquidSDKMapper {
return preparePayOnchainResponseList.map { v -> [String: Any?] in dictionaryOf(preparePayOnchainResponse: v) }
}
static func asPrepareReceiveOnchainRequest(prepareReceiveOnchainRequest: [String: Any?]) throws -> PrepareReceiveOnchainRequest {
guard let amountSat = prepareReceiveOnchainRequest["amountSat"] as? UInt64 else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "amountSat", typeName: "PrepareReceiveOnchainRequest"))
}
return PrepareReceiveOnchainRequest(
amountSat: amountSat)
}
static func dictionaryOf(prepareReceiveOnchainRequest: PrepareReceiveOnchainRequest) -> [String: Any?] {
return [
"amountSat": prepareReceiveOnchainRequest.amountSat,
]
}
static func asPrepareReceiveOnchainRequestList(arr: [Any]) throws -> [PrepareReceiveOnchainRequest] {
var list = [PrepareReceiveOnchainRequest]()
for value in arr {
if let val = value as? [String: Any?] {
var prepareReceiveOnchainRequest = try asPrepareReceiveOnchainRequest(prepareReceiveOnchainRequest: val)
list.append(prepareReceiveOnchainRequest)
} else {
throw LiquidSdkError.Generic(message: errUnexpectedType(typeName: "PrepareReceiveOnchainRequest"))
}
}
return list
}
static func arrayOf(prepareReceiveOnchainRequestList: [PrepareReceiveOnchainRequest]) -> [Any] {
return prepareReceiveOnchainRequestList.map { v -> [String: Any?] in dictionaryOf(prepareReceiveOnchainRequest: v) }
}
static func asPrepareReceiveOnchainResponse(prepareReceiveOnchainResponse: [String: Any?]) throws -> PrepareReceiveOnchainResponse {
guard let amountSat = prepareReceiveOnchainResponse["amountSat"] as? UInt64 else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "amountSat", typeName: "PrepareReceiveOnchainResponse"))
}
guard let feesSat = prepareReceiveOnchainResponse["feesSat"] as? UInt64 else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "feesSat", typeName: "PrepareReceiveOnchainResponse"))
}
return PrepareReceiveOnchainResponse(
amountSat: amountSat,
feesSat: feesSat
)
}
static func dictionaryOf(prepareReceiveOnchainResponse: PrepareReceiveOnchainResponse) -> [String: Any?] {
return [
"amountSat": prepareReceiveOnchainResponse.amountSat,
"feesSat": prepareReceiveOnchainResponse.feesSat,
]
}
static func asPrepareReceiveOnchainResponseList(arr: [Any]) throws -> [PrepareReceiveOnchainResponse] {
var list = [PrepareReceiveOnchainResponse]()
for value in arr {
if let val = value as? [String: Any?] {
var prepareReceiveOnchainResponse = try asPrepareReceiveOnchainResponse(prepareReceiveOnchainResponse: val)
list.append(prepareReceiveOnchainResponse)
} else {
throw LiquidSdkError.Generic(message: errUnexpectedType(typeName: "PrepareReceiveOnchainResponse"))
}
}
return list
}
static func arrayOf(prepareReceiveOnchainResponseList: [PrepareReceiveOnchainResponse]) -> [Any] {
return prepareReceiveOnchainResponseList.map { v -> [String: Any?] in dictionaryOf(prepareReceiveOnchainResponse: v) }
}
static func asPrepareReceiveRequest(prepareReceiveRequest: [String: Any?]) throws -> PrepareReceiveRequest {
guard let payerAmountSat = prepareReceiveRequest["payerAmountSat"] as? UInt64 else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "payerAmountSat", typeName: "PrepareReceiveRequest"))
@@ -1205,6 +1275,87 @@ enum BreezLiquidSDKMapper {
return prepareReceiveResponseList.map { v -> [String: Any?] in dictionaryOf(prepareReceiveResponse: v) }
}
static func asPrepareRefundRequest(prepareRefundRequest: [String: Any?]) throws -> PrepareRefundRequest {
guard let swapAddress = prepareRefundRequest["swapAddress"] as? String else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "swapAddress", typeName: "PrepareRefundRequest"))
}
guard let refundAddress = prepareRefundRequest["refundAddress"] as? String else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "refundAddress", typeName: "PrepareRefundRequest"))
}
guard let satPerVbyte = prepareRefundRequest["satPerVbyte"] as? UInt32 else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "satPerVbyte", typeName: "PrepareRefundRequest"))
}
return PrepareRefundRequest(
swapAddress: swapAddress,
refundAddress: refundAddress,
satPerVbyte: satPerVbyte
)
}
static func dictionaryOf(prepareRefundRequest: PrepareRefundRequest) -> [String: Any?] {
return [
"swapAddress": prepareRefundRequest.swapAddress,
"refundAddress": prepareRefundRequest.refundAddress,
"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 LiquidSdkError.Generic(message: errUnexpectedType(typeName: "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 refundTxVsize = prepareRefundResponse["refundTxVsize"] as? UInt32 else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "refundTxVsize", typeName: "PrepareRefundResponse"))
}
guard let refundTxFeeSat = prepareRefundResponse["refundTxFeeSat"] as? UInt64 else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "refundTxFeeSat", typeName: "PrepareRefundResponse"))
}
return PrepareRefundResponse(
refundTxVsize: refundTxVsize,
refundTxFeeSat: refundTxFeeSat
)
}
static func dictionaryOf(prepareRefundResponse: PrepareRefundResponse) -> [String: Any?] {
return [
"refundTxVsize": prepareRefundResponse.refundTxVsize,
"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 LiquidSdkError.Generic(message: errUnexpectedType(typeName: "PrepareRefundResponse"))
}
}
return list
}
static func arrayOf(prepareRefundResponseList: [PrepareRefundResponse]) -> [Any] {
return prepareRefundResponseList.map { v -> [String: Any?] in dictionaryOf(prepareRefundResponse: v) }
}
static func asPrepareSendRequest(prepareSendRequest: [String: Any?]) throws -> PrepareSendRequest {
guard let invoice = prepareSendRequest["invoice"] as? String else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "invoice", typeName: "PrepareSendRequest"))
@@ -1275,6 +1426,77 @@ enum BreezLiquidSDKMapper {
return prepareSendResponseList.map { v -> [String: Any?] in dictionaryOf(prepareSendResponse: v) }
}
static func asReceiveOnchainRequest(receiveOnchainRequest: [String: Any?]) throws -> ReceiveOnchainRequest {
guard let prepareResTmp = receiveOnchainRequest["prepareRes"] as? [String: Any?] else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "prepareRes", typeName: "ReceiveOnchainRequest"))
}
let prepareRes = try asPrepareReceiveOnchainResponse(prepareReceiveOnchainResponse: prepareResTmp)
return ReceiveOnchainRequest(
prepareRes: prepareRes)
}
static func dictionaryOf(receiveOnchainRequest: ReceiveOnchainRequest) -> [String: Any?] {
return [
"prepareRes": dictionaryOf(prepareReceiveOnchainResponse: receiveOnchainRequest.prepareRes),
]
}
static func asReceiveOnchainRequestList(arr: [Any]) throws -> [ReceiveOnchainRequest] {
var list = [ReceiveOnchainRequest]()
for value in arr {
if let val = value as? [String: Any?] {
var receiveOnchainRequest = try asReceiveOnchainRequest(receiveOnchainRequest: val)
list.append(receiveOnchainRequest)
} else {
throw LiquidSdkError.Generic(message: errUnexpectedType(typeName: "ReceiveOnchainRequest"))
}
}
return list
}
static func arrayOf(receiveOnchainRequestList: [ReceiveOnchainRequest]) -> [Any] {
return receiveOnchainRequestList.map { v -> [String: Any?] in dictionaryOf(receiveOnchainRequest: v) }
}
static func asReceiveOnchainResponse(receiveOnchainResponse: [String: Any?]) throws -> ReceiveOnchainResponse {
guard let address = receiveOnchainResponse["address"] as? String else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "address", typeName: "ReceiveOnchainResponse"))
}
guard let bip21 = receiveOnchainResponse["bip21"] as? String else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "bip21", typeName: "ReceiveOnchainResponse"))
}
return ReceiveOnchainResponse(
address: address,
bip21: bip21
)
}
static func dictionaryOf(receiveOnchainResponse: ReceiveOnchainResponse) -> [String: Any?] {
return [
"address": receiveOnchainResponse.address,
"bip21": receiveOnchainResponse.bip21,
]
}
static func asReceiveOnchainResponseList(arr: [Any]) throws -> [ReceiveOnchainResponse] {
var list = [ReceiveOnchainResponse]()
for value in arr {
if let val = value as? [String: Any?] {
var receiveOnchainResponse = try asReceiveOnchainResponse(receiveOnchainResponse: val)
list.append(receiveOnchainResponse)
} else {
throw LiquidSdkError.Generic(message: errUnexpectedType(typeName: "ReceiveOnchainResponse"))
}
}
return list
}
static func arrayOf(receiveOnchainResponseList: [ReceiveOnchainResponse]) -> [Any] {
return receiveOnchainResponseList.map { v -> [String: Any?] in dictionaryOf(receiveOnchainResponse: v) }
}
static func asReceivePaymentResponse(receivePaymentResponse: [String: Any?]) throws -> ReceivePaymentResponse {
guard let id = receivePaymentResponse["id"] as? String else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "id", typeName: "ReceivePaymentResponse"))
@@ -1313,6 +1535,124 @@ enum BreezLiquidSDKMapper {
return receivePaymentResponseList.map { v -> [String: Any?] in dictionaryOf(receivePaymentResponse: v) }
}
static func asRefundRequest(refundRequest: [String: Any?]) throws -> RefundRequest {
guard let swapAddress = refundRequest["swapAddress"] as? String else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "swapAddress", typeName: "RefundRequest"))
}
guard let refundAddress = refundRequest["refundAddress"] as? String else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "refundAddress", typeName: "RefundRequest"))
}
guard let satPerVbyte = refundRequest["satPerVbyte"] as? UInt32 else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "satPerVbyte", typeName: "RefundRequest"))
}
return RefundRequest(
swapAddress: swapAddress,
refundAddress: refundAddress,
satPerVbyte: satPerVbyte
)
}
static func dictionaryOf(refundRequest: RefundRequest) -> [String: Any?] {
return [
"swapAddress": refundRequest.swapAddress,
"refundAddress": refundRequest.refundAddress,
"satPerVbyte": refundRequest.satPerVbyte,
]
}
static func asRefundRequestList(arr: [Any]) throws -> [RefundRequest] {
var list = [RefundRequest]()
for value in arr {
if let val = value as? [String: Any?] {
var refundRequest = try asRefundRequest(refundRequest: val)
list.append(refundRequest)
} else {
throw LiquidSdkError.Generic(message: errUnexpectedType(typeName: "RefundRequest"))
}
}
return list
}
static func arrayOf(refundRequestList: [RefundRequest]) -> [Any] {
return refundRequestList.map { v -> [String: Any?] in dictionaryOf(refundRequest: v) }
}
static func asRefundResponse(refundResponse: [String: Any?]) throws -> RefundResponse {
guard let refundTxId = refundResponse["refundTxId"] as? String else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "refundTxId", typeName: "RefundResponse"))
}
return RefundResponse(
refundTxId: refundTxId)
}
static func dictionaryOf(refundResponse: RefundResponse) -> [String: Any?] {
return [
"refundTxId": refundResponse.refundTxId,
]
}
static func asRefundResponseList(arr: [Any]) throws -> [RefundResponse] {
var list = [RefundResponse]()
for value in arr {
if let val = value as? [String: Any?] {
var refundResponse = try asRefundResponse(refundResponse: val)
list.append(refundResponse)
} else {
throw LiquidSdkError.Generic(message: errUnexpectedType(typeName: "RefundResponse"))
}
}
return list
}
static func arrayOf(refundResponseList: [RefundResponse]) -> [Any] {
return refundResponseList.map { v -> [String: Any?] in dictionaryOf(refundResponse: v) }
}
static func asRefundableSwap(refundableSwap: [String: Any?]) throws -> RefundableSwap {
guard let swapAddress = refundableSwap["swapAddress"] as? String else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "swapAddress", typeName: "RefundableSwap"))
}
guard let timestamp = refundableSwap["timestamp"] as? UInt32 else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "timestamp", typeName: "RefundableSwap"))
}
guard let amountSat = refundableSwap["amountSat"] as? UInt64 else {
throw LiquidSdkError.Generic(message: errMissingMandatoryField(fieldName: "amountSat", typeName: "RefundableSwap"))
}
return RefundableSwap(
swapAddress: swapAddress,
timestamp: timestamp,
amountSat: amountSat
)
}
static func dictionaryOf(refundableSwap: RefundableSwap) -> [String: Any?] {
return [
"swapAddress": refundableSwap.swapAddress,
"timestamp": refundableSwap.timestamp,
"amountSat": refundableSwap.amountSat,
]
}
static func asRefundableSwapList(arr: [Any]) throws -> [RefundableSwap] {
var list = [RefundableSwap]()
for value in arr {
if let val = value as? [String: Any?] {
var refundableSwap = try asRefundableSwap(refundableSwap: val)
list.append(refundableSwap)
} else {
throw LiquidSdkError.Generic(message: errUnexpectedType(typeName: "RefundableSwap"))
}
}
return list
}
static func arrayOf(refundableSwapList: [RefundableSwap]) -> [Any] {
return refundableSwapList.map { v -> [String: Any?] in dictionaryOf(refundableSwap: v) }
}
static func asRestoreRequest(restoreRequest: [String: Any?]) throws -> RestoreRequest {
var backupPath: String?
if hasNonNilKey(data: restoreRequest, key: "backupPath") {
@@ -2155,6 +2495,9 @@ enum BreezLiquidSDKMapper {
case "timedOut":
return PaymentState.timedOut
case "refundable":
return PaymentState.refundable
default: throw LiquidSdkError.Generic(message: "Invalid variant \(paymentState) for enum PaymentState")
}
}
@@ -2175,6 +2518,9 @@ enum BreezLiquidSDKMapper {
case .timedOut:
return "timedOut"
case .refundable:
return "refundable"
}
}

View File

@@ -84,11 +84,40 @@ RCT_EXTERN_METHOD(
reject: (RCTPromiseRejectBlock)reject
)
RCT_EXTERN_METHOD(
prepareReceiveOnchain: (NSDictionary*)req
resolve: (RCTPromiseResolveBlock)resolve
reject: (RCTPromiseRejectBlock)reject
)
RCT_EXTERN_METHOD(
receiveOnchain: (NSDictionary*)req
resolve: (RCTPromiseResolveBlock)resolve
reject: (RCTPromiseRejectBlock)reject
)
RCT_EXTERN_METHOD(
listPayments: (RCTPromiseResolveBlock)resolve
reject: (RCTPromiseRejectBlock)reject
)
RCT_EXTERN_METHOD(
listRefundables: (RCTPromiseResolveBlock)resolve
reject: (RCTPromiseRejectBlock)reject
)
RCT_EXTERN_METHOD(
prepareRefund: (NSDictionary*)req
resolve: (RCTPromiseResolveBlock)resolve
reject: (RCTPromiseRejectBlock)reject
)
RCT_EXTERN_METHOD(
refund: (NSDictionary*)req
resolve: (RCTPromiseResolveBlock)resolve
reject: (RCTPromiseRejectBlock)reject
)
RCT_EXTERN_METHOD(
sync: (RCTPromiseResolveBlock)resolve
reject: (RCTPromiseRejectBlock)reject

View File

@@ -230,6 +230,28 @@ class RNBreezLiquidSDK: RCTEventEmitter {
}
}
@objc(prepareReceiveOnchain:resolve:reject:)
func prepareReceiveOnchain(_ req: [String: Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
do {
let prepareReceiveOnchainRequest = try BreezLiquidSDKMapper.asPrepareReceiveOnchainRequest(prepareReceiveOnchainRequest: req)
var res = try getBindingLiquidSdk().prepareReceiveOnchain(req: prepareReceiveOnchainRequest)
resolve(BreezLiquidSDKMapper.dictionaryOf(prepareReceiveOnchainResponse: res))
} catch let err {
rejectErr(err: err, reject: reject)
}
}
@objc(receiveOnchain:resolve:reject:)
func receiveOnchain(_ req: [String: Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
do {
let receiveOnchainRequest = try BreezLiquidSDKMapper.asReceiveOnchainRequest(receiveOnchainRequest: req)
var res = try getBindingLiquidSdk().receiveOnchain(req: receiveOnchainRequest)
resolve(BreezLiquidSDKMapper.dictionaryOf(receiveOnchainResponse: res))
} catch let err {
rejectErr(err: err, reject: reject)
}
}
@objc(listPayments:reject:)
func listPayments(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
do {
@@ -240,6 +262,38 @@ class RNBreezLiquidSDK: RCTEventEmitter {
}
}
@objc(listRefundables:reject:)
func listRefundables(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
do {
var res = try getBindingLiquidSdk().listRefundables()
resolve(BreezLiquidSDKMapper.arrayOf(refundableSwapList: res))
} catch let err {
rejectErr(err: err, reject: reject)
}
}
@objc(prepareRefund:resolve:reject:)
func prepareRefund(_ req: [String: Any], resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
do {
let prepareRefundRequest = try BreezLiquidSDKMapper.asPrepareRefundRequest(prepareRefundRequest: req)
var res = try getBindingLiquidSdk().prepareRefund(req: prepareRefundRequest)
resolve(BreezLiquidSDKMapper.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 {
let refundRequest = try BreezLiquidSDKMapper.asRefundRequest(refundRequest: req)
var res = try getBindingLiquidSdk().refund(req: refundRequest)
resolve(BreezLiquidSDKMapper.dictionaryOf(refundResponse: res))
} catch let err {
rejectErr(err: err, reject: reject)
}
}
@objc(sync:reject:)
func sync(_ resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) {
do {

View File

@@ -169,6 +169,15 @@ export interface PreparePayOnchainResponse {
feesSat: number
}
export interface PrepareReceiveOnchainRequest {
amountSat: number
}
export interface PrepareReceiveOnchainResponse {
amountSat: number
feesSat: number
}
export interface PrepareReceiveRequest {
payerAmountSat: number
}
@@ -178,6 +187,17 @@ export interface PrepareReceiveResponse {
feesSat: number
}
export interface PrepareRefundRequest {
swapAddress: string
refundAddress: string
satPerVbyte: number
}
export interface PrepareRefundResponse {
refundTxVsize: number
refundTxFeeSat: number
}
export interface PrepareSendRequest {
invoice: string
}
@@ -187,11 +207,36 @@ export interface PrepareSendResponse {
feesSat: number
}
export interface ReceiveOnchainRequest {
prepareRes: PrepareReceiveOnchainResponse
}
export interface ReceiveOnchainResponse {
address: string
bip21: string
}
export interface ReceivePaymentResponse {
id: string
invoice: string
}
export interface RefundRequest {
swapAddress: string
refundAddress: string
satPerVbyte: number
}
export interface RefundResponse {
refundTxId: string
}
export interface RefundableSwap {
swapAddress: string
timestamp: number
amountSat: number
}
export interface RestoreRequest {
backupPath?: string
}
@@ -360,7 +405,8 @@ export enum PaymentState {
PENDING = "pending",
COMPLETE = "complete",
FAILED = "failed",
TIMED_OUT = "timedOut"
TIMED_OUT = "timedOut",
REFUNDABLE = "refundable"
}
export enum PaymentType {
@@ -466,11 +512,36 @@ export const payOnchain = async (req: PayOnchainRequest): Promise<SendPaymentRes
return response
}
export const prepareReceiveOnchain = async (req: PrepareReceiveOnchainRequest): Promise<PrepareReceiveOnchainResponse> => {
const response = await BreezLiquidSDK.prepareReceiveOnchain(req)
return response
}
export const receiveOnchain = async (req: ReceiveOnchainRequest): Promise<ReceiveOnchainResponse> => {
const response = await BreezLiquidSDK.receiveOnchain(req)
return response
}
export const listPayments = async (): Promise<Payment[]> => {
const response = await BreezLiquidSDK.listPayments()
return response
}
export const listRefundables = async (): Promise<RefundableSwap[]> => {
const response = await BreezLiquidSDK.listRefundables()
return response
}
export const prepareRefund = async (req: PrepareRefundRequest): Promise<PrepareRefundResponse> => {
const response = await BreezLiquidSDK.prepareRefund(req)
return response
}
export const refund = async (req: RefundRequest): Promise<RefundResponse> => {
const response = await BreezLiquidSDK.refund(req)
return response
}
export const sync = async (): Promise<void> => {
await BreezLiquidSDK.sync()
}