Liquid/Lightning drain (#553)

* Attempt drain using liquid or lightning payment

* Optimize estimation handling, use address in drain estimation

* Add drain option to PrepareSendRequest

* Block draining while there are pending payments

* Apply suggestions from code review

* Rename PayOnchainAmount to PayAmount
This commit is contained in:
Ross Savage
2024-11-11 21:50:18 +01:00
committed by GitHub
parent 2c70315125
commit 4da57e3fe2
18 changed files with 503 additions and 291 deletions

View File

@@ -34,8 +34,12 @@ pub(crate) enum Command {
#[arg(short, long)] #[arg(short, long)]
amount_sat: Option<u64>, amount_sat: Option<u64>,
/// Delay for the send, in seconds /// Whether or not this is a drain operation. If true, all available funds will be used.
#[arg(short, long)] #[arg(short, long)]
drain: Option<bool>,
/// Delay for the send, in seconds
#[arg(long)]
delay: Option<u64>, delay: Option<u64>,
}, },
/// Fetch the current limits for Send and Receive payments /// Fetch the current limits for Send and Receive payments
@@ -310,6 +314,7 @@ pub(crate) async fn handle_command(
invoice, invoice,
address, address,
amount_sat, amount_sat,
drain,
delay, delay,
} => { } => {
let destination = match (invoice, address) { let destination = match (invoice, address) {
@@ -326,11 +331,16 @@ pub(crate) async fn handle_command(
)) ))
} }
}; };
let amount = match (amount_sat, drain.unwrap_or(false)) {
(Some(amount_sat), _) => Some(PayAmount::Receiver { amount_sat }),
(_, true) => Some(PayAmount::Drain),
(_, _) => None,
};
let prepare_response = sdk let prepare_response = sdk
.prepare_send_payment(&PrepareSendRequest { .prepare_send_payment(&PrepareSendRequest {
destination, destination,
amount_sat, amount,
}) })
.await?; .await?;
@@ -366,8 +376,8 @@ pub(crate) async fn handle_command(
fee_rate_sat_per_vbyte, fee_rate_sat_per_vbyte,
} => { } => {
let amount = match drain.unwrap_or(false) { let amount = match drain.unwrap_or(false) {
true => PayOnchainAmount::Drain, true => PayAmount::Drain,
false => PayOnchainAmount::Receiver { false => PayAmount::Receiver {
amount_sat: receiver_amount_sat.ok_or(anyhow::anyhow!( amount_sat: receiver_amount_sat.ok_or(anyhow::anyhow!(
"Must specify `receiver_amount_sat` if not draining" "Must specify `receiver_amount_sat` if not draining"
))?, ))?,

View File

@@ -279,21 +279,21 @@ typedef struct wire_cst_prepare_ln_url_pay_request {
bool *validate_success_action_url; bool *validate_success_action_url;
} wire_cst_prepare_ln_url_pay_request; } wire_cst_prepare_ln_url_pay_request;
typedef struct wire_cst_PayOnchainAmount_Receiver { typedef struct wire_cst_PayAmount_Receiver {
uint64_t amount_sat; uint64_t amount_sat;
} wire_cst_PayOnchainAmount_Receiver; } wire_cst_PayAmount_Receiver;
typedef union PayOnchainAmountKind { typedef union PayAmountKind {
struct wire_cst_PayOnchainAmount_Receiver Receiver; struct wire_cst_PayAmount_Receiver Receiver;
} PayOnchainAmountKind; } PayAmountKind;
typedef struct wire_cst_pay_onchain_amount { typedef struct wire_cst_pay_amount {
int32_t tag; int32_t tag;
union PayOnchainAmountKind kind; union PayAmountKind kind;
} wire_cst_pay_onchain_amount; } wire_cst_pay_amount;
typedef struct wire_cst_prepare_pay_onchain_request { typedef struct wire_cst_prepare_pay_onchain_request {
struct wire_cst_pay_onchain_amount amount; struct wire_cst_pay_amount amount;
uint32_t *fee_rate_sat_per_vbyte; uint32_t *fee_rate_sat_per_vbyte;
} wire_cst_prepare_pay_onchain_request; } wire_cst_prepare_pay_onchain_request;
@@ -310,7 +310,7 @@ typedef struct wire_cst_prepare_refund_request {
typedef struct wire_cst_prepare_send_request { typedef struct wire_cst_prepare_send_request {
struct wire_cst_list_prim_u_8_strict *destination; struct wire_cst_list_prim_u_8_strict *destination;
uint64_t *amount_sat; struct wire_cst_pay_amount *amount;
} wire_cst_prepare_send_request; } wire_cst_prepare_send_request;
typedef struct wire_cst_prepare_receive_response { typedef struct wire_cst_prepare_receive_response {
@@ -1166,6 +1166,8 @@ struct wire_cst_ln_url_withdraw_success_data *frbgen_breez_liquid_cst_new_box_au
struct wire_cst_message_success_action_data *frbgen_breez_liquid_cst_new_box_autoadd_message_success_action_data(void); struct wire_cst_message_success_action_data *frbgen_breez_liquid_cst_new_box_autoadd_message_success_action_data(void);
struct wire_cst_pay_amount *frbgen_breez_liquid_cst_new_box_autoadd_pay_amount(void);
struct wire_cst_pay_onchain_request *frbgen_breez_liquid_cst_new_box_autoadd_pay_onchain_request(void); struct wire_cst_pay_onchain_request *frbgen_breez_liquid_cst_new_box_autoadd_pay_onchain_request(void);
struct wire_cst_payment *frbgen_breez_liquid_cst_new_box_autoadd_payment(void); struct wire_cst_payment *frbgen_breez_liquid_cst_new_box_autoadd_payment(void);
@@ -1253,6 +1255,7 @@ static int64_t dummy_method_to_enforce_bundling(void) {
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_ln_url_withdraw_request_data); dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_ln_url_withdraw_request_data);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_ln_url_withdraw_success_data); dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_ln_url_withdraw_success_data);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_message_success_action_data); dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_message_success_action_data);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_pay_amount);
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_pay_onchain_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_payment); dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_payment);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_buy_bitcoin_request); dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_buy_bitcoin_request);

View File

@@ -373,7 +373,7 @@ dictionary LnUrlPayRequest {
dictionary PrepareSendRequest { dictionary PrepareSendRequest {
string destination; string destination;
u64? amount_sat = null; PayAmount? amount = null;
}; };
[Enum] [Enum]
@@ -439,13 +439,13 @@ dictionary OnchainPaymentLimitsResponse {
}; };
[Enum] [Enum]
interface PayOnchainAmount { interface PayAmount {
Receiver(u64 amount_sat); Receiver(u64 amount_sat);
Drain(); Drain();
}; };
dictionary PreparePayOnchainRequest { dictionary PreparePayOnchainRequest {
PayOnchainAmount amount; PayAmount amount;
u32? fee_rate_sat_per_vbyte = null; u32? fee_rate_sat_per_vbyte = null;
}; };

View File

@@ -681,30 +681,14 @@ impl ChainSwapHandler {
lockup_details.amount, lockup_details.lockup_address lockup_details.amount, lockup_details.lockup_address
); );
let lockup_tx = match self let lockup_tx = self
.onchain_wallet .onchain_wallet
.build_tx( .build_tx_or_drain_tx(
self.config self.config.lowball_fee_rate_msat_per_vbyte(),
.lowball_fee_rate_msat_per_vbyte()
.map(|v| v as f32),
&lockup_details.lockup_address, &lockup_details.lockup_address,
lockup_details.amount, lockup_details.amount,
) )
.await .await?;
{
Err(PaymentError::InsufficientFunds) => {
warn!("Cannot build normal lockup tx due to insufficient funds, attempting to build drain tx");
self.onchain_wallet
.build_drain_tx(
None,
&lockup_details.lockup_address,
Some(lockup_details.amount),
)
.await
}
Err(e) => Err(e),
Ok(lockup_tx) => Ok(lockup_tx),
}?;
let lockup_tx_id = self let lockup_tx_id = self
.liquid_chain_service .liquid_chain_service

View File

