mirror of
https://github.com/aljazceru/breez-sdk-liquid.git
synced 2025-12-24 01:14:22 +01:00
Add zero-amount Receive Chain Swap (#538)
Add support for Zero-Amount Receive Chain Swaps
This commit is contained in:
4
cli/Cargo.lock
generated
4
cli/Cargo.lock
generated
@@ -1,6 +1,6 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
@@ -609,7 +609,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "boltz-client"
|
name = "boltz-client"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
source = "git+https://github.com/SatoshiPortal/boltz-rust?branch=trunk#19e01071f5722c21f80ae9b34edef5c3972e9e0b"
|
source = "git+https://github.com/SatoshiPortal/boltz-rust?branch=trunk#68ff15b0f80abfa54d8dca4c11c8c2794e4b6921"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bip39",
|
"bip39",
|
||||||
"bitcoin 0.31.2",
|
"bitcoin 0.31.2",
|
||||||
|
|||||||
@@ -271,13 +271,21 @@ pub(crate) async fn handle_command(
|
|||||||
})
|
})
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
wait_confirmation!(
|
let fees = prepare_response.fees_sat;
|
||||||
format!(
|
let confirmation_msg = match payer_amount_sat {
|
||||||
"Fees: {} sat. Are the fees acceptable? (y/N) ",
|
Some(_) => format!("Fees: {fees} sat. Are the fees acceptable? (y/N)"),
|
||||||
prepare_response.fees_sat
|
None => {
|
||||||
),
|
let min = prepare_response.min_payer_amount_sat;
|
||||||
"Payment receive halted"
|
let max = prepare_response.max_payer_amount_sat;
|
||||||
);
|
let service_feerate = prepare_response.service_feerate;
|
||||||
|
format!(
|
||||||
|
"Fees: {fees} sat + {service_feerate:?}% of the sent amount. \
|
||||||
|
Sender should send between {min:?} sat and {max:?} sat. \
|
||||||
|
Are the fees acceptable? (y/N)"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
wait_confirmation!(confirmation_msg, "Payment receive halted");
|
||||||
|
|
||||||
let response = sdk
|
let response = sdk
|
||||||
.receive_payment(&ReceivePaymentRequest {
|
.receive_payment(&ReceivePaymentRequest {
|
||||||
|
|||||||
4
lib/Cargo.lock
generated
4
lib/Cargo.lock
generated
@@ -1,6 +1,6 @@
|
|||||||
# This file is automatically @generated by Cargo.
|
# This file is automatically @generated by Cargo.
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
version = 3
|
version = 4
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
@@ -723,7 +723,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "boltz-client"
|
name = "boltz-client"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
source = "git+https://github.com/SatoshiPortal/boltz-rust?branch=trunk#19e01071f5722c21f80ae9b34edef5c3972e9e0b"
|
source = "git+https://github.com/SatoshiPortal/boltz-rust?branch=trunk#68ff15b0f80abfa54d8dca4c11c8c2794e4b6921"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bip39",
|
"bip39",
|
||||||
"bitcoin 0.31.2",
|
"bitcoin 0.31.2",
|
||||||
|
|||||||
@@ -367,6 +367,9 @@ typedef struct wire_cst_prepare_receive_response {
|
|||||||
int32_t payment_method;
|
int32_t payment_method;
|
||||||
uint64_t *payer_amount_sat;
|
uint64_t *payer_amount_sat;
|
||||||
uint64_t fees_sat;
|
uint64_t fees_sat;
|
||||||
|
uint64_t *min_payer_amount_sat;
|
||||||
|
uint64_t *max_payer_amount_sat;
|
||||||
|
double *swapper_feerate;
|
||||||
} wire_cst_prepare_receive_response;
|
} wire_cst_prepare_receive_response;
|
||||||
|
|
||||||
typedef struct wire_cst_receive_payment_request {
|
typedef struct wire_cst_receive_payment_request {
|
||||||
@@ -1194,6 +1197,8 @@ struct wire_cst_check_message_request *frbgen_breez_liquid_cst_new_box_autoadd_c
|
|||||||
|
|
||||||
struct wire_cst_connect_request *frbgen_breez_liquid_cst_new_box_autoadd_connect_request(void);
|
struct wire_cst_connect_request *frbgen_breez_liquid_cst_new_box_autoadd_connect_request(void);
|
||||||
|
|
||||||
|
double *frbgen_breez_liquid_cst_new_box_autoadd_f_64(double value);
|
||||||
|
|
||||||
struct wire_cst_get_payment_request *frbgen_breez_liquid_cst_new_box_autoadd_get_payment_request(void);
|
struct wire_cst_get_payment_request *frbgen_breez_liquid_cst_new_box_autoadd_get_payment_request(void);
|
||||||
|
|
||||||
int64_t *frbgen_breez_liquid_cst_new_box_autoadd_i_64(int64_t value);
|
int64_t *frbgen_breez_liquid_cst_new_box_autoadd_i_64(int64_t value);
|
||||||
@@ -1306,6 +1311,7 @@ static int64_t dummy_method_to_enforce_bundling(void) {
|
|||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_buy_bitcoin_request);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_buy_bitcoin_request);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_check_message_request);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_check_message_request);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_connect_request);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_connect_request);
|
||||||
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_f_64);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_get_payment_request);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_get_payment_request);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_i_64);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_i_64);
|
||||||
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_liquid_address_data);
|
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_liquid_address_data);
|
||||||
|
|||||||
@@ -431,9 +431,12 @@ dictionary PrepareReceiveRequest {
|
|||||||
};
|
};
|
||||||
|
|
||||||
dictionary PrepareReceiveResponse {
|
dictionary PrepareReceiveResponse {
|
||||||
u64? payer_amount_sat;
|
|
||||||
PaymentMethod payment_method;
|
PaymentMethod payment_method;
|
||||||
u64 fees_sat;
|
u64 fees_sat;
|
||||||
|
u64? payer_amount_sat;
|
||||||
|
u64? min_payer_amount_sat;
|
||||||
|
u64? max_payer_amount_sat;
|
||||||
|
f64? swapper_feerate;
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary ReceivePaymentRequest {
|
dictionary ReceivePaymentRequest {
|
||||||
|
|||||||
@@ -436,6 +436,20 @@ impl ChainSwapHandler {
|
|||||||
| ChainSwapStates::TransactionLockupFailed
|
| ChainSwapStates::TransactionLockupFailed
|
||||||
| ChainSwapStates::TransactionRefunded
|
| ChainSwapStates::TransactionRefunded
|
||||||
| ChainSwapStates::SwapExpired => {
|
| ChainSwapStates::SwapExpired => {
|
||||||
|
// Zero-amount Receive Chain Swaps also get to TransactionLockupFailed when user locks up funds
|
||||||
|
let is_zero_amount = swap.payer_amount_sat == 0;
|
||||||
|
if matches!(swap_state, ChainSwapStates::TransactionLockupFailed) && is_zero_amount
|
||||||
|
{
|
||||||
|
match self.handle_amountless_update(swap).await {
|
||||||
|
Ok(_) => {
|
||||||
|
// We successfully accepted the quote, the swap should continue as normal
|
||||||
|
return Ok(()); // Break from TxLockupFailed branch
|
||||||
|
}
|
||||||
|
// In case of error, we continue and mark it as refundable
|
||||||
|
Err(e) => error!("Failed to accept the quote for swap {}: {e:?}", &swap.id),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match swap.refund_tx_id.clone() {
|
match swap.refund_tx_id.clone() {
|
||||||
None => {
|
None => {
|
||||||
warn!("Chain Swap {id} is in an unrecoverable state: {swap_state:?}");
|
warn!("Chain Swap {id} is in an unrecoverable state: {swap_state:?}");
|
||||||
@@ -453,7 +467,7 @@ impl ChainSwapHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some(refund_tx_id) => warn!(
|
Some(refund_tx_id) => warn!(
|
||||||
"Refund tx for Chain Swap {id} was already broadcast: txid {refund_tx_id}"
|
"Refund for Chain Swap {id} was already broadcast: txid {refund_tx_id}"
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -466,6 +480,82 @@ impl ChainSwapHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn handle_amountless_update(&self, swap: &ChainSwap) -> Result<(), PaymentError> {
|
||||||
|
let quote = self
|
||||||
|
.swapper
|
||||||
|
.get_zero_amount_chain_swap_quote(&swap.id)
|
||||||
|
.map(|quote| quote.to_sat())?;
|
||||||
|
info!("Got quote of {quote} sat for swap {}", &swap.id);
|
||||||
|
|
||||||
|
self.validate_and_update_amountless_swap(swap, quote)
|
||||||
|
.await?;
|
||||||
|
self.swapper
|
||||||
|
.accept_zero_amount_chain_swap_quote(&swap.id, quote)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn validate_and_update_amountless_swap(
|
||||||
|
&self,
|
||||||
|
swap: &ChainSwap,
|
||||||
|
quote_server_lockup_amount_sat: u64,
|
||||||
|
) -> Result<(), PaymentError> {
|
||||||
|
debug!("Validating {swap:?}");
|
||||||
|
|
||||||
|
ensure_sdk!(
|
||||||
|
matches!(swap.direction, Direction::Incoming),
|
||||||
|
PaymentError::generic(&format!(
|
||||||
|
"Only an incoming chain swap can be a zero-amount swap. Swap ID: {}",
|
||||||
|
&swap.id
|
||||||
|
))
|
||||||
|
);
|
||||||
|
|
||||||
|
let script_pubkey = swap.get_receive_lockup_swap_script_pubkey(self.config.network)?;
|
||||||
|
let script_balance = self
|
||||||
|
.bitcoin_chain_service
|
||||||
|
.lock()
|
||||||
|
.await
|
||||||
|
.script_get_balance(script_pubkey.as_script())?;
|
||||||
|
debug!("Found lockup balance {script_balance:?}");
|
||||||
|
let user_lockup_amount_sat = match script_balance.confirmed > 0 {
|
||||||
|
true => script_balance.confirmed,
|
||||||
|
false => match script_balance.unconfirmed > 0 {
|
||||||
|
true => script_balance.unconfirmed.unsigned_abs(),
|
||||||
|
false => 0,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
ensure_sdk!(
|
||||||
|
user_lockup_amount_sat > 0,
|
||||||
|
PaymentError::generic("Lockup address has no confirmed or unconfirmed balance")
|
||||||
|
);
|
||||||
|
|
||||||
|
let pair = swap.get_boltz_pair()?;
|
||||||
|
let swapper_service_feerate = pair.fees.percentage;
|
||||||
|
let swapper_server_fees_sat = pair.fees.server();
|
||||||
|
let service_fees_sat =
|
||||||
|
((swapper_service_feerate / 100.0) * user_lockup_amount_sat as f64).ceil() as u64;
|
||||||
|
let fees_sat = swapper_server_fees_sat + service_fees_sat;
|
||||||
|
ensure_sdk!(
|
||||||
|
user_lockup_amount_sat > fees_sat,
|
||||||
|
PaymentError::generic(&format!("Invalid quote: fees ({fees_sat} sat) are higher than user lockup ({user_lockup_amount_sat} sat)"))
|
||||||
|
);
|
||||||
|
|
||||||
|
let expected_server_lockup_amount_sat = user_lockup_amount_sat - fees_sat;
|
||||||
|
debug!("user_lockup_amount_sat = {}, service_fees_sat = {}, server_fees_sat = {}, expected_server_lockup_amount_sat = {}, quote_server_lockup_amount_sat = {}",
|
||||||
|
user_lockup_amount_sat, service_fees_sat, swapper_server_fees_sat, expected_server_lockup_amount_sat, quote_server_lockup_amount_sat);
|
||||||
|
ensure_sdk!(
|
||||||
|
expected_server_lockup_amount_sat <= quote_server_lockup_amount_sat,
|
||||||
|
PaymentError::generic(&format!("Invalid quote: expected at least {expected_server_lockup_amount_sat} sat, got {quote_server_lockup_amount_sat} sat"))
|
||||||
|
);
|
||||||
|
|
||||||
|
let receiver_amount_sat = quote_server_lockup_amount_sat - swap.claim_fees_sat;
|
||||||
|
self.persister.update_zero_amount_swap_values(
|
||||||
|
&swap.id,
|
||||||
|
user_lockup_amount_sat,
|
||||||
|
receiver_amount_sat,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
async fn on_new_outgoing_status(&self, swap: &ChainSwap, update: &boltz::Update) -> Result<()> {
|
async fn on_new_outgoing_status(&self, swap: &ChainSwap, update: &boltz::Update) -> Result<()> {
|
||||||
let id = &update.id;
|
let id = &update.id;
|
||||||
let status = &update.status;
|
let status = &update.status;
|
||||||
|
|||||||
@@ -3291,6 +3291,17 @@ impl SseDecode for Option<bool> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SseDecode for Option<f64> {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||||
|
if (<bool>::sse_decode(deserializer)) {
|
||||||
|
return Some(<f64>::sse_decode(deserializer));
|
||||||
|
} else {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SseDecode for Option<i64> {
|
impl SseDecode for Option<i64> {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
|
||||||
@@ -3747,10 +3758,16 @@ impl SseDecode for crate::model::PrepareReceiveResponse {
|
|||||||
let mut var_paymentMethod = <crate::model::PaymentMethod>::sse_decode(deserializer);
|
let mut var_paymentMethod = <crate::model::PaymentMethod>::sse_decode(deserializer);
|
||||||
let mut var_payerAmountSat = <Option<u64>>::sse_decode(deserializer);
|
let mut var_payerAmountSat = <Option<u64>>::sse_decode(deserializer);
|
||||||
let mut var_feesSat = <u64>::sse_decode(deserializer);
|
let mut var_feesSat = <u64>::sse_decode(deserializer);
|
||||||
|
let mut var_minPayerAmountSat = <Option<u64>>::sse_decode(deserializer);
|
||||||
|
let mut var_maxPayerAmountSat = <Option<u64>>::sse_decode(deserializer);
|
||||||
|
let mut var_swapperFeerate = <Option<f64>>::sse_decode(deserializer);
|
||||||
return crate::model::PrepareReceiveResponse {
|
return crate::model::PrepareReceiveResponse {
|
||||||
payment_method: var_paymentMethod,
|
payment_method: var_paymentMethod,
|
||||||
payer_amount_sat: var_payerAmountSat,
|
payer_amount_sat: var_payerAmountSat,
|
||||||
fees_sat: var_feesSat,
|
fees_sat: var_feesSat,
|
||||||
|
min_payer_amount_sat: var_minPayerAmountSat,
|
||||||
|
max_payer_amount_sat: var_maxPayerAmountSat,
|
||||||
|
swapper_feerate: var_swapperFeerate,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5807,6 +5824,9 @@ impl flutter_rust_bridge::IntoDart for crate::model::PrepareReceiveResponse {
|
|||||||
self.payment_method.into_into_dart().into_dart(),
|
self.payment_method.into_into_dart().into_dart(),
|
||||||
self.payer_amount_sat.into_into_dart().into_dart(),
|
self.payer_amount_sat.into_into_dart().into_dart(),
|
||||||
self.fees_sat.into_into_dart().into_dart(),
|
self.fees_sat.into_into_dart().into_dart(),
|
||||||
|
self.min_payer_amount_sat.into_into_dart().into_dart(),
|
||||||
|
self.max_payer_amount_sat.into_into_dart().into_dart(),
|
||||||
|
self.swapper_feerate.into_into_dart().into_dart(),
|
||||||
]
|
]
|
||||||
.into_dart()
|
.into_dart()
|
||||||
}
|
}
|
||||||
@@ -7282,6 +7302,16 @@ impl SseEncode for Option<bool> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl SseEncode for Option<f64> {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||||
|
<bool>::sse_encode(self.is_some(), serializer);
|
||||||
|
if let Some(value) = self {
|
||||||
|
<f64>::sse_encode(value, serializer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl SseEncode for Option<i64> {
|
impl SseEncode for Option<i64> {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||||
@@ -7680,6 +7710,9 @@ impl SseEncode for crate::model::PrepareReceiveResponse {
|
|||||||
<crate::model::PaymentMethod>::sse_encode(self.payment_method, serializer);
|
<crate::model::PaymentMethod>::sse_encode(self.payment_method, serializer);
|
||||||
<Option<u64>>::sse_encode(self.payer_amount_sat, serializer);
|
<Option<u64>>::sse_encode(self.payer_amount_sat, serializer);
|
||||||
<u64>::sse_encode(self.fees_sat, serializer);
|
<u64>::sse_encode(self.fees_sat, serializer);
|
||||||
|
<Option<u64>>::sse_encode(self.min_payer_amount_sat, serializer);
|
||||||
|
<Option<u64>>::sse_encode(self.max_payer_amount_sat, serializer);
|
||||||
|
<Option<f64>>::sse_encode(self.swapper_feerate, serializer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8290,6 +8323,12 @@ mod io {
|
|||||||
CstDecode::<crate::model::ConnectRequest>::cst_decode(*wrap).into()
|
CstDecode::<crate::model::ConnectRequest>::cst_decode(*wrap).into()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
impl CstDecode<f64> for *mut f64 {
|
||||||
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
|
fn cst_decode(self) -> f64 {
|
||||||
|
unsafe { *flutter_rust_bridge::for_generated::box_from_leak_ptr(self) }
|
||||||
|
}
|
||||||
|
}
|
||||||
impl CstDecode<crate::model::GetPaymentRequest> for *mut wire_cst_get_payment_request {
|
impl CstDecode<crate::model::GetPaymentRequest> for *mut wire_cst_get_payment_request {
|
||||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
fn cst_decode(self) -> crate::model::GetPaymentRequest {
|
fn cst_decode(self) -> crate::model::GetPaymentRequest {
|
||||||
@@ -9554,6 +9593,9 @@ mod io {
|
|||||||
payment_method: self.payment_method.cst_decode(),
|
payment_method: self.payment_method.cst_decode(),
|
||||||
payer_amount_sat: self.payer_amount_sat.cst_decode(),
|
payer_amount_sat: self.payer_amount_sat.cst_decode(),
|
||||||
fees_sat: self.fees_sat.cst_decode(),
|
fees_sat: self.fees_sat.cst_decode(),
|
||||||
|
min_payer_amount_sat: self.min_payer_amount_sat.cst_decode(),
|
||||||
|
max_payer_amount_sat: self.max_payer_amount_sat.cst_decode(),
|
||||||
|
swapper_feerate: self.swapper_feerate.cst_decode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10702,6 +10744,9 @@ mod io {
|
|||||||
payment_method: Default::default(),
|
payment_method: Default::default(),
|
||||||
payer_amount_sat: core::ptr::null_mut(),
|
payer_amount_sat: core::ptr::null_mut(),
|
||||||
fees_sat: Default::default(),
|
fees_sat: Default::default(),
|
||||||
|
min_payer_amount_sat: core::ptr::null_mut(),
|
||||||
|
max_payer_amount_sat: core::ptr::null_mut(),
|
||||||
|
swapper_feerate: core::ptr::null_mut(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11481,6 +11526,11 @@ mod io {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_f_64(value: f64) -> *mut f64 {
|
||||||
|
flutter_rust_bridge::for_generated::new_leak_box_ptr(value)
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_get_payment_request(
|
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_get_payment_request(
|
||||||
) -> *mut wire_cst_get_payment_request {
|
) -> *mut wire_cst_get_payment_request {
|
||||||
@@ -12840,6 +12890,9 @@ mod io {
|
|||||||
payment_method: i32,
|
payment_method: i32,
|
||||||
payer_amount_sat: *mut u64,
|
payer_amount_sat: *mut u64,
|
||||||
fees_sat: u64,
|
fees_sat: u64,
|
||||||
|
min_payer_amount_sat: *mut u64,
|
||||||
|
max_payer_amount_sat: *mut u64,
|
||||||
|
swapper_feerate: *mut f64,
|
||||||
}
|
}
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use std::path::PathBuf;
|
|||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
|
||||||
|
use boltz_client::boltz::ChainPair;
|
||||||
use boltz_client::{
|
use boltz_client::{
|
||||||
bitcoin::ScriptBuf,
|
bitcoin::ScriptBuf,
|
||||||
network::Chain,
|
network::Chain,
|
||||||
@@ -302,7 +303,31 @@ pub struct PrepareReceiveRequest {
|
|||||||
pub struct PrepareReceiveResponse {
|
pub struct PrepareReceiveResponse {
|
||||||
pub payment_method: PaymentMethod,
|
pub payment_method: PaymentMethod,
|
||||||
pub payer_amount_sat: Option<u64>,
|
pub payer_amount_sat: Option<u64>,
|
||||||
|
|
||||||
|
/// Generally represents the total fees that would be paid to send or receive this payment.
|
||||||
|
///
|
||||||
|
/// In case of Zero-Amount Receive Chain swaps, the swapper service fee (`swapper_feerate` times
|
||||||
|
/// the amount) is paid in addition to `fees_sat`. The swapper service feerate is already known
|
||||||
|
/// in the beginning, but the exact swapper service fee will only be known when the
|
||||||
|
/// `payer_amount_sat` is known.
|
||||||
|
///
|
||||||
|
/// In all other types of swaps, the swapper service fee is included in `fees_sat`.
|
||||||
pub fees_sat: u64,
|
pub fees_sat: u64,
|
||||||
|
|
||||||
|
/// The minimum amount the payer can send for this swap to succeed.
|
||||||
|
///
|
||||||
|
/// When the method is [PaymentMethod::LiquidAddress], this is empty.
|
||||||
|
pub min_payer_amount_sat: Option<u64>,
|
||||||
|
|
||||||
|
/// The maximum amount the payer can send for this swap to succeed.
|
||||||
|
///
|
||||||
|
/// When the method is [PaymentMethod::LiquidAddress], this is empty.
|
||||||
|
pub max_payer_amount_sat: Option<u64>,
|
||||||
|
|
||||||
|
/// The percentage of the sent amount that will count towards the service fee.
|
||||||
|
///
|
||||||
|
/// When the method is [PaymentMethod::LiquidAddress], this is empty.
|
||||||
|
pub swapper_feerate: Option<f64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An argument when calling [crate::sdk::LiquidSdk::receive_payment].
|
/// An argument when calling [crate::sdk::LiquidSdk::receive_payment].
|
||||||
@@ -671,6 +696,13 @@ impl ChainSwap {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) fn get_boltz_pair(&self) -> Result<ChainPair> {
|
||||||
|
let pair: ChainPair = serde_json::from_str(&self.pair_fees_json)
|
||||||
|
.map_err(|e| anyhow!("Failed to deserialize ChainPair: {e:?}"))?;
|
||||||
|
|
||||||
|
Ok(pair)
|
||||||
|
}
|
||||||
|
|
||||||
pub(crate) fn get_claim_swap_script(&self) -> SdkResult<SwapScriptV2> {
|
pub(crate) fn get_claim_swap_script(&self) -> SdkResult<SwapScriptV2> {
|
||||||
let chain_swap_details = self.get_boltz_create_response()?.claim_details;
|
let chain_swap_details = self.get_boltz_create_response()?.claim_details;
|
||||||
let our_pubkey = self.get_claim_keypair()?.public_key();
|
let our_pubkey = self.get_claim_keypair()?.public_key();
|
||||||
|
|||||||
@@ -267,6 +267,32 @@ impl Persister {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Used for Zero-amount Receive Chain swaps, when we fetched the quote and we know how much
|
||||||
|
/// the sender locked up
|
||||||
|
pub(crate) fn update_zero_amount_swap_values(
|
||||||
|
&self,
|
||||||
|
swap_id: &str,
|
||||||
|
payer_amount_sat: u64,
|
||||||
|
receiver_amount_sat: u64,
|
||||||
|
) -> Result<(), PaymentError> {
|
||||||
|
log::info!("Updating chain swap {swap_id}: payer_amount_sat = {payer_amount_sat}, receiver_amount_sat = {receiver_amount_sat}");
|
||||||
|
let con: Connection = self.get_connection()?;
|
||||||
|
con.execute(
|
||||||
|
"UPDATE chain_swaps
|
||||||
|
SET
|
||||||
|
payer_amount_sat = :payer_amount_sat,
|
||||||
|
receiver_amount_sat = :receiver_amount_sat
|
||||||
|
WHERE
|
||||||
|
id = :id",
|
||||||
|
named_params! {
|
||||||
|
":id": swap_id,
|
||||||
|
":payer_amount_sat": payer_amount_sat,
|
||||||
|
":receiver_amount_sat": receiver_amount_sat,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
// Only set the Chain Swap claim_tx_id if not set, otherwise return an error
|
// Only set the Chain Swap claim_tx_id if not set, otherwise return an error
|
||||||
pub(crate) fn set_chain_swap_claim_tx_id(
|
pub(crate) fn set_chain_swap_claim_tx_id(
|
||||||
&self,
|
&self,
|
||||||
|
|||||||
@@ -706,10 +706,12 @@ impl LiquidSdk {
|
|||||||
fn get_and_validate_chain_pair(
|
fn get_and_validate_chain_pair(
|
||||||
&self,
|
&self,
|
||||||
direction: Direction,
|
direction: Direction,
|
||||||
user_lockup_amount_sat: u64,
|
user_lockup_amount_sat: Option<u64>,
|
||||||
) -> Result<ChainPair, PaymentError> {
|
) -> Result<ChainPair, PaymentError> {
|
||||||
let pair = self.get_chain_pair(direction)?;
|
let pair = self.get_chain_pair(direction)?;
|
||||||
self.validate_user_lockup_amount_for_chain_pair(&pair, user_lockup_amount_sat)?;
|
if let Some(user_lockup_amount_sat) = user_lockup_amount_sat {
|
||||||
|
self.validate_user_lockup_amount_for_chain_pair(&pair, user_lockup_amount_sat)?;
|
||||||
|
}
|
||||||
Ok(pair)
|
Ok(pair)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1631,6 +1633,9 @@ impl LiquidSdk {
|
|||||||
) -> Result<PrepareReceiveResponse, PaymentError> {
|
) -> Result<PrepareReceiveResponse, PaymentError> {
|
||||||
self.ensure_is_started().await?;
|
self.ensure_is_started().await?;
|
||||||
|
|
||||||
|
let mut min_payer_amount_sat = None;
|
||||||
|
let mut max_payer_amount_sat = None;
|
||||||
|
let mut swapper_feerate = None;
|
||||||
let fees_sat;
|
let fees_sat;
|
||||||
match req.payment_method {
|
match req.payment_method {
|
||||||
PaymentMethod::Lightning => {
|
PaymentMethod::Lightning => {
|
||||||
@@ -1651,29 +1656,35 @@ impl LiquidSdk {
|
|||||||
.within(payer_amount_sat)
|
.within(payer_amount_sat)
|
||||||
.map_err(|_| PaymentError::AmountOutOfRange)?;
|
.map_err(|_| PaymentError::AmountOutOfRange)?;
|
||||||
|
|
||||||
|
min_payer_amount_sat = Some(reverse_pair.limits.minimal);
|
||||||
|
max_payer_amount_sat = Some(reverse_pair.limits.maximal);
|
||||||
|
swapper_feerate = Some(reverse_pair.fees.percentage);
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"Preparing Lightning Receive Swap with: payer_amount_sat {payer_amount_sat} sat, fees_sat {fees_sat} sat"
|
"Preparing Lightning Receive Swap with: payer_amount_sat {payer_amount_sat} sat, fees_sat {fees_sat} sat"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
PaymentMethod::BitcoinAddress => {
|
PaymentMethod::BitcoinAddress => {
|
||||||
let Some(payer_amount_sat) = req.payer_amount_sat else {
|
let payer_amount_sat = req.payer_amount_sat;
|
||||||
return Err(PaymentError::AmountMissing { err: "`payer_amount_sat` must be specified when `PaymentMethod::BitcoinAddress` is used.".to_string() });
|
|
||||||
};
|
|
||||||
let pair =
|
let pair =
|
||||||
self.get_and_validate_chain_pair(Direction::Incoming, payer_amount_sat)?;
|
self.get_and_validate_chain_pair(Direction::Incoming, payer_amount_sat)?;
|
||||||
let claim_fees_sat = pair.fees.claim_estimate();
|
let claim_fees_sat = pair.fees.claim_estimate();
|
||||||
let server_fees_sat = pair.fees.server();
|
let server_fees_sat = pair.fees.server();
|
||||||
fees_sat = pair.fees.boltz(payer_amount_sat) + claim_fees_sat + server_fees_sat;
|
let service_fees_sat = payer_amount_sat
|
||||||
debug!(
|
.map(|user_lockup_amount_sat| pair.fees.boltz(user_lockup_amount_sat))
|
||||||
"Preparing Chain Receive Swap with: payer_amount_sat {payer_amount_sat} sat, fees_sat {fees_sat} sat"
|
.unwrap_or_default();
|
||||||
);
|
|
||||||
|
min_payer_amount_sat = Some(pair.limits.minimal);
|
||||||
|
max_payer_amount_sat = Some(pair.limits.maximal);
|
||||||
|
swapper_feerate = Some(pair.fees.percentage);
|
||||||
|
|
||||||
|
fees_sat = service_fees_sat + claim_fees_sat + server_fees_sat;
|
||||||
|
debug!("Preparing Chain Receive Swap with: payer_amount_sat {payer_amount_sat:?}, fees_sat {fees_sat}");
|
||||||
}
|
}
|
||||||
PaymentMethod::LiquidAddress => {
|
PaymentMethod::LiquidAddress => {
|
||||||
fees_sat = 0;
|
fees_sat = 0;
|
||||||
debug!(
|
let payer_amount_sat = req.payer_amount_sat;
|
||||||
"Preparing Liquid Receive Swap with: amount_sat {:?} sat, fees_sat {fees_sat} sat",
|
debug!("Preparing Liquid Receive Swap with: amount_sat {payer_amount_sat:?}, fees_sat {fees_sat}");
|
||||||
req.payer_amount_sat
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1681,6 +1692,9 @@ impl LiquidSdk {
|
|||||||
payer_amount_sat: req.payer_amount_sat,
|
payer_amount_sat: req.payer_amount_sat,
|
||||||
fees_sat,
|
fees_sat,
|
||||||
payment_method: req.payment_method.clone(),
|
payment_method: req.payment_method.clone(),
|
||||||
|
min_payer_amount_sat,
|
||||||
|
max_payer_amount_sat,
|
||||||
|
swapper_feerate,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1708,6 +1722,7 @@ impl LiquidSdk {
|
|||||||
payment_method,
|
payment_method,
|
||||||
payer_amount_sat: amount_sat,
|
payer_amount_sat: amount_sat,
|
||||||
fees_sat,
|
fees_sat,
|
||||||
|
..
|
||||||
} = &req.prepare_response;
|
} = &req.prepare_response;
|
||||||
|
|
||||||
match payment_method {
|
match payment_method {
|
||||||
@@ -1733,12 +1748,7 @@ impl LiquidSdk {
|
|||||||
self.create_receive_swap(*amount_sat, *fees_sat, description, description_hash)
|
self.create_receive_swap(*amount_sat, *fees_sat, description, description_hash)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
PaymentMethod::BitcoinAddress => {
|
PaymentMethod::BitcoinAddress => self.receive_onchain(*amount_sat, *fees_sat).await,
|
||||||
let Some(amount_sat) = amount_sat else {
|
|
||||||
return Err(PaymentError::AmountMissing { err: "`amount_sat` must be specified when `PaymentMethod::BitcoinAddress` is used.".to_string() });
|
|
||||||
};
|
|
||||||
self.receive_onchain(*amount_sat, *fees_sat).await
|
|
||||||
}
|
|
||||||
PaymentMethod::LiquidAddress => {
|
PaymentMethod::LiquidAddress => {
|
||||||
let address = self.onchain_wallet.next_unused_address().await?.to_string();
|
let address = self.onchain_wallet.next_unused_address().await?.to_string();
|
||||||
|
|
||||||
@@ -1898,15 +1908,19 @@ impl LiquidSdk {
|
|||||||
|
|
||||||
async fn create_receive_chain_swap(
|
async fn create_receive_chain_swap(
|
||||||
&self,
|
&self,
|
||||||
user_lockup_amount_sat: u64,
|
user_lockup_amount_sat: Option<u64>,
|
||||||
fees_sat: u64,
|
fees_sat: u64,
|
||||||
) -> Result<ChainSwap, PaymentError> {
|
) -> Result<ChainSwap, PaymentError> {
|
||||||
let pair = self.get_and_validate_chain_pair(Direction::Incoming, user_lockup_amount_sat)?;
|
let pair = self.get_and_validate_chain_pair(Direction::Incoming, user_lockup_amount_sat)?;
|
||||||
let claim_fees_sat = pair.fees.claim_estimate();
|
let claim_fees_sat = pair.fees.claim_estimate();
|
||||||
let server_fees_sat = pair.fees.server();
|
let server_fees_sat = pair.fees.server();
|
||||||
|
// Service fees are 0 if this is a zero-amount swap
|
||||||
|
let service_fees_sat = user_lockup_amount_sat
|
||||||
|
.map(|user_lockup_amount_sat| pair.fees.boltz(user_lockup_amount_sat))
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
ensure_sdk!(
|
ensure_sdk!(
|
||||||
fees_sat == pair.fees.boltz(user_lockup_amount_sat) + claim_fees_sat + server_fees_sat,
|
fees_sat == service_fees_sat + claim_fees_sat + server_fees_sat,
|
||||||
PaymentError::InvalidOrExpiredFees
|
PaymentError::InvalidOrExpiredFees
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -1938,7 +1952,7 @@ impl LiquidSdk {
|
|||||||
preimage_hash: preimage.sha256,
|
preimage_hash: preimage.sha256,
|
||||||
claim_public_key: Some(claim_public_key),
|
claim_public_key: Some(claim_public_key),
|
||||||
refund_public_key: Some(refund_public_key),
|
refund_public_key: Some(refund_public_key),
|
||||||
user_lock_amount: Some(user_lockup_amount_sat),
|
user_lock_amount: user_lockup_amount_sat,
|
||||||
server_lock_amount: None,
|
server_lock_amount: None,
|
||||||
pair_hash: Some(pair.hash.clone()),
|
pair_hash: Some(pair.hash.clone()),
|
||||||
referral_id: None,
|
referral_id: None,
|
||||||
@@ -1949,8 +1963,12 @@ impl LiquidSdk {
|
|||||||
let create_response_json =
|
let create_response_json =
|
||||||
ChainSwap::from_boltz_struct_to_json(&create_response, &swap_id)?;
|
ChainSwap::from_boltz_struct_to_json(&create_response, &swap_id)?;
|
||||||
|
|
||||||
let accept_zero_conf = user_lockup_amount_sat <= pair.limits.maximal_zero_conf;
|
let accept_zero_conf = user_lockup_amount_sat
|
||||||
let receiver_amount_sat = user_lockup_amount_sat - fees_sat;
|
.map(|user_lockup_amount_sat| user_lockup_amount_sat <= pair.limits.maximal_zero_conf)
|
||||||
|
.unwrap_or(false);
|
||||||
|
let receiver_amount_sat = user_lockup_amount_sat
|
||||||
|
.map(|user_lockup_amount_sat| user_lockup_amount_sat - fees_sat)
|
||||||
|
.unwrap_or(0);
|
||||||
|
|
||||||
let swap = ChainSwap {
|
let swap = ChainSwap {
|
||||||
id: swap_id.clone(),
|
id: swap_id.clone(),
|
||||||
@@ -1960,7 +1978,7 @@ impl LiquidSdk {
|
|||||||
timeout_block_height: create_response.lockup_details.timeout_block_height,
|
timeout_block_height: create_response.lockup_details.timeout_block_height,
|
||||||
preimage: preimage_str,
|
preimage: preimage_str,
|
||||||
description: Some("Bitcoin transfer".to_string()),
|
description: Some("Bitcoin transfer".to_string()),
|
||||||
payer_amount_sat: user_lockup_amount_sat,
|
payer_amount_sat: user_lockup_amount_sat.unwrap_or(0),
|
||||||
receiver_amount_sat,
|
receiver_amount_sat,
|
||||||
claim_fees_sat,
|
claim_fees_sat,
|
||||||
pair_fees_json: serde_json::to_string(&pair).map_err(|e| {
|
pair_fees_json: serde_json::to_string(&pair).map_err(|e| {
|
||||||
@@ -1983,15 +2001,18 @@ impl LiquidSdk {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Receive from a Bitcoin transaction via a chain swap.
|
/// Receive from a Bitcoin transaction via a chain swap.
|
||||||
|
///
|
||||||
|
/// If no `user_lockup_amount_sat` is specified, this is an amountless swap and `fees_sat` exclude
|
||||||
|
/// the service fees.
|
||||||
async fn receive_onchain(
|
async fn receive_onchain(
|
||||||
&self,
|
&self,
|
||||||
payer_amount_sat: u64,
|
user_lockup_amount_sat: Option<u64>,
|
||||||
fees_sat: u64,
|
fees_sat: u64,
|
||||||
) -> Result<ReceivePaymentResponse, PaymentError> {
|
) -> Result<ReceivePaymentResponse, PaymentError> {
|
||||||
self.ensure_is_started().await?;
|
self.ensure_is_started().await?;
|
||||||
|
|
||||||
let swap = self
|
let swap = self
|
||||||
.create_receive_chain_swap(payer_amount_sat, fees_sat)
|
.create_receive_chain_swap(user_lockup_amount_sat, fees_sat)
|
||||||
.await?;
|
.await?;
|
||||||
let create_response = swap.get_boltz_create_response()?;
|
let create_response = swap.get_boltz_create_response()?;
|
||||||
let address = create_response.lockup_details.lockup_address;
|
let address = create_response.lockup_details.lockup_address;
|
||||||
@@ -2170,7 +2191,7 @@ impl LiquidSdk {
|
|||||||
|
|
||||||
let swap = self
|
let swap = self
|
||||||
.create_receive_chain_swap(
|
.create_receive_chain_swap(
|
||||||
req.prepare_response.amount_sat,
|
Some(req.prepare_response.amount_sat),
|
||||||
req.prepare_response.fees_sat,
|
req.prepare_response.fees_sat,
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use boltz_client::{
|
|||||||
elements::secp256k1_zkp::{MusigPartialSignature, MusigPubNonce},
|
elements::secp256k1_zkp::{MusigPartialSignature, MusigPubNonce},
|
||||||
network::{electrum::ElectrumConfig, Chain},
|
network::{electrum::ElectrumConfig, Chain},
|
||||||
util::secrets::Preimage,
|
util::secrets::Preimage,
|
||||||
|
Amount,
|
||||||
};
|
};
|
||||||
use log::info;
|
use log::info;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
@@ -179,6 +180,23 @@ impl Swapper for BoltzSwapper {
|
|||||||
Ok((pair_outgoing, pair_incoming))
|
Ok((pair_outgoing, pair_incoming))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_zero_amount_chain_swap_quote(&self, swap_id: &str) -> Result<Amount, PaymentError> {
|
||||||
|
self.client
|
||||||
|
.get_quote(swap_id)
|
||||||
|
.map(|r| Amount::from_sat(r.amount))
|
||||||
|
.map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn accept_zero_amount_chain_swap_quote(
|
||||||
|
&self,
|
||||||
|
swap_id: &str,
|
||||||
|
server_lockup_sat: u64,
|
||||||
|
) -> Result<(), PaymentError> {
|
||||||
|
self.client
|
||||||
|
.accept_quote(swap_id, server_lockup_sat)
|
||||||
|
.map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a submarine pair information
|
/// Get a submarine pair information
|
||||||
fn get_submarine_pairs(&self) -> Result<Option<SubmarinePair>, PaymentError> {
|
fn get_submarine_pairs(&self) -> Result<Option<SubmarinePair>, PaymentError> {
|
||||||
Ok(self.client.get_submarine_pairs()?.get_lbtc_to_btc_pair())
|
Ok(self.client.get_submarine_pairs()?.get_lbtc_to_btc_pair())
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use boltz_client::{
|
|||||||
SubmarineClaimTxResponse, SubmarinePair,
|
SubmarineClaimTxResponse, SubmarinePair,
|
||||||
},
|
},
|
||||||
network::Chain,
|
network::Chain,
|
||||||
|
Amount,
|
||||||
};
|
};
|
||||||
use tokio::sync::{broadcast, watch};
|
use tokio::sync::{broadcast, watch};
|
||||||
|
|
||||||
@@ -40,6 +41,19 @@ pub trait Swapper: Send + Sync {
|
|||||||
/// Get the current rate, limits and fees for both swap directions
|
/// Get the current rate, limits and fees for both swap directions
|
||||||
fn get_chain_pairs(&self) -> Result<(Option<ChainPair>, Option<ChainPair>), PaymentError>;
|
fn get_chain_pairs(&self) -> Result<(Option<ChainPair>, Option<ChainPair>), PaymentError>;
|
||||||
|
|
||||||
|
/// Get the quote for a Zero-Amount Receive Chain Swap.
|
||||||
|
///
|
||||||
|
/// If the user locked-up funds in the valid range this will return that amount. In all other
|
||||||
|
/// cases, this will return an error.
|
||||||
|
fn get_zero_amount_chain_swap_quote(&self, swap_id: &str) -> Result<Amount, PaymentError>;
|
||||||
|
|
||||||
|
/// Accept a specific quote for a Zero-Amount Receive Chain Swap
|
||||||
|
fn accept_zero_amount_chain_swap_quote(
|
||||||
|
&self,
|
||||||
|
swap_id: &str,
|
||||||
|
server_lockup_sat: u64,
|
||||||
|
) -> Result<(), PaymentError>;
|
||||||
|
|
||||||
/// Get a submarine pair information
|
/// Get a submarine pair information
|
||||||
fn get_submarine_pairs(&self) -> Result<Option<SubmarinePair>, PaymentError>;
|
fn get_submarine_pairs(&self) -> Result<Option<SubmarinePair>, PaymentError>;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use boltz_client::{
|
|||||||
SubmarinePair, SwapTree,
|
SubmarinePair, SwapTree,
|
||||||
},
|
},
|
||||||
util::secrets::Preimage,
|
util::secrets::Preimage,
|
||||||
PublicKey,
|
Amount, PublicKey,
|
||||||
};
|
};
|
||||||
use sdk_common::invoice::parse_invoice;
|
use sdk_common::invoice::parse_invoice;
|
||||||
|
|
||||||
@@ -313,4 +313,16 @@ impl Swapper for MockSwapper {
|
|||||||
fn get_bolt12_invoice(&self, _offer: &str, _amount_sat: u64) -> Result<String, PaymentError> {
|
fn get_bolt12_invoice(&self, _offer: &str, _amount_sat: u64) -> Result<String, PaymentError> {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_zero_amount_chain_swap_quote(&self, swap_id: &str) -> Result<Amount, PaymentError> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn accept_zero_amount_chain_swap_quote(
|
||||||
|
&self,
|
||||||
|
_swap_id: &str,
|
||||||
|
_server_lockup_sat: u64,
|
||||||
|
) -> Result<(), PaymentError> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1411,6 +1411,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return dco_decode_connect_request(raw);
|
return dco_decode_connect_request(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
double dco_decode_box_autoadd_f_64(dynamic raw) {
|
||||||
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
|
return raw as double;
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
GetPaymentRequest dco_decode_box_autoadd_get_payment_request(dynamic raw) {
|
GetPaymentRequest dco_decode_box_autoadd_get_payment_request(dynamic raw) {
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
@@ -2379,6 +2385,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return raw == null ? null : dco_decode_box_autoadd_bool(raw);
|
return raw == null ? null : dco_decode_box_autoadd_bool(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
double? dco_decode_opt_box_autoadd_f_64(dynamic raw) {
|
||||||
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
|
return raw == null ? null : dco_decode_box_autoadd_f_64(raw);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
PlatformInt64? dco_decode_opt_box_autoadd_i_64(dynamic raw) {
|
PlatformInt64? dco_decode_opt_box_autoadd_i_64(dynamic raw) {
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
@@ -2691,11 +2703,14 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
PrepareReceiveResponse dco_decode_prepare_receive_response(dynamic raw) {
|
PrepareReceiveResponse dco_decode_prepare_receive_response(dynamic raw) {
|
||||||
// Codec=Dco (DartCObject based), see doc to use other codecs
|
// Codec=Dco (DartCObject based), see doc to use other codecs
|
||||||
final arr = raw as List<dynamic>;
|
final arr = raw as List<dynamic>;
|
||||||
if (arr.length != 3) throw Exception('unexpected arr length: expect 3 but see ${arr.length}');
|
if (arr.length != 6) throw Exception('unexpected arr length: expect 6 but see ${arr.length}');
|
||||||
return PrepareReceiveResponse(
|
return PrepareReceiveResponse(
|
||||||
paymentMethod: dco_decode_payment_method(arr[0]),
|
paymentMethod: dco_decode_payment_method(arr[0]),
|
||||||
payerAmountSat: dco_decode_opt_box_autoadd_u_64(arr[1]),
|
payerAmountSat: dco_decode_opt_box_autoadd_u_64(arr[1]),
|
||||||
feesSat: dco_decode_u_64(arr[2]),
|
feesSat: dco_decode_u_64(arr[2]),
|
||||||
|
minPayerAmountSat: dco_decode_opt_box_autoadd_u_64(arr[3]),
|
||||||
|
maxPayerAmountSat: dco_decode_opt_box_autoadd_u_64(arr[4]),
|
||||||
|
swapperFeerate: dco_decode_opt_box_autoadd_f_64(arr[5]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3291,6 +3306,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return (sse_decode_connect_request(deserializer));
|
return (sse_decode_connect_request(deserializer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
double sse_decode_box_autoadd_f_64(SseDeserializer deserializer) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
return (sse_decode_f_64(deserializer));
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
GetPaymentRequest sse_decode_box_autoadd_get_payment_request(SseDeserializer deserializer) {
|
GetPaymentRequest sse_decode_box_autoadd_get_payment_request(SseDeserializer deserializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
@@ -4303,6 +4324,17 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
double? sse_decode_opt_box_autoadd_f_64(SseDeserializer deserializer) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
|
||||||
|
if (sse_decode_bool(deserializer)) {
|
||||||
|
return (sse_decode_box_autoadd_f_64(deserializer));
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
PlatformInt64? sse_decode_opt_box_autoadd_i_64(SseDeserializer deserializer) {
|
PlatformInt64? sse_decode_opt_box_autoadd_i_64(SseDeserializer deserializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
@@ -4664,8 +4696,16 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
var var_paymentMethod = sse_decode_payment_method(deserializer);
|
var var_paymentMethod = sse_decode_payment_method(deserializer);
|
||||||
var var_payerAmountSat = sse_decode_opt_box_autoadd_u_64(deserializer);
|
var var_payerAmountSat = sse_decode_opt_box_autoadd_u_64(deserializer);
|
||||||
var var_feesSat = sse_decode_u_64(deserializer);
|
var var_feesSat = sse_decode_u_64(deserializer);
|
||||||
|
var var_minPayerAmountSat = sse_decode_opt_box_autoadd_u_64(deserializer);
|
||||||
|
var var_maxPayerAmountSat = sse_decode_opt_box_autoadd_u_64(deserializer);
|
||||||
|
var var_swapperFeerate = sse_decode_opt_box_autoadd_f_64(deserializer);
|
||||||
return PrepareReceiveResponse(
|
return PrepareReceiveResponse(
|
||||||
paymentMethod: var_paymentMethod, payerAmountSat: var_payerAmountSat, feesSat: var_feesSat);
|
paymentMethod: var_paymentMethod,
|
||||||
|
payerAmountSat: var_payerAmountSat,
|
||||||
|
feesSat: var_feesSat,
|
||||||
|
minPayerAmountSat: var_minPayerAmountSat,
|
||||||
|
maxPayerAmountSat: var_maxPayerAmountSat,
|
||||||
|
swapperFeerate: var_swapperFeerate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
@@ -5308,6 +5348,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_connect_request(self, serializer);
|
sse_encode_connect_request(self, serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_box_autoadd_f_64(double self, SseSerializer serializer) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
sse_encode_f_64(self, serializer);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_box_autoadd_get_payment_request(GetPaymentRequest self, SseSerializer serializer) {
|
void sse_encode_box_autoadd_get_payment_request(GetPaymentRequest self, SseSerializer serializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
@@ -6175,6 +6221,16 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_opt_box_autoadd_f_64(double? self, SseSerializer serializer) {
|
||||||
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
|
|
||||||
|
sse_encode_bool(self != null, serializer);
|
||||||
|
if (self != null) {
|
||||||
|
sse_encode_box_autoadd_f_64(self, serializer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_opt_box_autoadd_i_64(PlatformInt64? self, SseSerializer serializer) {
|
void sse_encode_opt_box_autoadd_i_64(PlatformInt64? self, SseSerializer serializer) {
|
||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
@@ -6494,6 +6550,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_payment_method(self.paymentMethod, serializer);
|
sse_encode_payment_method(self.paymentMethod, serializer);
|
||||||
sse_encode_opt_box_autoadd_u_64(self.payerAmountSat, serializer);
|
sse_encode_opt_box_autoadd_u_64(self.payerAmountSat, serializer);
|
||||||
sse_encode_u_64(self.feesSat, serializer);
|
sse_encode_u_64(self.feesSat, serializer);
|
||||||
|
sse_encode_opt_box_autoadd_u_64(self.minPayerAmountSat, serializer);
|
||||||
|
sse_encode_opt_box_autoadd_u_64(self.maxPayerAmountSat, serializer);
|
||||||
|
sse_encode_opt_box_autoadd_f_64(self.swapperFeerate, serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
|
|||||||
@@ -107,6 +107,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
ConnectRequest dco_decode_box_autoadd_connect_request(dynamic raw);
|
ConnectRequest dco_decode_box_autoadd_connect_request(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
double dco_decode_box_autoadd_f_64(dynamic raw);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
GetPaymentRequest dco_decode_box_autoadd_get_payment_request(dynamic raw);
|
GetPaymentRequest dco_decode_box_autoadd_get_payment_request(dynamic raw);
|
||||||
|
|
||||||
@@ -398,6 +401,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
bool? dco_decode_opt_box_autoadd_bool(dynamic raw);
|
bool? dco_decode_opt_box_autoadd_bool(dynamic raw);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
double? dco_decode_opt_box_autoadd_f_64(dynamic raw);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
PlatformInt64? dco_decode_opt_box_autoadd_i_64(dynamic raw);
|
PlatformInt64? dco_decode_opt_box_autoadd_i_64(dynamic raw);
|
||||||
|
|
||||||
@@ -654,6 +660,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
ConnectRequest sse_decode_box_autoadd_connect_request(SseDeserializer deserializer);
|
ConnectRequest sse_decode_box_autoadd_connect_request(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
double sse_decode_box_autoadd_f_64(SseDeserializer deserializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
GetPaymentRequest sse_decode_box_autoadd_get_payment_request(SseDeserializer deserializer);
|
GetPaymentRequest sse_decode_box_autoadd_get_payment_request(SseDeserializer deserializer);
|
||||||
|
|
||||||
@@ -945,6 +954,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
bool? sse_decode_opt_box_autoadd_bool(SseDeserializer deserializer);
|
bool? sse_decode_opt_box_autoadd_bool(SseDeserializer deserializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
double? sse_decode_opt_box_autoadd_f_64(SseDeserializer deserializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
PlatformInt64? sse_decode_opt_box_autoadd_i_64(SseDeserializer deserializer);
|
PlatformInt64? sse_decode_opt_box_autoadd_i_64(SseDeserializer deserializer);
|
||||||
|
|
||||||
@@ -1243,6 +1255,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
ffi.Pointer<ffi.Double> cst_encode_box_autoadd_f_64(double raw) {
|
||||||
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
|
return wire.cst_new_box_autoadd_f_64(cst_encode_f_64(raw));
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
ffi.Pointer<wire_cst_get_payment_request> cst_encode_box_autoadd_get_payment_request(
|
ffi.Pointer<wire_cst_get_payment_request> cst_encode_box_autoadd_get_payment_request(
|
||||||
GetPaymentRequest raw) {
|
GetPaymentRequest raw) {
|
||||||
@@ -1708,6 +1726,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
return raw == null ? ffi.nullptr : cst_encode_box_autoadd_bool(raw);
|
return raw == null ? ffi.nullptr : cst_encode_box_autoadd_bool(raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@protected
|
||||||
|
ffi.Pointer<ffi.Double> cst_encode_opt_box_autoadd_f_64(double? raw) {
|
||||||
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
|
return raw == null ? ffi.nullptr : cst_encode_box_autoadd_f_64(raw);
|
||||||
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
ffi.Pointer<ffi.Int64> cst_encode_opt_box_autoadd_i_64(PlatformInt64? raw) {
|
ffi.Pointer<ffi.Int64> cst_encode_opt_box_autoadd_i_64(PlatformInt64? raw) {
|
||||||
// Codec=Cst (C-struct based), see doc to use other codecs
|
// Codec=Cst (C-struct based), see doc to use other codecs
|
||||||
@@ -2895,6 +2919,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
wireObj.payment_method = cst_encode_payment_method(apiObj.paymentMethod);
|
wireObj.payment_method = cst_encode_payment_method(apiObj.paymentMethod);
|
||||||
wireObj.payer_amount_sat = cst_encode_opt_box_autoadd_u_64(apiObj.payerAmountSat);
|
wireObj.payer_amount_sat = cst_encode_opt_box_autoadd_u_64(apiObj.payerAmountSat);
|
||||||
wireObj.fees_sat = cst_encode_u_64(apiObj.feesSat);
|
wireObj.fees_sat = cst_encode_u_64(apiObj.feesSat);
|
||||||
|
wireObj.min_payer_amount_sat = cst_encode_opt_box_autoadd_u_64(apiObj.minPayerAmountSat);
|
||||||
|
wireObj.max_payer_amount_sat = cst_encode_opt_box_autoadd_u_64(apiObj.maxPayerAmountSat);
|
||||||
|
wireObj.swapper_feerate = cst_encode_opt_box_autoadd_f_64(apiObj.swapperFeerate);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
@@ -3308,6 +3335,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
void sse_encode_box_autoadd_connect_request(ConnectRequest self, SseSerializer serializer);
|
void sse_encode_box_autoadd_connect_request(ConnectRequest self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_box_autoadd_f_64(double self, SseSerializer serializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_box_autoadd_get_payment_request(GetPaymentRequest self, SseSerializer serializer);
|
void sse_encode_box_autoadd_get_payment_request(GetPaymentRequest self, SseSerializer serializer);
|
||||||
|
|
||||||
@@ -3607,6 +3637,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
@protected
|
@protected
|
||||||
void sse_encode_opt_box_autoadd_bool(bool? self, SseSerializer serializer);
|
void sse_encode_opt_box_autoadd_bool(bool? self, SseSerializer serializer);
|
||||||
|
|
||||||
|
@protected
|
||||||
|
void sse_encode_opt_box_autoadd_f_64(double? self, SseSerializer serializer);
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
void sse_encode_opt_box_autoadd_i_64(PlatformInt64? self, SseSerializer serializer);
|
void sse_encode_opt_box_autoadd_i_64(PlatformInt64? self, SseSerializer serializer);
|
||||||
|
|
||||||
@@ -4689,6 +4722,20 @@ class RustLibWire implements BaseWire {
|
|||||||
late final _cst_new_box_autoadd_connect_request =
|
late final _cst_new_box_autoadd_connect_request =
|
||||||
_cst_new_box_autoadd_connect_requestPtr.asFunction<ffi.Pointer<wire_cst_connect_request> Function()>();
|
_cst_new_box_autoadd_connect_requestPtr.asFunction<ffi.Pointer<wire_cst_connect_request> Function()>();
|
||||||
|
|
||||||
|
ffi.Pointer<ffi.Double> cst_new_box_autoadd_f_64(
|
||||||
|
double value,
|
||||||
|
) {
|
||||||
|
return _cst_new_box_autoadd_f_64(
|
||||||
|
value,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final _cst_new_box_autoadd_f_64Ptr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Double> Function(ffi.Double)>>(
|
||||||
|
'frbgen_breez_liquid_cst_new_box_autoadd_f_64');
|
||||||
|
late final _cst_new_box_autoadd_f_64 =
|
||||||
|
_cst_new_box_autoadd_f_64Ptr.asFunction<ffi.Pointer<ffi.Double> Function(double)>();
|
||||||
|
|
||||||
ffi.Pointer<wire_cst_get_payment_request> cst_new_box_autoadd_get_payment_request() {
|
ffi.Pointer<wire_cst_get_payment_request> cst_new_box_autoadd_get_payment_request() {
|
||||||
return _cst_new_box_autoadd_get_payment_request();
|
return _cst_new_box_autoadd_get_payment_request();
|
||||||
}
|
}
|
||||||
@@ -5744,6 +5791,12 @@ final class wire_cst_prepare_receive_response extends ffi.Struct {
|
|||||||
|
|
||||||
@ffi.Uint64()
|
@ffi.Uint64()
|
||||||
external int fees_sat;
|
external int fees_sat;
|
||||||
|
|
||||||
|
external ffi.Pointer<ffi.Uint64> min_payer_amount_sat;
|
||||||
|
|
||||||
|
external ffi.Pointer<ffi.Uint64> max_payer_amount_sat;
|
||||||
|
|
||||||
|
external ffi.Pointer<ffi.Double> swapper_feerate;
|
||||||
}
|
}
|
||||||
|
|
||||||
final class wire_cst_receive_payment_request extends ffi.Struct {
|
final class wire_cst_receive_payment_request extends ffi.Struct {
|
||||||
|
|||||||
@@ -936,16 +936,49 @@ class PrepareReceiveRequest {
|
|||||||
class PrepareReceiveResponse {
|
class PrepareReceiveResponse {
|
||||||
final PaymentMethod paymentMethod;
|
final PaymentMethod paymentMethod;
|
||||||
final BigInt? payerAmountSat;
|
final BigInt? payerAmountSat;
|
||||||
|
|
||||||
|
/// Generally represents the total fees that would be paid to send or receive this payment.
|
||||||
|
///
|
||||||
|
/// In case of Zero-Amount Receive Chain swaps, the swapper service fee (`swapper_feerate` times
|
||||||
|
/// the amount) is paid in addition to `fees_sat`. The swapper service feerate is already known
|
||||||
|
/// in the beginning, but the exact swapper service fee will only be known when the
|
||||||
|
/// `payer_amount_sat` is known.
|
||||||
|
///
|
||||||
|
/// In all other types of swaps, the swapper service fee is included in `fees_sat`.
|
||||||
final BigInt feesSat;
|
final BigInt feesSat;
|
||||||
|
|
||||||
|
/// The minimum amount the payer can send for this swap to succeed.
|
||||||
|
///
|
||||||
|
/// When the method is [PaymentMethod::LiquidAddress], this is empty.
|
||||||
|
final BigInt? minPayerAmountSat;
|
||||||
|
|
||||||
|
/// The maximum amount the payer can send for this swap to succeed.
|
||||||
|
///
|
||||||
|
/// When the method is [PaymentMethod::LiquidAddress], this is empty.
|
||||||
|
final BigInt? maxPayerAmountSat;
|
||||||
|
|
||||||
|
/// The percentage of the sent amount that will count towards the service fee.
|
||||||
|
///
|
||||||
|
/// When the method is [PaymentMethod::LiquidAddress], this is empty.
|
||||||
|
final double? swapperFeerate;
|
||||||
|
|
||||||
const PrepareReceiveResponse({
|
const PrepareReceiveResponse({
|
||||||
required this.paymentMethod,
|
required this.paymentMethod,
|
||||||
this.payerAmountSat,
|
this.payerAmountSat,
|
||||||
required this.feesSat,
|
required this.feesSat,
|
||||||
|
this.minPayerAmountSat,
|
||||||
|
this.maxPayerAmountSat,
|
||||||
|
this.swapperFeerate,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => paymentMethod.hashCode ^ payerAmountSat.hashCode ^ feesSat.hashCode;
|
int get hashCode =>
|
||||||
|
paymentMethod.hashCode ^
|
||||||
|
payerAmountSat.hashCode ^
|
||||||
|
feesSat.hashCode ^
|
||||||
|
minPayerAmountSat.hashCode ^
|
||||||
|
maxPayerAmountSat.hashCode ^
|
||||||
|
swapperFeerate.hashCode;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
@@ -954,7 +987,10 @@ class PrepareReceiveResponse {
|
|||||||
runtimeType == other.runtimeType &&
|
runtimeType == other.runtimeType &&
|
||||||
paymentMethod == other.paymentMethod &&
|
paymentMethod == other.paymentMethod &&
|
||||||
payerAmountSat == other.payerAmountSat &&
|
payerAmountSat == other.payerAmountSat &&
|
||||||
feesSat == other.feesSat;
|
feesSat == other.feesSat &&
|
||||||
|
minPayerAmountSat == other.minPayerAmountSat &&
|
||||||
|
maxPayerAmountSat == other.maxPayerAmountSat &&
|
||||||
|
swapperFeerate == other.swapperFeerate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An argument when calling [crate::sdk::LiquidSdk::prepare_refund].
|
/// An argument when calling [crate::sdk::LiquidSdk::prepare_refund].
|
||||||
|
|||||||
@@ -939,6 +939,20 @@ class FlutterBreezLiquidBindings {
|
|||||||
_frbgen_breez_liquid_cst_new_box_autoadd_connect_requestPtr
|
_frbgen_breez_liquid_cst_new_box_autoadd_connect_requestPtr
|
||||||
.asFunction<ffi.Pointer<wire_cst_connect_request> Function()>();
|
.asFunction<ffi.Pointer<wire_cst_connect_request> Function()>();
|
||||||
|
|
||||||
|
ffi.Pointer<ffi.Double> frbgen_breez_liquid_cst_new_box_autoadd_f_64(
|
||||||
|
double value,
|
||||||
|
) {
|
||||||
|
return _frbgen_breez_liquid_cst_new_box_autoadd_f_64(
|
||||||
|
value,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
late final _frbgen_breez_liquid_cst_new_box_autoadd_f_64Ptr =
|
||||||
|
_lookup<ffi.NativeFunction<ffi.Pointer<ffi.Double> Function(ffi.Double)>>(
|
||||||
|
'frbgen_breez_liquid_cst_new_box_autoadd_f_64');
|
||||||
|
late final _frbgen_breez_liquid_cst_new_box_autoadd_f_64 =
|
||||||
|
_frbgen_breez_liquid_cst_new_box_autoadd_f_64Ptr.asFunction<ffi.Pointer<ffi.Double> Function(double)>();
|
||||||
|
|
||||||
ffi.Pointer<wire_cst_get_payment_request> frbgen_breez_liquid_cst_new_box_autoadd_get_payment_request() {
|
ffi.Pointer<wire_cst_get_payment_request> frbgen_breez_liquid_cst_new_box_autoadd_get_payment_request() {
|
||||||
return _frbgen_breez_liquid_cst_new_box_autoadd_get_payment_request();
|
return _frbgen_breez_liquid_cst_new_box_autoadd_get_payment_request();
|
||||||
}
|
}
|
||||||
@@ -4327,6 +4341,12 @@ final class wire_cst_prepare_receive_response extends ffi.Struct {
|
|||||||
|
|
||||||
@ffi.Uint64()
|
@ffi.Uint64()
|
||||||
external int fees_sat;
|
external int fees_sat;
|
||||||
|
|
||||||
|
external ffi.Pointer<ffi.Uint64> min_payer_amount_sat;
|
||||||
|
|
||||||
|
external ffi.Pointer<ffi.Uint64> max_payer_amount_sat;
|
||||||
|
|
||||||
|
external ffi.Pointer<ffi.Double> swapper_feerate;
|
||||||
}
|
}
|
||||||
|
|
||||||
final class wire_cst_receive_payment_request extends ffi.Struct {
|
final class wire_cst_receive_payment_request extends ffi.Struct {
|
||||||
|
|||||||
@@ -1687,6 +1687,8 @@ fun asPrepareReceiveResponse(prepareReceiveResponse: ReadableMap): PrepareReceiv
|
|||||||
) {
|
) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
val paymentMethod = prepareReceiveResponse.getString("paymentMethod")?.let { asPaymentMethod(it) }!!
|
||||||
|
val feesSat = prepareReceiveResponse.getDouble("feesSat").toULong()
|
||||||
val payerAmountSat =
|
val payerAmountSat =
|
||||||
if (hasNonNullKey(
|
if (hasNonNullKey(
|
||||||
prepareReceiveResponse,
|
prepareReceiveResponse,
|
||||||
@@ -1697,16 +1699,47 @@ fun asPrepareReceiveResponse(prepareReceiveResponse: ReadableMap): PrepareReceiv
|
|||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
val paymentMethod = prepareReceiveResponse.getString("paymentMethod")?.let { asPaymentMethod(it) }!!
|
val minPayerAmountSat =
|
||||||
val feesSat = prepareReceiveResponse.getDouble("feesSat").toULong()
|
if (hasNonNullKey(
|
||||||
return PrepareReceiveResponse(payerAmountSat, paymentMethod, feesSat)
|
prepareReceiveResponse,
|
||||||
|
"minPayerAmountSat",
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
prepareReceiveResponse.getDouble("minPayerAmountSat").toULong()
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
val maxPayerAmountSat =
|
||||||
|
if (hasNonNullKey(
|
||||||
|
prepareReceiveResponse,
|
||||||
|
"maxPayerAmountSat",
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
prepareReceiveResponse.getDouble("maxPayerAmountSat").toULong()
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
val swapperFeerate =
|
||||||
|
if (hasNonNullKey(
|
||||||
|
prepareReceiveResponse,
|
||||||
|
"swapperFeerate",
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
prepareReceiveResponse.getDouble("swapperFeerate")
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
return PrepareReceiveResponse(paymentMethod, feesSat, payerAmountSat, minPayerAmountSat, maxPayerAmountSat, swapperFeerate)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun readableMapOf(prepareReceiveResponse: PrepareReceiveResponse): ReadableMap =
|
fun readableMapOf(prepareReceiveResponse: PrepareReceiveResponse): ReadableMap =
|
||||||
readableMapOf(
|
readableMapOf(
|
||||||
"payerAmountSat" to prepareReceiveResponse.payerAmountSat,
|
|
||||||
"paymentMethod" to prepareReceiveResponse.paymentMethod.name.lowercase(),
|
"paymentMethod" to prepareReceiveResponse.paymentMethod.name.lowercase(),
|
||||||
"feesSat" to prepareReceiveResponse.feesSat,
|
"feesSat" to prepareReceiveResponse.feesSat,
|
||||||
|
"payerAmountSat" to prepareReceiveResponse.payerAmountSat,
|
||||||
|
"minPayerAmountSat" to prepareReceiveResponse.minPayerAmountSat,
|
||||||
|
"maxPayerAmountSat" to prepareReceiveResponse.maxPayerAmountSat,
|
||||||
|
"swapperFeerate" to prepareReceiveResponse.swapperFeerate,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun asPrepareReceiveResponseList(arr: ReadableArray): List<PrepareReceiveResponse> {
|
fun asPrepareReceiveResponseList(arr: ReadableArray): List<PrepareReceiveResponse> {
|
||||||
|
|||||||
@@ -1972,13 +1972,6 @@ enum BreezSDKLiquidMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static func asPrepareReceiveResponse(prepareReceiveResponse: [String: Any?]) throws -> PrepareReceiveResponse {
|
static func asPrepareReceiveResponse(prepareReceiveResponse: [String: Any?]) throws -> PrepareReceiveResponse {
|
||||||
var payerAmountSat: UInt64?
|
|
||||||
if hasNonNilKey(data: prepareReceiveResponse, key: "payerAmountSat") {
|
|
||||||
guard let payerAmountSatTmp = prepareReceiveResponse["payerAmountSat"] as? UInt64 else {
|
|
||||||
throw SdkError.Generic(message: errUnexpectedValue(fieldName: "payerAmountSat"))
|
|
||||||
}
|
|
||||||
payerAmountSat = payerAmountSatTmp
|
|
||||||
}
|
|
||||||
guard let paymentMethodTmp = prepareReceiveResponse["paymentMethod"] as? String else {
|
guard let paymentMethodTmp = prepareReceiveResponse["paymentMethod"] as? String else {
|
||||||
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "paymentMethod", typeName: "PrepareReceiveResponse"))
|
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "paymentMethod", typeName: "PrepareReceiveResponse"))
|
||||||
}
|
}
|
||||||
@@ -1987,15 +1980,46 @@ enum BreezSDKLiquidMapper {
|
|||||||
guard let feesSat = prepareReceiveResponse["feesSat"] as? UInt64 else {
|
guard let feesSat = prepareReceiveResponse["feesSat"] as? UInt64 else {
|
||||||
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "feesSat", typeName: "PrepareReceiveResponse"))
|
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "feesSat", typeName: "PrepareReceiveResponse"))
|
||||||
}
|
}
|
||||||
|
var payerAmountSat: UInt64?
|
||||||
|
if hasNonNilKey(data: prepareReceiveResponse, key: "payerAmountSat") {
|
||||||
|
guard let payerAmountSatTmp = prepareReceiveResponse["payerAmountSat"] as? UInt64 else {
|
||||||
|
throw SdkError.Generic(message: errUnexpectedValue(fieldName: "payerAmountSat"))
|
||||||
|
}
|
||||||
|
payerAmountSat = payerAmountSatTmp
|
||||||
|
}
|
||||||
|
var minPayerAmountSat: UInt64?
|
||||||
|
if hasNonNilKey(data: prepareReceiveResponse, key: "minPayerAmountSat") {
|
||||||
|
guard let minPayerAmountSatTmp = prepareReceiveResponse["minPayerAmountSat"] as? UInt64 else {
|
||||||
|
throw SdkError.Generic(message: errUnexpectedValue(fieldName: "minPayerAmountSat"))
|
||||||
|
}
|
||||||
|
minPayerAmountSat = minPayerAmountSatTmp
|
||||||
|
}
|
||||||
|
var maxPayerAmountSat: UInt64?
|
||||||
|
if hasNonNilKey(data: prepareReceiveResponse, key: "maxPayerAmountSat") {
|
||||||
|
guard let maxPayerAmountSatTmp = prepareReceiveResponse["maxPayerAmountSat"] as? UInt64 else {
|
||||||
|
throw SdkError.Generic(message: errUnexpectedValue(fieldName: "maxPayerAmountSat"))
|
||||||
|
}
|
||||||
|
maxPayerAmountSat = maxPayerAmountSatTmp
|
||||||
|
}
|
||||||
|
var swapperFeerate: Double?
|
||||||
|
if hasNonNilKey(data: prepareReceiveResponse, key: "swapperFeerate") {
|
||||||
|
guard let swapperFeerateTmp = prepareReceiveResponse["swapperFeerate"] as? Double else {
|
||||||
|
throw SdkError.Generic(message: errUnexpectedValue(fieldName: "swapperFeerate"))
|
||||||
|
}
|
||||||
|
swapperFeerate = swapperFeerateTmp
|
||||||
|
}
|
||||||
|
|
||||||
return PrepareReceiveResponse(payerAmountSat: payerAmountSat, paymentMethod: paymentMethod, feesSat: feesSat)
|
return PrepareReceiveResponse(paymentMethod: paymentMethod, feesSat: feesSat, payerAmountSat: payerAmountSat, minPayerAmountSat: minPayerAmountSat, maxPayerAmountSat: maxPayerAmountSat, swapperFeerate: swapperFeerate)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func dictionaryOf(prepareReceiveResponse: PrepareReceiveResponse) -> [String: Any?] {
|
static func dictionaryOf(prepareReceiveResponse: PrepareReceiveResponse) -> [String: Any?] {
|
||||||
return [
|
return [
|
||||||
"payerAmountSat": prepareReceiveResponse.payerAmountSat == nil ? nil : prepareReceiveResponse.payerAmountSat,
|
|
||||||
"paymentMethod": valueOf(paymentMethod: prepareReceiveResponse.paymentMethod),
|
"paymentMethod": valueOf(paymentMethod: prepareReceiveResponse.paymentMethod),
|
||||||
"feesSat": prepareReceiveResponse.feesSat,
|
"feesSat": prepareReceiveResponse.feesSat,
|
||||||
|
"payerAmountSat": prepareReceiveResponse.payerAmountSat == nil ? nil : prepareReceiveResponse.payerAmountSat,
|
||||||
|
"minPayerAmountSat": prepareReceiveResponse.minPayerAmountSat == nil ? nil : prepareReceiveResponse.minPayerAmountSat,
|
||||||
|
"maxPayerAmountSat": prepareReceiveResponse.maxPayerAmountSat == nil ? nil : prepareReceiveResponse.maxPayerAmountSat,
|
||||||
|
"swapperFeerate": prepareReceiveResponse.swapperFeerate == nil ? nil : prepareReceiveResponse.swapperFeerate,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -299,9 +299,12 @@ export interface PrepareReceiveRequest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface PrepareReceiveResponse {
|
export interface PrepareReceiveResponse {
|
||||||
payerAmountSat?: number
|
|
||||||
paymentMethod: PaymentMethod
|
paymentMethod: PaymentMethod
|
||||||
feesSat: number
|
feesSat: number
|
||||||
|
payerAmountSat?: number
|
||||||
|
minPayerAmountSat?: number
|
||||||
|
maxPayerAmountSat?: number
|
||||||
|
swapperFeerate?: number
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PrepareRefundRequest {
|
export interface PrepareRefundRequest {
|
||||||
|
|||||||
Reference in New Issue
Block a user