@@ -3180,6 +3180,17 @@ impl SseDecode for Option<crate::model::ListPaymentDetails> {
} }
} }
impl SseDecode for Option<crate::model::PayAmount> {
// 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(<crate::model::PayAmount>::sse_decode(deserializer));
} else {
return None;
}
}
}
impl SseDecode for Option<crate::model::Payment> { impl SseDecode for Option<crate::model::Payment> {
// 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 {
@@ -3259,19 +3270,19 @@ impl SseDecode for Option<Vec<crate::model::PaymentType>> {
} }
} }
impl SseDecode for crate::model::PayOnchainAmount { impl SseDecode for crate::model::PayAmount {
// 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 {
let mut tag_ = <i32>::sse_decode(deserializer); let mut tag_ = <i32>::sse_decode(deserializer);
match tag_ { match tag_ {
0 => { 0 => {
let mut var_amountSat = <u64>::sse_decode(deserializer); let mut var_amountSat = <u64>::sse_decode(deserializer);
return crate::model::PayOnchainAmount::Receiver { return crate::model::PayAmount::Receiver {
amount_sat: var_amountSat, amount_sat: var_amountSat,
}; };
} }
1 => { 1 => {
return crate::model::PayOnchainAmount::Drain; return crate::model::PayAmount::Drain;
} }
_ => { _ => {
unimplemented!(""); unimplemented!("");
@@ -3558,7 +3569,7 @@ impl SseDecode for crate::model::PrepareLnUrlPayResponse {
impl SseDecode for crate::model::PreparePayOnchainRequest { impl SseDecode for crate::model::PreparePayOnchainRequest {
// 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 {
let mut var_amount = <crate::model::PayOnchainAmount>::sse_decode(deserializer); let mut var_amount = <crate::model::PayAmount>::sse_decode(deserializer);
let mut var_feeRateSatPerVbyte = <Option<u32>>::sse_decode(deserializer); let mut var_feeRateSatPerVbyte = <Option<u32>>::sse_decode(deserializer);
return crate::model::PreparePayOnchainRequest { return crate::model::PreparePayOnchainRequest {
amount: var_amount, amount: var_amount,
@@ -3639,10 +3650,10 @@ impl SseDecode for crate::model::PrepareSendRequest {
// 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 {
let mut var_destination = <String>::sse_decode(deserializer); let mut var_destination = <String>::sse_decode(deserializer);
let mut var_amountSat = <Option<u64>>::sse_decode(deserializer); let mut var_amount = <Option<crate::model::PayAmount>>::sse_decode(deserializer);
return crate::model::PrepareSendRequest { return crate::model::PrepareSendRequest {
destination: var_destination, destination: var_destination,
amount_sat: var_amountSat, amount: var_amount,
}; };
} }
} }
@@ -5169,27 +5180,22 @@ impl flutter_rust_bridge::IntoIntoDart<crate::model::OnchainPaymentLimitsRespons
} }
} }
// Codec=Dco (DartCObject based), see doc to use other codecs // Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::PayOnchainAmount { impl flutter_rust_bridge::IntoDart for crate::model::PayAmount {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
match self { match self {
crate::model::PayOnchainAmount::Receiver { amount_sat } => { crate::model::PayAmount::Receiver { amount_sat } => {
[0.into_dart(), amount_sat.into_into_dart().into_dart()].into_dart() [0.into_dart(), amount_sat.into_into_dart().into_dart()].into_dart()
} }
crate::model::PayOnchainAmount::Drain => [1.into_dart()].into_dart(), crate::model::PayAmount::Drain => [1.into_dart()].into_dart(),
_ => { _ => {
unimplemented!(""); unimplemented!("");
} }
} }
} }
} }
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::model::PayAmount {}
for crate::model::PayOnchainAmount impl flutter_rust_bridge::IntoIntoDart<crate::model::PayAmount> for crate::model::PayAmount {
{ fn into_into_dart(self) -> crate::model::PayAmount {
}
impl flutter_rust_bridge::IntoIntoDart<crate::model::PayOnchainAmount>
for crate::model::PayOnchainAmount
{
fn into_into_dart(self) -> crate::model::PayOnchainAmount {
self self
} }
} }
@@ -5636,7 +5642,7 @@ impl flutter_rust_bridge::IntoDart for crate::model::PrepareSendRequest {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi { fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[ [
self.destination.into_into_dart().into_dart(), self.destination.into_into_dart().into_dart(),
self.amount_sat.into_into_dart().into_dart(), self.amount.into_into_dart().into_dart(),
] ]
.into_dart() .into_dart()
} }
@@ -6979,6 +6985,16 @@ impl SseEncode for Option<crate::model::ListPaymentDetails> {
} }
} }
impl SseEncode for Option<crate::model::PayAmount> {
// 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 {
<crate::model::PayAmount>::sse_encode(value, serializer);
}
}
}
impl SseEncode for Option<crate::model::Payment> { impl SseEncode for Option<crate::model::Payment> {
// 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) {
@@ -7049,15 +7065,15 @@ impl SseEncode for Option<Vec<crate::model::PaymentType>> {
} }
} }
impl SseEncode for crate::model::PayOnchainAmount { impl SseEncode for crate::model::PayAmount {
// 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) {
match self { match self {
crate::model::PayOnchainAmount::Receiver { amount_sat } => { crate::model::PayAmount::Receiver { amount_sat } => {
<i32>::sse_encode(0, serializer); <i32>::sse_encode(0, serializer);
<u64>::sse_encode(amount_sat, serializer); <u64>::sse_encode(amount_sat, serializer);
} }
crate::model::PayOnchainAmount::Drain => { crate::model::PayAmount::Drain => {
<i32>::sse_encode(1, serializer); <i32>::sse_encode(1, serializer);
} }
_ => { _ => {
@@ -7316,7 +7332,7 @@ impl SseEncode for crate::model::PrepareLnUrlPayResponse {
impl SseEncode for crate::model::PreparePayOnchainRequest { impl SseEncode for crate::model::PreparePayOnchainRequest {
// 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) {
<crate::model::PayOnchainAmount>::sse_encode(self.amount, serializer); <crate::model::PayAmount>::sse_encode(self.amount, serializer);
<Option<u32>>::sse_encode(self.fee_rate_sat_per_vbyte, serializer); <Option<u32>>::sse_encode(self.fee_rate_sat_per_vbyte, serializer);
} }
} }
@@ -7369,7 +7385,7 @@ impl SseEncode for crate::model::PrepareSendRequest {
// 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) {
<String>::sse_encode(self.destination, serializer); <String>::sse_encode(self.destination, serializer);
<Option<u64>>::sse_encode(self.amount_sat, serializer); <Option<crate::model::PayAmount>>::sse_encode(self.amount, serializer);
} }
} }
@@ -8036,6 +8052,13 @@ mod io {
CstDecode::<crate::bindings::MessageSuccessActionData>::cst_decode(*wrap).into() CstDecode::<crate::bindings::MessageSuccessActionData>::cst_decode(*wrap).into()
} }
} }
impl CstDecode<crate::model::PayAmount> for *mut wire_cst_pay_amount {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::PayAmount {
let wrap = unsafe { flutter_rust_bridge::for_generated::box_from_leak_ptr(self) };
CstDecode::<crate::model::PayAmount>::cst_decode(*wrap).into()
}
}
impl CstDecode<crate::model::PayOnchainRequest> for *mut wire_cst_pay_onchain_request { impl CstDecode<crate::model::PayOnchainRequest> for *mut wire_cst_pay_onchain_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::PayOnchainRequest { fn cst_decode(self) -> crate::model::PayOnchainRequest {
@@ -8884,17 +8907,17 @@ mod io {
} }
} }
} }
impl CstDecode<crate::model::PayOnchainAmount> for wire_cst_pay_onchain_amount { impl CstDecode<crate::model::PayAmount> for wire_cst_pay_amount {
// 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::PayOnchainAmount { fn cst_decode(self) -> crate::model::PayAmount {
match self.tag { match self.tag {
0 => { 0 => {
let ans = unsafe { self.kind.Receiver }; let ans = unsafe { self.kind.Receiver };
crate::model::PayOnchainAmount::Receiver { crate::model::PayAmount::Receiver {
amount_sat: ans.amount_sat.cst_decode(), amount_sat: ans.amount_sat.cst_decode(),
} }
} }
1 => crate::model::PayOnchainAmount::Drain, 1 => crate::model::PayAmount::Drain,
_ => unreachable!(), _ => unreachable!(),
} }
} }
@@ -9142,7 +9165,7 @@ mod io {
fn cst_decode(self) -> crate::model::PrepareSendRequest { fn cst_decode(self) -> crate::model::PrepareSendRequest {
crate::model::PrepareSendRequest { crate::model::PrepareSendRequest {
destination: self.destination.cst_decode(), destination: self.destination.cst_decode(),
amount_sat: self.amount_sat.cst_decode(), amount: self.amount.cst_decode(),
} }
} }
} }
@@ -10036,15 +10059,15 @@ mod io {
Self::new_with_null_ptr() Self::new_with_null_ptr()
} }
} }
impl NewWithNullPtr for wire_cst_pay_onchain_amount { impl NewWithNullPtr for wire_cst_pay_amount {
fn new_with_null_ptr() -> Self { fn new_with_null_ptr() -> Self {
Self { Self {
tag: -1, tag: -1,
kind: PayOnchainAmountKind { nil__: () }, kind: PayAmountKind { nil__: () },
} }
} }
} }
impl Default for wire_cst_pay_onchain_amount { impl Default for wire_cst_pay_amount {
fn default() -> Self { fn default() -> Self {
Self::new_with_null_ptr() Self::new_with_null_ptr()
} }
@@ -10249,7 +10272,7 @@ mod io {
fn new_with_null_ptr() -> Self { fn new_with_null_ptr() -> Self {
Self { Self {
destination: core::ptr::null_mut(), destination: core::ptr::null_mut(),
amount_sat: core::ptr::null_mut(), amount: core::ptr::null_mut(),
} }
} }
} }
@@ -11108,6 +11131,14 @@ mod io {
) )
} }
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_pay_amount(
) -> *mut wire_cst_pay_amount {
flutter_rust_bridge::for_generated::new_leak_box_ptr(
wire_cst_pay_amount::new_with_null_ptr(),
)
}
#[no_mangle] #[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_pay_onchain_request( pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_pay_onchain_request(
) -> *mut wire_cst_pay_onchain_request { ) -> *mut wire_cst_pay_onchain_request {
@@ -12042,19 +12073,19 @@ mod io {
} }
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct wire_cst_pay_onchain_amount { pub struct wire_cst_pay_amount {
tag: i32, tag: i32,
kind: PayOnchainAmountKind, kind: PayAmountKind,
} }
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub union PayOnchainAmountKind { pub union PayAmountKind {
Receiver: wire_cst_PayOnchainAmount_Receiver, Receiver: wire_cst_PayAmount_Receiver,
nil__: (), nil__: (),
} }
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct wire_cst_PayOnchainAmount_Receiver { pub struct wire_cst_PayAmount_Receiver {
amount_sat: u64, amount_sat: u64,
} }
#[repr(C)] #[repr(C)]
@@ -12217,7 +12248,7 @@ mod io {
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct wire_cst_prepare_pay_onchain_request { pub struct wire_cst_prepare_pay_onchain_request {
amount: wire_cst_pay_onchain_amount, amount: wire_cst_pay_amount,
fee_rate_sat_per_vbyte: *mut u32, fee_rate_sat_per_vbyte: *mut u32,
} }
#[repr(C)] #[repr(C)]
@@ -12258,7 +12289,7 @@ mod io {
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct wire_cst_prepare_send_request { pub struct wire_cst_prepare_send_request {
destination: *mut wire_cst_list_prim_u_8_strict, destination: *mut wire_cst_list_prim_u_8_strict,
amount_sat: *mut u64, amount: *mut wire_cst_pay_amount,
} }
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Clone, Copy)]

View File

@@ -100,9 +100,9 @@ impl Config {
.unwrap_or(DEFAULT_ZERO_CONF_MAX_SAT) .unwrap_or(DEFAULT_ZERO_CONF_MAX_SAT)
} }
pub(crate) fn lowball_fee_rate_msat_per_vbyte(&self) -> Option<f64> { pub(crate) fn lowball_fee_rate_msat_per_vbyte(&self) -> Option<f32> {
match self.network { match self.network {
LiquidNetwork::Mainnet => Some(LOWBALL_FEE_RATE_SAT_PER_VBYTE * 1000.0), LiquidNetwork::Mainnet => Some((LOWBALL_FEE_RATE_SAT_PER_VBYTE * 1000.0) as f32),
LiquidNetwork::Testnet => None, LiquidNetwork::Testnet => None,
} }
} }
@@ -349,8 +349,8 @@ pub struct PrepareSendRequest {
pub destination: String, pub destination: String,
/// Should only be set when paying directly onchain or to a BIP21 URI /// Should only be set when paying directly onchain or to a BIP21 URI
/// where no amount is specified /// where no amount is specified, or when the caller wishes to drain
pub amount_sat: Option<u64>, pub amount: Option<PayAmount>,
} }
/// Specifies the supported destinations which can be payed by the SDK /// Specifies the supported destinations which can be payed by the SDK
@@ -384,7 +384,7 @@ pub struct SendPaymentResponse {
} }
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
pub enum PayOnchainAmount { pub enum PayAmount {
/// The amount in satoshi that will be received /// The amount in satoshi that will be received
Receiver { amount_sat: u64 }, Receiver { amount_sat: u64 },
/// Indicates that all available funds should be sent /// Indicates that all available funds should be sent
@@ -394,7 +394,7 @@ pub enum PayOnchainAmount {
/// An argument when calling [crate::sdk::LiquidSdk::prepare_pay_onchain]. /// An argument when calling [crate::sdk::LiquidSdk::prepare_pay_onchain].
#[derive(Debug, Serialize, Clone)] #[derive(Debug, Serialize, Clone)]
pub struct PreparePayOnchainRequest { pub struct PreparePayOnchainRequest {
pub amount: PayOnchainAmount, pub amount: PayAmount,
/// The optional fee rate of the Bitcoin claim transaction in sat/vB. Defaults to the swapper estimated claim fee. /// The optional fee rate of the Bitcoin claim transaction in sat/vB. Defaults to the swapper estimated claim fee.
pub fee_rate_sat_per_vbyte: Option<u32>, pub fee_rate_sat_per_vbyte: Option<u32>,
} }

View File

@@ -643,10 +643,7 @@ impl LiquidSdk {
amount_sat: u64, amount_sat: u64,
address: &str, address: &str,
) -> Result<u64, PaymentError> { ) -> Result<u64, PaymentError> {
let fee_rate_msat_per_vbyte = self let fee_rate_msat_per_vbyte = self.config.lowball_fee_rate_msat_per_vbyte();
.config
.lowball_fee_rate_msat_per_vbyte()
.map(|v| v as f32);
Ok(self Ok(self
.onchain_wallet .onchain_wallet
.build_tx(fee_rate_msat_per_vbyte, address, amount_sat) .build_tx(fee_rate_msat_per_vbyte, address, amount_sat)
@@ -665,34 +662,30 @@ impl LiquidSdk {
} }
} }
/// Estimate the lockup tx fee for Send swaps /// Estimate the lockup tx fee for Send and Chain Send swaps
async fn estimate_lockup_tx_fee_send( async fn estimate_lockup_tx_fee(
&self, &self,
user_lockup_amount_sat: u64, user_lockup_amount_sat: u64,
) -> Result<u64, PaymentError> { ) -> Result<u64, PaymentError> {
let temp_p2tr_addr = self.get_temp_p2tr_addr(); let temp_p2tr_addr = self.get_temp_p2tr_addr();
self.estimate_onchain_tx_fee(user_lockup_amount_sat, temp_p2tr_addr) self.estimate_onchain_tx_fee(user_lockup_amount_sat, temp_p2tr_addr)
.await .await
} }
/// Estimate the lockup tx fee for Chain Send swaps async fn estimate_drain_tx_fee(
async fn estimate_lockup_tx_fee_chain_send(
&self, &self,
user_lockup_amount_sat: u64, enforce_amount_sat: Option<u64>,
address: Option<&str>,
) -> Result<u64, PaymentError> { ) -> Result<u64, PaymentError> {
let temp_p2tr_addr = self.get_temp_p2tr_addr(); let receipent_address = address.unwrap_or(self.get_temp_p2tr_addr());
let fee_rate_msat_per_vbyte = self.config.lowball_fee_rate_msat_per_vbyte();
self.estimate_onchain_tx_fee(user_lockup_amount_sat, temp_p2tr_addr)
.await
}
async fn estimate_drain_tx_fee(&self) -> Result<u64, PaymentError> {
let temp_p2tr_addr = self.get_temp_p2tr_addr();
let fee_sat = self let fee_sat = self
.onchain_wallet .onchain_wallet
.build_drain_tx(None, temp_p2tr_addr, None) .build_drain_tx(
fee_rate_msat_per_vbyte,
receipent_address,
enforce_amount_sat,
)
.await? .await?
.all_fees() .all_fees()
.values() .values()
@@ -702,13 +695,40 @@ impl LiquidSdk {
Ok(fee_sat) Ok(fee_sat)
} }
async fn estimate_onchain_tx_or_drain_tx_fee(
&self,
amount_sat: u64,
address: &str,
) -> Result<u64, PaymentError> {
match self.estimate_onchain_tx_fee(amount_sat, address).await {
Ok(fees_sat) => Ok(fees_sat),
Err(PaymentError::InsufficientFunds) => self
.estimate_drain_tx_fee(Some(amount_sat), Some(address))
.await
.map_err(|_| PaymentError::InsufficientFunds),
Err(e) => Err(e),
}
}
async fn estimate_lockup_tx_or_drain_tx_fee(
&self,
amount_sat: u64,
) -> Result<u64, PaymentError> {
let temp_p2tr_addr = self.get_temp_p2tr_addr();
self.estimate_onchain_tx_or_drain_tx_fee(amount_sat, temp_p2tr_addr)
.await
}
/// Prepares to pay a Lightning invoice via a submarine swap. /// Prepares to pay a Lightning invoice via a submarine swap.
/// ///
/// # Arguments /// # Arguments
/// ///
/// * `req` - the [PrepareSendRequest] containing: /// * `req` - the [PrepareSendRequest] containing:
/// * `destination` - Either a Liquid BIP21 URI/address or a BOLT11 invoice /// * `destination` - Either a Liquid BIP21 URI/address or a BOLT11 invoice
/// * `amount_sat` - Should only be specified when paying directly onchain or via amount-less BIP21 /// * `amount` - The optional amount of type [PayAmount]. Should only be specified
/// when paying directly onchain or via amount-less BIP21.
/// - [PayAmount::Drain] which uses all funds
/// - [PayAmount::Receiver] which sets the amount the receiver should receive
/// ///
/// # Returns /// # Returns
/// Returns a [PrepareSendResponse] containing: /// Returns a [PrepareSendResponse] containing:
@@ -720,6 +740,7 @@ impl LiquidSdk {
) -> Result<PrepareSendResponse, PaymentError> { ) -> Result<PrepareSendResponse, PaymentError> {
self.ensure_is_started().await?; self.ensure_is_started().await?;
let get_info_res = self.get_info().await?;
let fees_sat; let fees_sat;
let receiver_amount_sat; let receiver_amount_sat;
let payment_destination; let payment_destination;
@@ -728,12 +749,16 @@ impl LiquidSdk {
InputType::LiquidAddress { InputType::LiquidAddress {
address: mut liquid_address_data, address: mut liquid_address_data,
} => { } => {
let amount_sat = match (liquid_address_data.amount_sat, req.amount_sat) { let amount = match (liquid_address_data.amount_sat, req.amount.clone()) {
(None, None) => { (None, None) => {
return Err(PaymentError::AmountMissing { err: "`amount_sat` must be present when paying to a `SendDestination::LiquidAddress`".to_string() }); return Err(PaymentError::AmountMissing {
err: "Amount must be set when paying to a Liquid address".to_string(),
});
} }
(Some(bip21_amount_sat), None) => bip21_amount_sat, (Some(bip21_amount_sat), None) => PayAmount::Receiver {
(_, Some(request_amount_sat)) => request_amount_sat, amount_sat: bip21_amount_sat,
},
(_, Some(amount)) => amount,
}; };
ensure_sdk!( ensure_sdk!(
@@ -747,10 +772,32 @@ impl LiquidSdk {
} }
); );
receiver_amount_sat = amount_sat; (receiver_amount_sat, fees_sat) = match amount {
fees_sat = self PayAmount::Drain => {
.estimate_onchain_tx_fee(receiver_amount_sat, &liquid_address_data.address) ensure_sdk!(
.await?; get_info_res.pending_receive_sat == 0
&& get_info_res.pending_send_sat == 0,
PaymentError::Generic {
err: "Cannot drain while there are pending payments".to_string(),
}
);
let drain_fees_sat = self
.estimate_drain_tx_fee(None, Some(&liquid_address_data.address))
.await?;
let drain_amount_sat = get_info_res.balance_sat - drain_fees_sat;
info!("Drain amount: {drain_amount_sat} sat");
(drain_amount_sat, drain_fees_sat)
}
PayAmount::Receiver { amount_sat } => {
let fees_sat = self
.estimate_onchain_tx_or_drain_tx_fee(
amount_sat,
&liquid_address_data.address,
)
.await?;
(amount_sat, fees_sat)
}
};
liquid_address_data.amount_sat = Some(receiver_amount_sat); liquid_address_data.amount_sat = Some(receiver_amount_sat);
payment_destination = SendDestination::LiquidAddress { payment_destination = SendDestination::LiquidAddress {
@@ -765,10 +812,12 @@ impl LiquidSdk {
err: "Expected invoice with an amount".to_string(), err: "Expected invoice with an amount".to_string(),
})? / 1000; })? / 1000;
if let Some(amount_sat) = req.amount_sat { if let Some(PayAmount::Receiver { amount_sat }) = req.amount {
ensure_sdk!( ensure_sdk!(
receiver_amount_sat == amount_sat, receiver_amount_sat == amount_sat,
PaymentError::Generic { err: "Amount in the payment request is not the same as the one in the invoice".to_string() } PaymentError::Generic {
err: "Receiver amount and invoice amount do not match".to_string()
}
); );
} }
@@ -776,13 +825,14 @@ impl LiquidSdk {
fees_sat = match self.swapper.check_for_mrh(&invoice.bolt11)? { fees_sat = match self.swapper.check_for_mrh(&invoice.bolt11)? {
Some((lbtc_address, _)) => { Some((lbtc_address, _)) => {
self.estimate_onchain_tx_fee(receiver_amount_sat, &lbtc_address) self.estimate_onchain_tx_or_drain_tx_fee(receiver_amount_sat, &lbtc_address)
.await? .await?
} }
None => { None => {
let boltz_fees_total = lbtc_pair.fees.total(receiver_amount_sat); let boltz_fees_total = lbtc_pair.fees.total(receiver_amount_sat);
let user_lockup_amount_sat = receiver_amount_sat + boltz_fees_total;
let lockup_fees_sat = self let lockup_fees_sat = self
.estimate_lockup_tx_fee_send(receiver_amount_sat + boltz_fees_total) .estimate_lockup_tx_or_drain_tx_fee(user_lockup_amount_sat)
.await?; .await?;
boltz_fees_total + lockup_fees_sat boltz_fees_total + lockup_fees_sat
} }
@@ -798,7 +848,7 @@ impl LiquidSdk {
let payer_amount_sat = receiver_amount_sat + fees_sat; let payer_amount_sat = receiver_amount_sat + fees_sat;
ensure_sdk!( ensure_sdk!(
payer_amount_sat <= self.get_info().await?.balance_sat, payer_amount_sat <= get_info_res.balance_sat,
PaymentError::InsufficientFunds PaymentError::InsufficientFunds
); );
@@ -923,10 +973,8 @@ impl LiquidSdk {
) -> Result<SendPaymentResponse, PaymentError> { ) -> Result<SendPaymentResponse, PaymentError> {
let tx = self let tx = self
.onchain_wallet .onchain_wallet
.build_tx( .build_tx_or_drain_tx(
self.config self.config.lowball_fee_rate_msat_per_vbyte(),
.lowball_fee_rate_msat_per_vbyte()
.map(|v| v as f32),
&address_data.address, &address_data.address,
receiver_amount_sat, receiver_amount_sat,
) )
@@ -994,8 +1042,9 @@ impl LiquidSdk {
let lbtc_pair = self.validate_submarine_pairs(receiver_amount_sat)?; let lbtc_pair = self.validate_submarine_pairs(receiver_amount_sat)?;
let boltz_fees_total = lbtc_pair.fees.total(receiver_amount_sat); let boltz_fees_total = lbtc_pair.fees.total(receiver_amount_sat);
let user_lockup_amount_sat = receiver_amount_sat + boltz_fees_total;
let lockup_tx_fees_sat = self let lockup_tx_fees_sat = self
.estimate_lockup_tx_fee_send(receiver_amount_sat + boltz_fees_total) .estimate_lockup_tx_or_drain_tx_fee(user_lockup_amount_sat)
.await?; .await?;
ensure_sdk!( ensure_sdk!(
fees_sat == boltz_fees_total + lockup_tx_fees_sat, fees_sat == boltz_fees_total + lockup_tx_fees_sat,
@@ -1149,8 +1198,8 @@ impl LiquidSdk {
/// # Arguments /// # Arguments
/// ///
/// * `req` - the [PreparePayOnchainRequest] containing: /// * `req` - the [PreparePayOnchainRequest] containing:
/// * `amount` - which can be of two types: [PayOnchainAmount::Drain], which uses all funds, /// * `amount` - which can be of two types: [PayAmount::Drain], which uses all funds,
/// and [PayOnchainAmount::Receiver], which sets the amount the receiver should receive /// and [PayAmount::Receiver], which sets the amount the receiver should receive
/// * `fee_rate_sat_per_vbyte` - the optional fee rate of the Bitcoin claim transaction. Defaults to the swapper estimated claim fee /// * `fee_rate_sat_per_vbyte` - the optional fee rate of the Bitcoin claim transaction. Defaults to the swapper estimated claim fee
pub async fn prepare_pay_onchain( pub async fn prepare_pay_onchain(
&self, &self,
@@ -1158,7 +1207,7 @@ impl LiquidSdk {
) -> Result<PreparePayOnchainResponse, PaymentError> { ) -> Result<PreparePayOnchainResponse, PaymentError> {
self.ensure_is_started().await?; self.ensure_is_started().await?;
let balance_sat = self.get_info().await?.balance_sat; let get_info_res = self.get_info().await?;
let pair = self.get_chain_pair(Direction::Outgoing)?; let pair = self.get_chain_pair(Direction::Outgoing)?;
let claim_fees_sat = match req.fee_rate_sat_per_vbyte { let claim_fees_sat = match req.fee_rate_sat_per_vbyte {
Some(sat_per_vbyte) => ESTIMATED_BTC_CLAIM_TX_VSIZE * sat_per_vbyte as u64, Some(sat_per_vbyte) => ESTIMATED_BTC_CLAIM_TX_VSIZE * sat_per_vbyte as u64,
@@ -1168,7 +1217,7 @@ impl LiquidSdk {
info!("Preparing for onchain payment of kind: {:?}", req.amount); info!("Preparing for onchain payment of kind: {:?}", req.amount);
let (payer_amount_sat, receiver_amount_sat, total_fees_sat) = match req.amount { let (payer_amount_sat, receiver_amount_sat, total_fees_sat) = match req.amount {
PayOnchainAmount::Receiver { amount_sat } => { PayAmount::Receiver { amount_sat } => {
let receiver_amount_sat = amount_sat; let receiver_amount_sat = amount_sat;
let user_lockup_amount_sat_without_service_fee = let user_lockup_amount_sat_without_service_fee =
@@ -1182,9 +1231,7 @@ impl LiquidSdk {
.ceil() as u64; .ceil() as u64;
self.validate_user_lockup_amount_for_chain_pair(&pair, user_lockup_amount_sat)?; self.validate_user_lockup_amount_for_chain_pair(&pair, user_lockup_amount_sat)?;
let lockup_fees_sat = self let lockup_fees_sat = self.estimate_lockup_tx_fee(user_lockup_amount_sat).await?;
.estimate_lockup_tx_fee_chain_send(user_lockup_amount_sat)
.await?;
let boltz_fees_sat = let boltz_fees_sat =
user_lockup_amount_sat - user_lockup_amount_sat_without_service_fee; user_lockup_amount_sat - user_lockup_amount_sat_without_service_fee;
@@ -1194,9 +1241,15 @@ impl LiquidSdk {
(payer_amount_sat, receiver_amount_sat, total_fees_sat) (payer_amount_sat, receiver_amount_sat, total_fees_sat)
} }
PayOnchainAmount::Drain => { PayAmount::Drain => {
let payer_amount_sat = balance_sat; ensure_sdk!(
let lockup_fees_sat = self.estimate_drain_tx_fee().await?; get_info_res.pending_receive_sat == 0 && get_info_res.pending_send_sat == 0,
PaymentError::Generic {
err: "Cannot drain while there are pending payments".to_string(),
}
);
let payer_amount_sat = get_info_res.balance_sat;
let lockup_fees_sat = self.estimate_drain_tx_fee(None, None).await?;
let user_lockup_amount_sat = payer_amount_sat - lockup_fees_sat; let user_lockup_amount_sat = payer_amount_sat - lockup_fees_sat;
self.validate_user_lockup_amount_for_chain_pair(&pair, user_lockup_amount_sat)?; self.validate_user_lockup_amount_for_chain_pair(&pair, user_lockup_amount_sat)?;
@@ -1217,7 +1270,7 @@ impl LiquidSdk {
}; };
ensure_sdk!( ensure_sdk!(
payer_amount_sat <= balance_sat, payer_amount_sat <= get_info_res.balance_sat,
PaymentError::InsufficientFunds PaymentError::InsufficientFunds
); );
@@ -1269,11 +1322,8 @@ impl LiquidSdk {
let payer_amount_sat = req.prepare_response.total_fees_sat + receiver_amount_sat; let payer_amount_sat = req.prepare_response.total_fees_sat + receiver_amount_sat;
let lockup_fees_sat = match payer_amount_sat == balance_sat { let lockup_fees_sat = match payer_amount_sat == balance_sat {
true => self.estimate_drain_tx_fee().await?, true => self.estimate_drain_tx_fee(None, None).await?,
false => { false => self.estimate_lockup_tx_fee(user_lockup_amount_sat).await?,
self.estimate_lockup_tx_fee_chain_send(user_lockup_amount_sat)
.await?
}
}; };
ensure_sdk!( ensure_sdk!(
@@ -2247,7 +2297,7 @@ impl LiquidSdk {
let prepare_response = self let prepare_response = self
.prepare_send_payment(&PrepareSendRequest { .prepare_send_payment(&PrepareSendRequest {
destination: data.pr.clone(), destination: data.pr.clone(),
amount_sat: None, amount: None,
}) })
.await .await
.map_err(|e| LnUrlPayError::Generic { err: e.to_string() })?; .map_err(|e| LnUrlPayError::Generic { err: e.to_string() })?;

View File

@@ -190,10 +190,8 @@ impl SendSwapHandler {
let lockup_tx = self let lockup_tx = self
.onchain_wallet .onchain_wallet
.build_tx( .build_tx_or_drain_tx(
self.config self.config.lowball_fee_rate_msat_per_vbyte(),
.lowball_fee_rate_msat_per_vbyte()
.map(|v| v as f32),
&create_response.address, &create_response.address,
create_response.expected_amount, create_response.expected_amount,
) )

View File

@@ -53,6 +53,15 @@ impl OnchainWallet for MockWallet {
Ok(TEST_LIQUID_TX.clone()) Ok(TEST_LIQUID_TX.clone())
} }
async fn build_tx_or_drain_tx(
&self,
_fee_rate_sats_per_kvb: Option<f32>,
_recipient_address: &str,
_amount_sat: u64,
) -> Result<Transaction, PaymentError> {
Ok(TEST_LIQUID_TX.clone())
}
async fn next_unused_address(&self) -> Result<Address, PaymentError> { async fn next_unused_address(&self) -> Result<Address, PaymentError> {
Ok(TEST_P2TR_ADDR.clone()) Ok(TEST_P2TR_ADDR.clone())
} }

View File

@@ -4,7 +4,7 @@ use std::{str::FromStr, sync::Arc};
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};
use async_trait::async_trait; use async_trait::async_trait;
use boltz_client::ElementsAddress; use boltz_client::ElementsAddress;
use log::debug; use log::{debug, warn};
use lwk_common::Signer as LwkSigner; use lwk_common::Signer as LwkSigner;
use lwk_common::{singlesig_desc, Singlesig}; use lwk_common::{singlesig_desc, Singlesig};
use lwk_wollet::{ use lwk_wollet::{
@@ -56,6 +56,16 @@ pub trait OnchainWallet: Send + Sync {
enforce_amount_sat: Option<u64>, enforce_amount_sat: Option<u64>,
) -> Result<Transaction, PaymentError>; ) -> Result<Transaction, PaymentError>;
/// Build a transaction to send funds to a recipient. If building a transaction
/// results in an InsufficientFunds error, attempt to build a drain transaction
/// validating that the `amount_sat` matches the drain output.
async fn build_tx_or_drain_tx(
&self,
fee_rate_sats_per_kvb: Option<f32>,
recipient_address: &str,
amount_sat: u64,
) -> Result<Transaction, PaymentError>;
/// Get the next unused address in the wallet /// Get the next unused address in the wallet
async fn next_unused_address(&self) -> Result<Address, PaymentError>; async fn next_unused_address(&self) -> Result<Address, PaymentError>;
@@ -209,6 +219,26 @@ impl OnchainWallet for LiquidOnchainWallet {
Ok(lwk_wollet.finalize(&mut pset)?) Ok(lwk_wollet.finalize(&mut pset)?)
} }
async fn build_tx_or_drain_tx(
&self,
fee_rate_sats_per_kvb: Option<f32>,
recipient_address: &str,
amount_sat: u64,
) -> Result<Transaction, PaymentError> {
match self
.build_tx(fee_rate_sats_per_kvb, recipient_address, amount_sat)
.await
{
Ok(tx) => Ok(tx),
Err(PaymentError::InsufficientFunds) => {
warn!("Cannot build tx due to insufficient funds, attempting to build drain tx");
self.build_drain_tx(fee_rate_sats_per_kvb, recipient_address, Some(amount_sat))
.await
}
Err(e) => Err(e),
}
}
/// Get the next unused address in the wallet /// Get the next unused address in the wallet
async fn next_unused_address(&self) -> Result<Address, PaymentError> { async fn next_unused_address(&self) -> Result<Address, PaymentError> {
let tip = self.tip().await.height(); let tip = self.tip().await.height();

View File

@@ -1483,6 +1483,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return dco_decode_message_success_action_data(raw); return dco_decode_message_success_action_data(raw);
} }
@protected
PayAmount dco_decode_box_autoadd_pay_amount(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return dco_decode_pay_amount(raw);
}
@protected @protected
PayOnchainRequest dco_decode_box_autoadd_pay_onchain_request(dynamic raw) { PayOnchainRequest dco_decode_box_autoadd_pay_onchain_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs // Codec=Dco (DartCObject based), see doc to use other codecs
@@ -2305,6 +2311,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return raw == null ? null : dco_decode_box_autoadd_list_payment_details(raw); return raw == null ? null : dco_decode_box_autoadd_list_payment_details(raw);
} }
@protected
PayAmount? dco_decode_opt_box_autoadd_pay_amount(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return raw == null ? null : dco_decode_box_autoadd_pay_amount(raw);
}
@protected @protected
Payment? dco_decode_opt_box_autoadd_payment(dynamic raw) { Payment? dco_decode_opt_box_autoadd_payment(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs // Codec=Dco (DartCObject based), see doc to use other codecs
@@ -2348,15 +2360,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
} }
@protected @protected
PayOnchainAmount dco_decode_pay_onchain_amount(dynamic raw) { PayAmount dco_decode_pay_amount(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs // Codec=Dco (DartCObject based), see doc to use other codecs
switch (raw[0]) { switch (raw[0]) {
case 0: case 0:
return PayOnchainAmount_Receiver( return PayAmount_Receiver(
amountSat: dco_decode_u_64(raw[1]), amountSat: dco_decode_u_64(raw[1]),
); );
case 1: case 1:
return PayOnchainAmount_Drain(); return PayAmount_Drain();
default: default:
throw Exception("unreachable"); throw Exception("unreachable");
} }
@@ -2565,7 +2577,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
final arr = raw as List<dynamic>; final arr = raw as List<dynamic>;
if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}'); if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}');
return PreparePayOnchainRequest( return PreparePayOnchainRequest(
amount: dco_decode_pay_onchain_amount(arr[0]), amount: dco_decode_pay_amount(arr[0]),
feeRateSatPerVbyte: dco_decode_opt_box_autoadd_u_32(arr[1]), feeRateSatPerVbyte: dco_decode_opt_box_autoadd_u_32(arr[1]),
); );
} }
@@ -2636,7 +2648,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}'); if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}');
return PrepareSendRequest( return PrepareSendRequest(
destination: dco_decode_String(arr[0]), destination: dco_decode_String(arr[0]),
amountSat: dco_decode_opt_box_autoadd_u_64(arr[1]), amount: dco_decode_opt_box_autoadd_pay_amount(arr[1]),
); );
} }
@@ -3264,6 +3276,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return (sse_decode_message_success_action_data(deserializer)); return (sse_decode_message_success_action_data(deserializer));
} }
@protected
PayAmount sse_decode_box_autoadd_pay_amount(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
return (sse_decode_pay_amount(deserializer));
}
@protected @protected
PayOnchainRequest sse_decode_box_autoadd_pay_onchain_request(SseDeserializer deserializer) { PayOnchainRequest sse_decode_box_autoadd_pay_onchain_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs // Codec=Sse (Serialization based), see doc to use other codecs
@@ -4121,6 +4139,17 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
} }
} }
@protected
PayAmount? sse_decode_opt_box_autoadd_pay_amount(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
if (sse_decode_bool(deserializer)) {
return (sse_decode_box_autoadd_pay_amount(deserializer));
} else {
return null;
}
}
@protected @protected
Payment? sse_decode_opt_box_autoadd_payment(SseDeserializer deserializer) { Payment? sse_decode_opt_box_autoadd_payment(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs // Codec=Sse (Serialization based), see doc to use other codecs
@@ -4199,16 +4228,16 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
} }
@protected @protected
PayOnchainAmount sse_decode_pay_onchain_amount(SseDeserializer deserializer) { PayAmount sse_decode_pay_amount(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs // Codec=Sse (Serialization based), see doc to use other codecs
var tag_ = sse_decode_i_32(deserializer); var tag_ = sse_decode_i_32(deserializer);
switch (tag_) { switch (tag_) {
case 0: case 0:
var var_amountSat = sse_decode_u_64(deserializer); var var_amountSat = sse_decode_u_64(deserializer);
return PayOnchainAmount_Receiver(amountSat: var_amountSat); return PayAmount_Receiver(amountSat: var_amountSat);
case 1: case 1:
return PayOnchainAmount_Drain(); return PayAmount_Drain();
default: default:
throw UnimplementedError(''); throw UnimplementedError('');
} }
@@ -4414,7 +4443,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
@protected @protected
PreparePayOnchainRequest sse_decode_prepare_pay_onchain_request(SseDeserializer deserializer) { PreparePayOnchainRequest sse_decode_prepare_pay_onchain_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs // Codec=Sse (Serialization based), see doc to use other codecs
var var_amount = sse_decode_pay_onchain_amount(deserializer); var var_amount = sse_decode_pay_amount(deserializer);
var var_feeRateSatPerVbyte = sse_decode_opt_box_autoadd_u_32(deserializer); var var_feeRateSatPerVbyte = sse_decode_opt_box_autoadd_u_32(deserializer);
return PreparePayOnchainRequest(amount: var_amount, feeRateSatPerVbyte: var_feeRateSatPerVbyte); return PreparePayOnchainRequest(amount: var_amount, feeRateSatPerVbyte: var_feeRateSatPerVbyte);
} }
@@ -4474,8 +4503,8 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
PrepareSendRequest sse_decode_prepare_send_request(SseDeserializer deserializer) { PrepareSendRequest sse_decode_prepare_send_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs // Codec=Sse (Serialization based), see doc to use other codecs
var var_destination = sse_decode_String(deserializer); var var_destination = sse_decode_String(deserializer);
var var_amountSat = sse_decode_opt_box_autoadd_u_64(deserializer); var var_amount = sse_decode_opt_box_autoadd_pay_amount(deserializer);
return PrepareSendRequest(destination: var_destination, amountSat: var_amountSat); return PrepareSendRequest(destination: var_destination, amount: var_amount);
} }
@protected @protected
@@ -5162,6 +5191,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_message_success_action_data(self, serializer); sse_encode_message_success_action_data(self, serializer);
} }
@protected
void sse_encode_box_autoadd_pay_amount(PayAmount self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_pay_amount(self, serializer);
}
@protected @protected
void sse_encode_box_autoadd_pay_onchain_request(PayOnchainRequest self, SseSerializer serializer) { void sse_encode_box_autoadd_pay_onchain_request(PayOnchainRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs // Codec=Sse (Serialization based), see doc to use other codecs
@@ -5887,6 +5922,16 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
} }
} }
@protected
void sse_encode_opt_box_autoadd_pay_amount(PayAmount? 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_pay_amount(self, serializer);
}
}
@protected @protected
void sse_encode_opt_box_autoadd_payment(Payment? self, SseSerializer serializer) { void sse_encode_opt_box_autoadd_payment(Payment? self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs // Codec=Sse (Serialization based), see doc to use other codecs
@@ -5959,13 +6004,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
} }
@protected @protected
void sse_encode_pay_onchain_amount(PayOnchainAmount self, SseSerializer serializer) { void sse_encode_pay_amount(PayAmount self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs // Codec=Sse (Serialization based), see doc to use other codecs
switch (self) { switch (self) {
case PayOnchainAmount_Receiver(amountSat: final amountSat): case PayAmount_Receiver(amountSat: final amountSat):
sse_encode_i_32(0, serializer); sse_encode_i_32(0, serializer);
sse_encode_u_64(amountSat, serializer); sse_encode_u_64(amountSat, serializer);
case PayOnchainAmount_Drain(): case PayAmount_Drain():
sse_encode_i_32(1, serializer); sse_encode_i_32(1, serializer);
default: default:
throw UnimplementedError(''); throw UnimplementedError('');
@@ -6148,7 +6193,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
@protected @protected
void sse_encode_prepare_pay_onchain_request(PreparePayOnchainRequest self, SseSerializer serializer) { void sse_encode_prepare_pay_onchain_request(PreparePayOnchainRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs // Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_pay_onchain_amount(self.amount, serializer); sse_encode_pay_amount(self.amount, serializer);
sse_encode_opt_box_autoadd_u_32(self.feeRateSatPerVbyte, serializer); sse_encode_opt_box_autoadd_u_32(self.feeRateSatPerVbyte, serializer);
} }
@@ -6195,7 +6240,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
void sse_encode_prepare_send_request(PrepareSendRequest self, SseSerializer serializer) { void sse_encode_prepare_send_request(PrepareSendRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs // Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_String(self.destination, serializer); sse_encode_String(self.destination, serializer);
sse_encode_opt_box_autoadd_u_64(self.amountSat, serializer); sse_encode_opt_box_autoadd_pay_amount(self.amount, serializer);
} }
@protected @protected

View File

@@ -149,6 +149,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected @protected
MessageSuccessActionData dco_decode_box_autoadd_message_success_action_data(dynamic raw); MessageSuccessActionData dco_decode_box_autoadd_message_success_action_data(dynamic raw);
@protected
PayAmount dco_decode_box_autoadd_pay_amount(dynamic raw);
@protected @protected
PayOnchainRequest dco_decode_box_autoadd_pay_onchain_request(dynamic raw); PayOnchainRequest dco_decode_box_autoadd_pay_onchain_request(dynamic raw);
@@ -377,6 +380,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected @protected
ListPaymentDetails? dco_decode_opt_box_autoadd_list_payment_details(dynamic raw); ListPaymentDetails? dco_decode_opt_box_autoadd_list_payment_details(dynamic raw);
@protected
PayAmount? dco_decode_opt_box_autoadd_pay_amount(dynamic raw);
@protected @protected
Payment? dco_decode_opt_box_autoadd_payment(dynamic raw); Payment? dco_decode_opt_box_autoadd_payment(dynamic raw);
@@ -399,7 +405,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
List<PaymentType>? dco_decode_opt_list_payment_type(dynamic raw); List<PaymentType>? dco_decode_opt_list_payment_type(dynamic raw);
@protected @protected
PayOnchainAmount dco_decode_pay_onchain_amount(dynamic raw); PayAmount dco_decode_pay_amount(dynamic raw);
@protected @protected
PayOnchainRequest dco_decode_pay_onchain_request(dynamic raw); PayOnchainRequest dco_decode_pay_onchain_request(dynamic raw);
@@ -666,6 +672,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected @protected
MessageSuccessActionData sse_decode_box_autoadd_message_success_action_data(SseDeserializer deserializer); MessageSuccessActionData sse_decode_box_autoadd_message_success_action_data(SseDeserializer deserializer);
@protected
PayAmount sse_decode_box_autoadd_pay_amount(SseDeserializer deserializer);
@protected @protected
PayOnchainRequest sse_decode_box_autoadd_pay_onchain_request(SseDeserializer deserializer); PayOnchainRequest sse_decode_box_autoadd_pay_onchain_request(SseDeserializer deserializer);
@@ -894,6 +903,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected @protected
ListPaymentDetails? sse_decode_opt_box_autoadd_list_payment_details(SseDeserializer deserializer); ListPaymentDetails? sse_decode_opt_box_autoadd_list_payment_details(SseDeserializer deserializer);
@protected
PayAmount? sse_decode_opt_box_autoadd_pay_amount(SseDeserializer deserializer);
@protected @protected
Payment? sse_decode_opt_box_autoadd_payment(SseDeserializer deserializer); Payment? sse_decode_opt_box_autoadd_payment(SseDeserializer deserializer);
@@ -916,7 +928,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
List<PaymentType>? sse_decode_opt_list_payment_type(SseDeserializer deserializer); List<PaymentType>? sse_decode_opt_list_payment_type(SseDeserializer deserializer);
@protected @protected
PayOnchainAmount sse_decode_pay_onchain_amount(SseDeserializer deserializer); PayAmount sse_decode_pay_amount(SseDeserializer deserializer);
@protected @protected
PayOnchainRequest sse_decode_pay_onchain_request(SseDeserializer deserializer); PayOnchainRequest sse_decode_pay_onchain_request(SseDeserializer deserializer);
@@ -1313,6 +1325,14 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
return ptr; return ptr;
} }
@protected
ffi.Pointer<wire_cst_pay_amount> cst_encode_box_autoadd_pay_amount(PayAmount raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
final ptr = wire.cst_new_box_autoadd_pay_amount();
cst_api_fill_to_wire_pay_amount(raw, ptr.ref);
return ptr;
}
@protected @protected
ffi.Pointer<wire_cst_pay_onchain_request> cst_encode_box_autoadd_pay_onchain_request( ffi.Pointer<wire_cst_pay_onchain_request> cst_encode_box_autoadd_pay_onchain_request(
PayOnchainRequest raw) { PayOnchainRequest raw) {
@@ -1610,6 +1630,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
return raw == null ? ffi.nullptr : cst_encode_box_autoadd_list_payment_details(raw); return raw == null ? ffi.nullptr : cst_encode_box_autoadd_list_payment_details(raw);
} }
@protected
ffi.Pointer<wire_cst_pay_amount> cst_encode_opt_box_autoadd_pay_amount(PayAmount? raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
return raw == null ? ffi.nullptr : cst_encode_box_autoadd_pay_amount(raw);
}
@protected @protected
ffi.Pointer<wire_cst_payment> cst_encode_opt_box_autoadd_payment(Payment? raw) { ffi.Pointer<wire_cst_payment> cst_encode_opt_box_autoadd_payment(Payment? raw) {
// Codec=Cst (C-struct based), see doc to use other codecs // Codec=Cst (C-struct based), see doc to use other codecs
@@ -1862,6 +1888,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
cst_api_fill_to_wire_message_success_action_data(apiObj, wireObj.ref); cst_api_fill_to_wire_message_success_action_data(apiObj, wireObj.ref);
} }
@protected
void cst_api_fill_to_wire_box_autoadd_pay_amount(
PayAmount apiObj, ffi.Pointer<wire_cst_pay_amount> wireObj) {
cst_api_fill_to_wire_pay_amount(apiObj, wireObj.ref);
}
@protected @protected
void cst_api_fill_to_wire_box_autoadd_pay_onchain_request( void cst_api_fill_to_wire_box_autoadd_pay_onchain_request(
PayOnchainRequest apiObj, ffi.Pointer<wire_cst_pay_onchain_request> wireObj) { PayOnchainRequest apiObj, ffi.Pointer<wire_cst_pay_onchain_request> wireObj) {
@@ -2472,14 +2504,14 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
} }
@protected @protected
void cst_api_fill_to_wire_pay_onchain_amount(PayOnchainAmount apiObj, wire_cst_pay_onchain_amount wireObj) { void cst_api_fill_to_wire_pay_amount(PayAmount apiObj, wire_cst_pay_amount wireObj) {
if (apiObj is PayOnchainAmount_Receiver) { if (apiObj is PayAmount_Receiver) {
var pre_amount_sat = cst_encode_u_64(apiObj.amountSat); var pre_amount_sat = cst_encode_u_64(apiObj.amountSat);
wireObj.tag = 0; wireObj.tag = 0;
wireObj.kind.Receiver.amount_sat = pre_amount_sat; wireObj.kind.Receiver.amount_sat = pre_amount_sat;
return; return;
} }
if (apiObj is PayOnchainAmount_Drain) { if (apiObj is PayAmount_Drain) {
wireObj.tag = 1; wireObj.tag = 1;
return; return;
} }
@@ -2691,7 +2723,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected @protected
void cst_api_fill_to_wire_prepare_pay_onchain_request( void cst_api_fill_to_wire_prepare_pay_onchain_request(
PreparePayOnchainRequest apiObj, wire_cst_prepare_pay_onchain_request wireObj) { PreparePayOnchainRequest apiObj, wire_cst_prepare_pay_onchain_request wireObj) {
cst_api_fill_to_wire_pay_onchain_amount(apiObj.amount, wireObj.amount); cst_api_fill_to_wire_pay_amount(apiObj.amount, wireObj.amount);
wireObj.fee_rate_sat_per_vbyte = cst_encode_opt_box_autoadd_u_32(apiObj.feeRateSatPerVbyte); wireObj.fee_rate_sat_per_vbyte = cst_encode_opt_box_autoadd_u_32(apiObj.feeRateSatPerVbyte);
} }
@@ -2738,7 +2770,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
void cst_api_fill_to_wire_prepare_send_request( void cst_api_fill_to_wire_prepare_send_request(
PrepareSendRequest apiObj, wire_cst_prepare_send_request wireObj) { PrepareSendRequest apiObj, wire_cst_prepare_send_request wireObj) {
wireObj.destination = cst_encode_String(apiObj.destination); wireObj.destination = cst_encode_String(apiObj.destination);
wireObj.amount_sat = cst_encode_opt_box_autoadd_u_64(apiObj.amountSat); wireObj.amount = cst_encode_opt_box_autoadd_pay_amount(apiObj.amount);
} }
@protected @protected
@@ -3166,6 +3198,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
void sse_encode_box_autoadd_message_success_action_data( void sse_encode_box_autoadd_message_success_action_data(
MessageSuccessActionData self, SseSerializer serializer); MessageSuccessActionData self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_pay_amount(PayAmount self, SseSerializer serializer);
@protected @protected
void sse_encode_box_autoadd_pay_onchain_request(PayOnchainRequest self, SseSerializer serializer); void sse_encode_box_autoadd_pay_onchain_request(PayOnchainRequest self, SseSerializer serializer);
@@ -3399,6 +3434,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected @protected
void sse_encode_opt_box_autoadd_list_payment_details(ListPaymentDetails? self, SseSerializer serializer); void sse_encode_opt_box_autoadd_list_payment_details(ListPaymentDetails? self, SseSerializer serializer);
@protected
void sse_encode_opt_box_autoadd_pay_amount(PayAmount? self, SseSerializer serializer);
@protected @protected
void sse_encode_opt_box_autoadd_payment(Payment? self, SseSerializer serializer); void sse_encode_opt_box_autoadd_payment(Payment? self, SseSerializer serializer);
@@ -3422,7 +3460,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
void sse_encode_opt_list_payment_type(List<PaymentType>? self, SseSerializer serializer); void sse_encode_opt_list_payment_type(List<PaymentType>? self, SseSerializer serializer);
@protected @protected
void sse_encode_pay_onchain_amount(PayOnchainAmount self, SseSerializer serializer); void sse_encode_pay_amount(PayAmount self, SseSerializer serializer);
@protected @protected
void sse_encode_pay_onchain_request(PayOnchainRequest self, SseSerializer serializer); void sse_encode_pay_onchain_request(PayOnchainRequest self, SseSerializer serializer);
@@ -4629,6 +4667,16 @@ class RustLibWire implements BaseWire {
_cst_new_box_autoadd_message_success_action_dataPtr _cst_new_box_autoadd_message_success_action_dataPtr
.asFunction<ffi.Pointer<wire_cst_message_success_action_data> Function()>(); .asFunction<ffi.Pointer<wire_cst_message_success_action_data> Function()>();
ffi.Pointer<wire_cst_pay_amount> cst_new_box_autoadd_pay_amount() {
return _cst_new_box_autoadd_pay_amount();
}
late final _cst_new_box_autoadd_pay_amountPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_pay_amount> Function()>>(
'frbgen_breez_liquid_cst_new_box_autoadd_pay_amount');
late final _cst_new_box_autoadd_pay_amount =
_cst_new_box_autoadd_pay_amountPtr.asFunction<ffi.Pointer<wire_cst_pay_amount> Function()>();
ffi.Pointer<wire_cst_pay_onchain_request> cst_new_box_autoadd_pay_onchain_request() { ffi.Pointer<wire_cst_pay_onchain_request> cst_new_box_autoadd_pay_onchain_request() {
return _cst_new_box_autoadd_pay_onchain_request(); return _cst_new_box_autoadd_pay_onchain_request();
} }
@@ -5347,24 +5395,24 @@ final class wire_cst_prepare_ln_url_pay_request extends ffi.Struct {
external ffi.Pointer<ffi.Bool> validate_success_action_url; external ffi.Pointer<ffi.Bool> validate_success_action_url;
} }
final class wire_cst_PayOnchainAmount_Receiver extends ffi.Struct { final class wire_cst_PayAmount_Receiver extends ffi.Struct {
@ffi.Uint64() @ffi.Uint64()
external int amount_sat; external int amount_sat;
} }
final class PayOnchainAmountKind extends ffi.Union { final class PayAmountKind extends ffi.Union {
external wire_cst_PayOnchainAmount_Receiver Receiver; external wire_cst_PayAmount_Receiver Receiver;
} }
final class wire_cst_pay_onchain_amount extends ffi.Struct { final class wire_cst_pay_amount extends ffi.Struct {
@ffi.Int32() @ffi.Int32()
external int tag; external int tag;
external PayOnchainAmountKind kind; external PayAmountKind kind;
} }
final class wire_cst_prepare_pay_onchain_request extends ffi.Struct { final class wire_cst_prepare_pay_onchain_request extends ffi.Struct {
external wire_cst_pay_onchain_amount amount; external wire_cst_pay_amount amount;
external ffi.Pointer<ffi.Uint32> fee_rate_sat_per_vbyte; external ffi.Pointer<ffi.Uint32> fee_rate_sat_per_vbyte;
} }
@@ -5388,7 +5436,7 @@ final class wire_cst_prepare_refund_request extends ffi.Struct {
final class wire_cst_prepare_send_request extends ffi.Struct { final class wire_cst_prepare_send_request extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> destination; external ffi.Pointer<wire_cst_list_prim_u_8_strict> destination;
external ffi.Pointer<ffi.Uint64> amount_sat; external ffi.Pointer<wire_cst_pay_amount> amount;
} }
final class wire_cst_prepare_receive_response extends ffi.Struct { final class wire_cst_prepare_receive_response extends ffi.Struct {

View File

@@ -476,16 +476,16 @@ class OnchainPaymentLimitsResponse {
} }
@freezed @freezed
sealed class PayOnchainAmount with _$PayOnchainAmount { sealed class PayAmount with _$PayAmount {
const PayOnchainAmount._(); const PayAmount._();
/// The amount in satoshi that will be received /// The amount in satoshi that will be received
const factory PayOnchainAmount.receiver({ const factory PayAmount.receiver({
required BigInt amountSat, required BigInt amountSat,
}) = PayOnchainAmount_Receiver; }) = PayAmount_Receiver;
/// Indicates that all available funds should be sent /// Indicates that all available funds should be sent
const factory PayOnchainAmount.drain() = PayOnchainAmount_Drain; const factory PayAmount.drain() = PayAmount_Drain;
} }
/// An argument when calling [crate::sdk::LiquidSdk::pay_onchain]. /// An argument when calling [crate::sdk::LiquidSdk::pay_onchain].
@@ -849,7 +849,7 @@ class PrepareLnUrlPayResponse {
/// An argument when calling [crate::sdk::LiquidSdk::prepare_pay_onchain]. /// An argument when calling [crate::sdk::LiquidSdk::prepare_pay_onchain].
class PreparePayOnchainRequest { class PreparePayOnchainRequest {
final PayOnchainAmount amount; final PayAmount amount;
/// The optional fee rate of the Bitcoin claim transaction in sat/vB. Defaults to the swapper estimated claim fee. /// The optional fee rate of the Bitcoin claim transaction in sat/vB. Defaults to the swapper estimated claim fee.
final int? feeRateSatPerVbyte; final int? feeRateSatPerVbyte;
@@ -1005,16 +1005,16 @@ class PrepareSendRequest {
final String destination; final String destination;
/// Should only be set when paying directly onchain or to a BIP21 URI /// Should only be set when paying directly onchain or to a BIP21 URI
/// where no amount is specified /// where no amount is specified, or when the caller wishes to drain
final BigInt? amountSat; final PayAmount? amount;
const PrepareSendRequest({ const PrepareSendRequest({
required this.destination, required this.destination,
this.amountSat, this.amount,
}); });
@override @override
int get hashCode => destination.hashCode ^ amountSat.hashCode; int get hashCode => destination.hashCode ^ amount.hashCode;
@override @override
bool operator ==(Object other) => bool operator ==(Object other) =>
@@ -1022,7 +1022,7 @@ class PrepareSendRequest {
other is PrepareSendRequest && other is PrepareSendRequest &&
runtimeType == other.runtimeType && runtimeType == other.runtimeType &&
destination == other.destination && destination == other.destination &&
amountSat == other.amountSat; amount == other.amount;
} }
/// Returned when calling [crate::sdk::LiquidSdk::prepare_send_payment]. /// Returned when calling [crate::sdk::LiquidSdk::prepare_send_payment].

View File

@@ -594,53 +594,52 @@ abstract class LnUrlPayResult_PayError extends LnUrlPayResult {
} }
/// @nodoc /// @nodoc
mixin _$PayOnchainAmount {} mixin _$PayAmount {}
/// @nodoc /// @nodoc
abstract class $PayOnchainAmountCopyWith<$Res> { abstract class $PayAmountCopyWith<$Res> {
factory $PayOnchainAmountCopyWith(PayOnchainAmount value, $Res Function(PayOnchainAmount) then) = factory $PayAmountCopyWith(PayAmount value, $Res Function(PayAmount) then) =
_$PayOnchainAmountCopyWithImpl<$Res, PayOnchainAmount>; _$PayAmountCopyWithImpl<$Res, PayAmount>;
} }
/// @nodoc /// @nodoc
class _$PayOnchainAmountCopyWithImpl<$Res, $Val extends PayOnchainAmount> class _$PayAmountCopyWithImpl<$Res, $Val extends PayAmount> implements $PayAmountCopyWith<$Res> {
implements $PayOnchainAmountCopyWith<$Res> { _$PayAmountCopyWithImpl(this._value, this._then);
_$PayOnchainAmountCopyWithImpl(this._value, this._then);
// ignore: unused_field // ignore: unused_field
final $Val _value; final $Val _value;
// ignore: unused_field // ignore: unused_field
final $Res Function($Val) _then; final $Res Function($Val) _then;
/// Create a copy of PayOnchainAmount /// Create a copy of PayAmount
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
} }
/// @nodoc /// @nodoc
abstract class _$$PayOnchainAmount_ReceiverImplCopyWith<$Res> { abstract class _$$PayAmount_ReceiverImplCopyWith<$Res> {
factory _$$PayOnchainAmount_ReceiverImplCopyWith( factory _$$PayAmount_ReceiverImplCopyWith(
_$PayOnchainAmount_ReceiverImpl value, $Res Function(_$PayOnchainAmount_ReceiverImpl) then) = _$PayAmount_ReceiverImpl value, $Res Function(_$PayAmount_ReceiverImpl) then) =
__$$PayOnchainAmount_ReceiverImplCopyWithImpl<$Res>; __$$PayAmount_ReceiverImplCopyWithImpl<$Res>;
@useResult @useResult
$Res call({BigInt amountSat}); $Res call({BigInt amountSat});
} }
/// @nodoc /// @nodoc
class __$$PayOnchainAmount_ReceiverImplCopyWithImpl<$Res> class __$$PayAmount_ReceiverImplCopyWithImpl<$Res>
extends _$PayOnchainAmountCopyWithImpl<$Res, _$PayOnchainAmount_ReceiverImpl> extends _$PayAmountCopyWithImpl<$Res, _$PayAmount_ReceiverImpl>
implements _$$PayOnchainAmount_ReceiverImplCopyWith<$Res> { implements _$$PayAmount_ReceiverImplCopyWith<$Res> {
__$$PayOnchainAmount_ReceiverImplCopyWithImpl( __$$PayAmount_ReceiverImplCopyWithImpl(
_$PayOnchainAmount_ReceiverImpl _value, $Res Function(_$PayOnchainAmount_ReceiverImpl) _then) _$PayAmount_ReceiverImpl _value, $Res Function(_$PayAmount_ReceiverImpl) _then)
: super(_value, _then); : super(_value, _then);
/// Create a copy of PayOnchainAmount /// Create a copy of PayAmount
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
@override @override
$Res call({ $Res call({
Object? amountSat = null, Object? amountSat = null,
}) { }) {
return _then(_$PayOnchainAmount_ReceiverImpl( return _then(_$PayAmount_ReceiverImpl(
amountSat: null == amountSat amountSat: null == amountSat
? _value.amountSat ? _value.amountSat
: amountSat // ignore: cast_nullable_to_non_nullable : amountSat // ignore: cast_nullable_to_non_nullable
@@ -651,93 +650,90 @@ class __$$PayOnchainAmount_ReceiverImplCopyWithImpl<$Res>
/// @nodoc /// @nodoc
class _$PayOnchainAmount_ReceiverImpl extends PayOnchainAmount_Receiver { class _$PayAmount_ReceiverImpl extends PayAmount_Receiver {
const _$PayOnchainAmount_ReceiverImpl({required this.amountSat}) : super._(); const _$PayAmount_ReceiverImpl({required this.amountSat}) : super._();
@override @override
final BigInt amountSat; final BigInt amountSat;
@override @override
String toString() { String toString() {
return 'PayOnchainAmount.receiver(amountSat: $amountSat)'; return 'PayAmount.receiver(amountSat: $amountSat)';
} }
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return identical(this, other) || return identical(this, other) ||
(other.runtimeType == runtimeType && (other.runtimeType == runtimeType &&
other is _$PayOnchainAmount_ReceiverImpl && other is _$PayAmount_ReceiverImpl &&
(identical(other.amountSat, amountSat) || other.amountSat == amountSat)); (identical(other.amountSat, amountSat) || other.amountSat == amountSat));
} }
@override @override
int get hashCode => Object.hash(runtimeType, amountSat); int get hashCode => Object.hash(runtimeType, amountSat);
/// Create a copy of PayOnchainAmount /// Create a copy of PayAmount
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false) @JsonKey(includeFromJson: false, includeToJson: false)
@override @override
@pragma('vm:prefer-inline') @pragma('vm:prefer-inline')
_$$PayOnchainAmount_ReceiverImplCopyWith<_$PayOnchainAmount_ReceiverImpl> get copyWith => _$$PayAmount_ReceiverImplCopyWith<_$PayAmount_ReceiverImpl> get copyWith =>
__$$PayOnchainAmount_ReceiverImplCopyWithImpl<_$PayOnchainAmount_ReceiverImpl>(this, _$identity); __$$PayAmount_ReceiverImplCopyWithImpl<_$PayAmount_ReceiverImpl>(this, _$identity);
} }
abstract class PayOnchainAmount_Receiver extends PayOnchainAmount { abstract class PayAmount_Receiver extends PayAmount {
const factory PayOnchainAmount_Receiver({required final BigInt amountSat}) = const factory PayAmount_Receiver({required final BigInt amountSat}) = _$PayAmount_ReceiverImpl;
_$PayOnchainAmount_ReceiverImpl; const PayAmount_Receiver._() : super._();
const PayOnchainAmount_Receiver._() : super._();
BigInt get amountSat; BigInt get amountSat;
/// Create a copy of PayOnchainAmount /// Create a copy of PayAmount
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false) @JsonKey(includeFromJson: false, includeToJson: false)
_$$PayOnchainAmount_ReceiverImplCopyWith<_$PayOnchainAmount_ReceiverImpl> get copyWith => _$$PayAmount_ReceiverImplCopyWith<_$PayAmount_ReceiverImpl> get copyWith =>
throw _privateConstructorUsedError; throw _privateConstructorUsedError;
} }
/// @nodoc /// @nodoc
abstract class _$$PayOnchainAmount_DrainImplCopyWith<$Res> { abstract class _$$PayAmount_DrainImplCopyWith<$Res> {
factory _$$PayOnchainAmount_DrainImplCopyWith( factory _$$PayAmount_DrainImplCopyWith(
_$PayOnchainAmount_DrainImpl value, $Res Function(_$PayOnchainAmount_DrainImpl) then) = _$PayAmount_DrainImpl value, $Res Function(_$PayAmount_DrainImpl) then) =
__$$PayOnchainAmount_DrainImplCopyWithImpl<$Res>; __$$PayAmount_DrainImplCopyWithImpl<$Res>;
} }
/// @nodoc /// @nodoc
class __$$PayOnchainAmount_DrainImplCopyWithImpl<$Res> class __$$PayAmount_DrainImplCopyWithImpl<$Res> extends _$PayAmountCopyWithImpl<$Res, _$PayAmount_DrainImpl>
extends _$PayOnchainAmountCopyWithImpl<$Res, _$PayOnchainAmount_DrainImpl> implements _$$PayAmount_DrainImplCopyWith<$Res> {
implements _$$PayOnchainAmount_DrainImplCopyWith<$Res> { __$$PayAmount_DrainImplCopyWithImpl(
__$$PayOnchainAmount_DrainImplCopyWithImpl( _$PayAmount_DrainImpl _value, $Res Function(_$PayAmount_DrainImpl) _then)
_$PayOnchainAmount_DrainImpl _value, $Res Function(_$PayOnchainAmount_DrainImpl) _then)
: super(_value, _then); : super(_value, _then);
/// Create a copy of PayOnchainAmount /// Create a copy of PayAmount
/// with the given fields replaced by the non-null parameter values. /// with the given fields replaced by the non-null parameter values.
} }
/// @nodoc /// @nodoc
class _$PayOnchainAmount_DrainImpl extends PayOnchainAmount_Drain { class _$PayAmount_DrainImpl extends PayAmount_Drain {
const _$PayOnchainAmount_DrainImpl() : super._(); const _$PayAmount_DrainImpl() : super._();
@override @override
String toString() { String toString() {
return 'PayOnchainAmount.drain()'; return 'PayAmount.drain()';
} }
@override @override
bool operator ==(Object other) { bool operator ==(Object other) {
return identical(this, other) || return identical(this, other) || (other.runtimeType == runtimeType && other is _$PayAmount_DrainImpl);
(other.runtimeType == runtimeType && other is _$PayOnchainAmount_DrainImpl);
} }
@override @override
int get hashCode => runtimeType.hashCode; int get hashCode => runtimeType.hashCode;
} }
abstract class PayOnchainAmount_Drain extends PayOnchainAmount { abstract class PayAmount_Drain extends PayAmount {
const factory PayOnchainAmount_Drain() = _$PayOnchainAmount_DrainImpl; const factory PayAmount_Drain() = _$PayAmount_DrainImpl;
const PayOnchainAmount_Drain._() : super._(); const PayAmount_Drain._() : super._();
} }
/// @nodoc /// @nodoc

View File

@@ -1116,6 +1116,17 @@ class FlutterBreezLiquidBindings {
_frbgen_breez_liquid_cst_new_box_autoadd_message_success_action_dataPtr _frbgen_breez_liquid_cst_new_box_autoadd_message_success_action_dataPtr
.asFunction<ffi.Pointer<wire_cst_message_success_action_data> Function()>(); .asFunction<ffi.Pointer<wire_cst_message_success_action_data> Function()>();
ffi.Pointer<wire_cst_pay_amount> frbgen_breez_liquid_cst_new_box_autoadd_pay_amount() {
return _frbgen_breez_liquid_cst_new_box_autoadd_pay_amount();
}
late final _frbgen_breez_liquid_cst_new_box_autoadd_pay_amountPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_pay_amount> Function()>>(
'frbgen_breez_liquid_cst_new_box_autoadd_pay_amount');
late final _frbgen_breez_liquid_cst_new_box_autoadd_pay_amount =
_frbgen_breez_liquid_cst_new_box_autoadd_pay_amountPtr
.asFunction<ffi.Pointer<wire_cst_pay_amount> Function()>();
ffi.Pointer<wire_cst_pay_onchain_request> frbgen_breez_liquid_cst_new_box_autoadd_pay_onchain_request() { ffi.Pointer<wire_cst_pay_onchain_request> frbgen_breez_liquid_cst_new_box_autoadd_pay_onchain_request() {
return _frbgen_breez_liquid_cst_new_box_autoadd_pay_onchain_request(); return _frbgen_breez_liquid_cst_new_box_autoadd_pay_onchain_request();
} }
@@ -4143,24 +4154,24 @@ final class wire_cst_prepare_ln_url_pay_request extends ffi.Struct {
external ffi.Pointer<ffi.Bool> validate_success_action_url; external ffi.Pointer<ffi.Bool> validate_success_action_url;
} }
final class wire_cst_PayOnchainAmount_Receiver extends ffi.Struct { final class wire_cst_PayAmount_Receiver extends ffi.Struct {
@ffi.Uint64() @ffi.Uint64()
external int amount_sat; external int amount_sat;
} }
final class PayOnchainAmountKind extends ffi.Union { final class PayAmountKind extends ffi.Union {
external wire_cst_PayOnchainAmount_Receiver Receiver; external wire_cst_PayAmount_Receiver Receiver;
} }
final class wire_cst_pay_onchain_amount extends ffi.Struct { final class wire_cst_pay_amount extends ffi.Struct {
@ffi.Int32() @ffi.Int32()
external int tag; external int tag;
external PayOnchainAmountKind kind; external PayAmountKind kind;
} }
final class wire_cst_prepare_pay_onchain_request extends ffi.Struct { final class wire_cst_prepare_pay_onchain_request extends ffi.Struct {
external wire_cst_pay_onchain_amount amount; external wire_cst_pay_amount amount;
external ffi.Pointer<ffi.Uint32> fee_rate_sat_per_vbyte; external ffi.Pointer<ffi.Uint32> fee_rate_sat_per_vbyte;
} }
@@ -4184,7 +4195,7 @@ final class wire_cst_prepare_refund_request extends ffi.Struct {
final class wire_cst_prepare_send_request extends ffi.Struct { final class wire_cst_prepare_send_request extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> destination; external ffi.Pointer<wire_cst_list_prim_u_8_strict> destination;
external ffi.Pointer<ffi.Uint64> amount_sat; external ffi.Pointer<wire_cst_pay_amount> amount;
} }
final class wire_cst_prepare_receive_response extends ffi.Struct { final class wire_cst_prepare_receive_response extends ffi.Struct {

View File

@@ -1487,7 +1487,7 @@ fun asPreparePayOnchainRequest(preparePayOnchainRequest: ReadableMap): PreparePa
) { ) {
return null return null
} }
val amount = preparePayOnchainRequest.getMap("amount")?.let { asPayOnchainAmount(it) }!! val amount = preparePayOnchainRequest.getMap("amount")?.let { asPayAmount(it) }!!
val feeRateSatPerVbyte = val feeRateSatPerVbyte =
if (hasNonNullKey( if (hasNonNullKey(
preparePayOnchainRequest, preparePayOnchainRequest,
@@ -1721,14 +1721,14 @@ fun asPrepareSendRequest(prepareSendRequest: ReadableMap): PrepareSendRequest? {
return null return null
} }
val destination = prepareSendRequest.getString("destination")!! val destination = prepareSendRequest.getString("destination")!!
val amountSat = if (hasNonNullKey(prepareSendRequest, "amountSat")) prepareSendRequest.getDouble("amountSat").toULong() else null val amount = if (hasNonNullKey(prepareSendRequest, "amount")) prepareSendRequest.getMap("amount")?.let { asPayAmount(it) } else null
return PrepareSendRequest(destination, amountSat) return PrepareSendRequest(destination, amount)
} }
fun readableMapOf(prepareSendRequest: PrepareSendRequest): ReadableMap = fun readableMapOf(prepareSendRequest: PrepareSendRequest): ReadableMap =
readableMapOf( readableMapOf(
"destination" to prepareSendRequest.destination, "destination" to prepareSendRequest.destination,
"amountSat" to prepareSendRequest.amountSat, "amount" to prepareSendRequest.amount?.let { readableMapOf(it) },
) )
fun asPrepareSendRequestList(arr: ReadableArray): List<PrepareSendRequest> { fun asPrepareSendRequestList(arr: ReadableArray): List<PrepareSendRequest> {
@@ -2708,38 +2708,38 @@ fun asNetworkList(arr: ReadableArray): List<Network> {
return list return list
} }
fun asPayOnchainAmount(payOnchainAmount: ReadableMap): PayOnchainAmount? { fun asPayAmount(payAmount: ReadableMap): PayAmount? {
val type = payOnchainAmount.getString("type") val type = payAmount.getString("type")
if (type == "receiver") { if (type == "receiver") {
val amountSat = payOnchainAmount.getDouble("amountSat").toULong() val amountSat = payAmount.getDouble("amountSat").toULong()
return PayOnchainAmount.Receiver(amountSat) return PayAmount.Receiver(amountSat)
} }
if (type == "drain") { if (type == "drain") {
return PayOnchainAmount.Drain return PayAmount.Drain
} }
return null return null
} }
fun readableMapOf(payOnchainAmount: PayOnchainAmount): ReadableMap? { fun readableMapOf(payAmount: PayAmount): ReadableMap? {
val map = Arguments.createMap() val map = Arguments.createMap()
when (payOnchainAmount) { when (payAmount) {
is PayOnchainAmount.Receiver -> { is PayAmount.Receiver -> {
pushToMap(map, "type", "receiver") pushToMap(map, "type", "receiver")
pushToMap(map, "amountSat", payOnchainAmount.amountSat) pushToMap(map, "amountSat", payAmount.amountSat)
} }
is PayOnchainAmount.Drain -> { is PayAmount.Drain -> {
pushToMap(map, "type", "drain") pushToMap(map, "type", "drain")
} }
} }
return map return map
} }
fun asPayOnchainAmountList(arr: ReadableArray): List<PayOnchainAmount> { fun asPayAmountList(arr: ReadableArray): List<PayAmount> {
val list = ArrayList<PayOnchainAmount>() val list = ArrayList<PayAmount>()
for (value in arr.toList()) { for (value in arr.toList()) {
when (value) { when (value) {
is ReadableMap -> list.add(asPayOnchainAmount(value)!!) is ReadableMap -> list.add(asPayAmount(value)!!)
else -> throw SdkException.Generic(errUnexpectedType(value)) else -> throw SdkException.Generic(errUnexpectedType(value))
} }
} }

View File

@@ -1728,7 +1728,7 @@ enum BreezSDKLiquidMapper {
guard let amountTmp = preparePayOnchainRequest["amount"] as? [String: Any?] else { guard let amountTmp = preparePayOnchainRequest["amount"] as? [String: Any?] else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "amount", typeName: "PreparePayOnchainRequest")) throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "amount", typeName: "PreparePayOnchainRequest"))
} }
let amount = try asPayOnchainAmount(payOnchainAmount: amountTmp) let amount = try asPayAmount(payAmount: amountTmp)
var feeRateSatPerVbyte: UInt32? var feeRateSatPerVbyte: UInt32?
if hasNonNilKey(data: preparePayOnchainRequest, key: "feeRateSatPerVbyte") { if hasNonNilKey(data: preparePayOnchainRequest, key: "feeRateSatPerVbyte") {
@@ -1743,7 +1743,7 @@ enum BreezSDKLiquidMapper {
static func dictionaryOf(preparePayOnchainRequest: PreparePayOnchainRequest) -> [String: Any?] { static func dictionaryOf(preparePayOnchainRequest: PreparePayOnchainRequest) -> [String: Any?] {
return [ return [
"amount": dictionaryOf(payOnchainAmount: preparePayOnchainRequest.amount), "amount": dictionaryOf(payAmount: preparePayOnchainRequest.amount),
"feeRateSatPerVbyte": preparePayOnchainRequest.feeRateSatPerVbyte == nil ? nil : preparePayOnchainRequest.feeRateSatPerVbyte, "feeRateSatPerVbyte": preparePayOnchainRequest.feeRateSatPerVbyte == nil ? nil : preparePayOnchainRequest.feeRateSatPerVbyte,
] ]
} }
@@ -1976,21 +1976,18 @@ enum BreezSDKLiquidMapper {
guard let destination = prepareSendRequest["destination"] as? String else { guard let destination = prepareSendRequest["destination"] as? String else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "destination", typeName: "PrepareSendRequest")) throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "destination", typeName: "PrepareSendRequest"))
} }
var amountSat: UInt64? var amount: PayAmount?
if hasNonNilKey(data: prepareSendRequest, key: "amountSat") { if let amountTmp = prepareSendRequest["amount"] as? [String: Any?] {
guard let amountSatTmp = prepareSendRequest["amountSat"] as? UInt64 else { amount = try asPayAmount(payAmount: amountTmp)
throw SdkError.Generic(message: errUnexpectedValue(fieldName: "amountSat"))
}
amountSat = amountSatTmp
} }
return PrepareSendRequest(destination: destination, amountSat: amountSat) return PrepareSendRequest(destination: destination, amount: amount)
} }
static func dictionaryOf(prepareSendRequest: PrepareSendRequest) -> [String: Any?] { static func dictionaryOf(prepareSendRequest: PrepareSendRequest) -> [String: Any?] {
return [ return [
"destination": prepareSendRequest.destination, "destination": prepareSendRequest.destination,
"amountSat": prepareSendRequest.amountSat == nil ? nil : prepareSendRequest.amountSat, "amount": prepareSendRequest.amount == nil ? nil : dictionaryOf(payAmount: prepareSendRequest.amount!),
] ]
} }
@@ -3317,23 +3314,23 @@ enum BreezSDKLiquidMapper {
return list return list
} }
static func asPayOnchainAmount(payOnchainAmount: [String: Any?]) throws -> PayOnchainAmount { static func asPayAmount(payAmount: [String: Any?]) throws -> PayAmount {
let type = payOnchainAmount["type"] as! String let type = payAmount["type"] as! String
if type == "receiver" { if type == "receiver" {
guard let _amountSat = payOnchainAmount["amountSat"] as? UInt64 else { guard let _amountSat = payAmount["amountSat"] as? UInt64 else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "amountSat", typeName: "PayOnchainAmount")) throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "amountSat", typeName: "PayAmount"))
} }
return PayOnchainAmount.receiver(amountSat: _amountSat) return PayAmount.receiver(amountSat: _amountSat)
} }
if type == "drain" { if type == "drain" {
return PayOnchainAmount.drain return PayAmount.drain
} }
throw SdkError.Generic(message: "Unexpected type \(type) for enum PayOnchainAmount") throw SdkError.Generic(message: "Unexpected type \(type) for enum PayAmount")
} }
static func dictionaryOf(payOnchainAmount: PayOnchainAmount) -> [String: Any?] { static func dictionaryOf(payAmount: PayAmount) -> [String: Any?] {
switch payOnchainAmount { switch payAmount {
case let .receiver( case let .receiver(
amountSat amountSat
): ):
@@ -3349,18 +3346,18 @@ enum BreezSDKLiquidMapper {
} }
} }
static func arrayOf(payOnchainAmountList: [PayOnchainAmount]) -> [Any] { static func arrayOf(payAmountList: [PayAmount]) -> [Any] {
return payOnchainAmountList.map { v -> [String: Any?] in return dictionaryOf(payOnchainAmount: v) } return payAmountList.map { v -> [String: Any?] in return dictionaryOf(payAmount: v) }
} }
static func asPayOnchainAmountList(arr: [Any]) throws -> [PayOnchainAmount] { static func asPayAmountList(arr: [Any]) throws -> [PayAmount] {
var list = [PayOnchainAmount]() var list = [PayAmount]()
for value in arr { for value in arr {
if let val = value as? [String: Any?] { if let val = value as? [String: Any?] {
var payOnchainAmount = try asPayOnchainAmount(payOnchainAmount: val) var payAmount = try asPayAmount(payAmount: val)
list.append(payOnchainAmount) list.append(payAmount)
} else { } else {
throw SdkError.Generic(message: errUnexpectedType(typeName: "PayOnchainAmount")) throw SdkError.Generic(message: errUnexpectedType(typeName: "PayAmount"))
} }
} }
return list return list

View File

@@ -266,7 +266,7 @@ export interface PrepareLnUrlPayResponse {
} }
export interface PreparePayOnchainRequest { export interface PreparePayOnchainRequest {
amount: PayOnchainAmount amount: PayAmount
feeRateSatPerVbyte?: number feeRateSatPerVbyte?: number
} }
@@ -301,7 +301,7 @@ export interface PrepareRefundResponse {
export interface PrepareSendRequest { export interface PrepareSendRequest {
destination: string destination: string
amountSat?: number amount?: PayAmount
} }
export interface PrepareSendResponse { export interface PrepareSendResponse {
@@ -533,16 +533,16 @@ export enum Network {
REGTEST = "regtest" REGTEST = "regtest"
} }
export enum PayOnchainAmountVariant { export enum PayAmountVariant {
RECEIVER = "receiver", RECEIVER = "receiver",
DRAIN = "drain" DRAIN = "drain"
} }
export type PayOnchainAmount = { export type PayAmount = {
type: PayOnchainAmountVariant.RECEIVER, type: PayAmountVariant.RECEIVER,
amountSat: number amountSat: number
} | { } | {
type: PayOnchainAmountVariant.DRAIN type: PayAmountVariant.DRAIN
} }
export enum PaymentDetailsVariant { export enum PaymentDetailsVariant {