mirror of
https://github.com/aljazceru/breez-sdk-liquid.git
synced 2025-12-24 01:14:22 +01:00
Chain swap refund tx fee bumping (#688)
* Chain swap refund tx fee bumping * Add "pending" to refund tx id field names * Rename pending to last
This commit is contained in:
2
cli/Cargo.lock
generated
2
cli/Cargo.lock
generated
@@ -707,7 +707,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "boltz-client"
|
name = "boltz-client"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "git+https://github.com/SatoshiPortal/boltz-rust?rev=540b5cb6505a97f1d02d846bf544bd5c1f800b25#540b5cb6505a97f1d02d846bf544bd5c1f800b25"
|
source = "git+https://github.com/danielgranhao/boltz-rust?rev=e3e87186604c818c667b1293149423af5757dfbe#e3e87186604c818c667b1293149423af5757dfbe"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bip39",
|
"bip39",
|
||||||
"bitcoin 0.32.5",
|
"bitcoin 0.32.5",
|
||||||
|
|||||||
926
lib/Cargo.lock
generated
926
lib/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -711,6 +711,7 @@ typedef struct wire_cst_refundable_swap {
|
|||||||
struct wire_cst_list_prim_u_8_strict *swap_address;
|
struct wire_cst_list_prim_u_8_strict *swap_address;
|
||||||
uint32_t timestamp;
|
uint32_t timestamp;
|
||||||
uint64_t amount_sat;
|
uint64_t amount_sat;
|
||||||
|
struct wire_cst_list_prim_u_8_strict *last_refund_tx_id;
|
||||||
} wire_cst_refundable_swap;
|
} wire_cst_refundable_swap;
|
||||||
|
|
||||||
typedef struct wire_cst_list_refundable_swap {
|
typedef struct wire_cst_list_refundable_swap {
|
||||||
@@ -1064,7 +1065,7 @@ typedef struct wire_cst_payment_error {
|
|||||||
typedef struct wire_cst_prepare_refund_response {
|
typedef struct wire_cst_prepare_refund_response {
|
||||||
uint32_t tx_vsize;
|
uint32_t tx_vsize;
|
||||||
uint64_t tx_fee_sat;
|
uint64_t tx_fee_sat;
|
||||||
struct wire_cst_list_prim_u_8_strict *refund_tx_id;
|
struct wire_cst_list_prim_u_8_strict *last_refund_tx_id;
|
||||||
} wire_cst_prepare_refund_response;
|
} wire_cst_prepare_refund_response;
|
||||||
|
|
||||||
typedef struct wire_cst_receive_payment_response {
|
typedef struct wire_cst_receive_payment_response {
|
||||||
|
|||||||
@@ -618,6 +618,7 @@ dictionary RefundableSwap {
|
|||||||
string swap_address;
|
string swap_address;
|
||||||
u32 timestamp;
|
u32 timestamp;
|
||||||
u64 amount_sat;
|
u64 amount_sat;
|
||||||
|
string? last_refund_tx_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary RecommendedFees {
|
dictionary RecommendedFees {
|
||||||
@@ -637,7 +638,7 @@ dictionary PrepareRefundRequest {
|
|||||||
dictionary PrepareRefundResponse {
|
dictionary PrepareRefundResponse {
|
||||||
u32 tx_vsize;
|
u32 tx_vsize;
|
||||||
u64 tx_fee_sat;
|
u64 tx_fee_sat;
|
||||||
string? refund_tx_id = null;
|
string? last_refund_tx_id = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
dictionary RefundRequest {
|
dictionary RefundRequest {
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ workspace = true
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { workspace = true }
|
anyhow = { workspace = true }
|
||||||
bip39 = "2.0.0"
|
bip39 = "2.0.0"
|
||||||
boltz-client = { git = "https://github.com/SatoshiPortal/boltz-rust", rev = "540b5cb6505a97f1d02d846bf544bd5c1f800b25" }
|
boltz-client = { git = "https://github.com/danielgranhao/boltz-rust", rev = "e3e87186604c818c667b1293149423af5757dfbe" }
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
derivative = "2.2.0"
|
derivative = "2.2.0"
|
||||||
env_logger = "0.11"
|
env_logger = "0.11"
|
||||||
|
|||||||
@@ -2,14 +2,13 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use boltz_client::Amount;
|
|
||||||
use electrum_client::{
|
use electrum_client::{
|
||||||
bitcoin::{
|
bitcoin::{
|
||||||
consensus::{deserialize, serialize},
|
consensus::{deserialize, serialize},
|
||||||
hashes::{sha256, Hash},
|
hashes::{sha256, Hash},
|
||||||
Address, OutPoint, Script, Transaction, TxOut, Txid,
|
Address, OutPoint, Script, Transaction, Txid,
|
||||||
},
|
},
|
||||||
Client, ElectrumApi, GetBalanceRes, HeaderNotification, ListUnspentRes,
|
Client, ElectrumApi, GetBalanceRes, HeaderNotification,
|
||||||
};
|
};
|
||||||
use log::info;
|
use log::info;
|
||||||
use lwk_wollet::{ElectrumOptions, ElectrumUrl, Error, History};
|
use lwk_wollet::{ElectrumOptions, ElectrumUrl, Error, History};
|
||||||
@@ -188,27 +187,46 @@ impl BitcoinChainService for HybridBitcoinChainService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn get_script_utxos(&self, script: &Script) -> Result<Vec<Utxo>> {
|
async fn get_script_utxos(&self, script: &Script) -> Result<Vec<Utxo>> {
|
||||||
let utxos = self
|
// Get confirmed transactions involving our script
|
||||||
.client
|
let history: Vec<_> = self
|
||||||
.script_list_unspent(script)?
|
.get_script_history(script)?
|
||||||
.iter()
|
.into_iter()
|
||||||
.map(
|
.filter(|h| h.height > 0)
|
||||||
|ListUnspentRes {
|
|
||||||
tx_hash,
|
|
||||||
tx_pos,
|
|
||||||
value,
|
|
||||||
..
|
|
||||||
}| {
|
|
||||||
Utxo::Bitcoin((
|
|
||||||
OutPoint::new(*tx_hash, *tx_pos as u32),
|
|
||||||
TxOut {
|
|
||||||
value: Amount::from_sat(*value),
|
|
||||||
script_pubkey: script.into(),
|
|
||||||
},
|
|
||||||
))
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.collect();
|
.collect();
|
||||||
|
let txs = self.get_transactions(
|
||||||
|
&history
|
||||||
|
.iter()
|
||||||
|
.map(|h| h.txid.to_raw_hash().into())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
// Find all unspent outputs paying to our script
|
||||||
|
let utxos = txs
|
||||||
|
.iter()
|
||||||
|
.flat_map(|tx| {
|
||||||
|
tx.output
|
||||||
|
.iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|(_, output)| output.script_pubkey == *script)
|
||||||
|
.filter(|(vout, _)| {
|
||||||
|
// Check if output is unspent
|
||||||
|
!txs.iter().any(|spending_tx| {
|
||||||
|
// Check if any input spends our output
|
||||||
|
spending_tx.input.iter().any(|input| {
|
||||||
|
input.previous_output.txid == tx.compute_txid()
|
||||||
|
&& input.previous_output.vout == *vout as u32
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.map(|(vout, output)| {
|
||||||
|
Utxo::Bitcoin((
|
||||||
|
OutPoint::new(tx.compute_txid(), vout as u32),
|
||||||
|
output.clone(),
|
||||||
|
))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
Ok(utxos)
|
Ok(utxos)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1167,7 +1167,7 @@ impl ChainSwapHandler {
|
|||||||
err: format!("Cannot transition from {from_state:?} to Refundable state"),
|
err: format!("Cannot transition from {from_state:?} to Refundable state"),
|
||||||
}),
|
}),
|
||||||
|
|
||||||
(Pending | WaitingFeeAcceptance | Refundable, RefundPending) => Ok(()),
|
(Pending | WaitingFeeAcceptance | Refundable | RefundPending, RefundPending) => Ok(()),
|
||||||
(_, RefundPending) => Err(PaymentError::Generic {
|
(_, RefundPending) => Err(PaymentError::Generic {
|
||||||
err: format!("Cannot transition from {from_state:?} to RefundPending state"),
|
err: format!("Cannot transition from {from_state:?} to RefundPending state"),
|
||||||
}),
|
}),
|
||||||
@@ -1530,7 +1530,10 @@ mod tests {
|
|||||||
(TimedOut, HashSet::from([Failed])),
|
(TimedOut, HashSet::from([Failed])),
|
||||||
(Complete, HashSet::from([Refundable])),
|
(Complete, HashSet::from([Refundable])),
|
||||||
(Refundable, HashSet::from([RefundPending, Failed])),
|
(Refundable, HashSet::from([RefundPending, Failed])),
|
||||||
(RefundPending, HashSet::from([Refundable, Complete, Failed])),
|
(
|
||||||
|
RefundPending,
|
||||||
|
HashSet::from([Refundable, Complete, Failed, RefundPending]),
|
||||||
|
),
|
||||||
(Failed, HashSet::from([Failed, Refundable])),
|
(Failed, HashSet::from([Failed, Refundable])),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|||||||
@@ -4093,11 +4093,11 @@ impl SseDecode for crate::model::PrepareRefundResponse {
|
|||||||
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_txVsize = <u32>::sse_decode(deserializer);
|
let mut var_txVsize = <u32>::sse_decode(deserializer);
|
||||||
let mut var_txFeeSat = <u64>::sse_decode(deserializer);
|
let mut var_txFeeSat = <u64>::sse_decode(deserializer);
|
||||||
let mut var_refundTxId = <Option<String>>::sse_decode(deserializer);
|
let mut var_lastRefundTxId = <Option<String>>::sse_decode(deserializer);
|
||||||
return crate::model::PrepareRefundResponse {
|
return crate::model::PrepareRefundResponse {
|
||||||
tx_vsize: var_txVsize,
|
tx_vsize: var_txVsize,
|
||||||
tx_fee_sat: var_txFeeSat,
|
tx_fee_sat: var_txFeeSat,
|
||||||
refund_tx_id: var_refundTxId,
|
last_refund_tx_id: var_lastRefundTxId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4211,10 +4211,12 @@ impl SseDecode for crate::model::RefundableSwap {
|
|||||||
let mut var_swapAddress = <String>::sse_decode(deserializer);
|
let mut var_swapAddress = <String>::sse_decode(deserializer);
|
||||||
let mut var_timestamp = <u32>::sse_decode(deserializer);
|
let mut var_timestamp = <u32>::sse_decode(deserializer);
|
||||||
let mut var_amountSat = <u64>::sse_decode(deserializer);
|
let mut var_amountSat = <u64>::sse_decode(deserializer);
|
||||||
|
let mut var_lastRefundTxId = <Option<String>>::sse_decode(deserializer);
|
||||||
return crate::model::RefundableSwap {
|
return crate::model::RefundableSwap {
|
||||||
swap_address: var_swapAddress,
|
swap_address: var_swapAddress,
|
||||||
timestamp: var_timestamp,
|
timestamp: var_timestamp,
|
||||||
amount_sat: var_amountSat,
|
amount_sat: var_amountSat,
|
||||||
|
last_refund_tx_id: var_lastRefundTxId,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6343,7 +6345,7 @@ impl flutter_rust_bridge::IntoDart for crate::model::PrepareRefundResponse {
|
|||||||
[
|
[
|
||||||
self.tx_vsize.into_into_dart().into_dart(),
|
self.tx_vsize.into_into_dart().into_dart(),
|
||||||
self.tx_fee_sat.into_into_dart().into_dart(),
|
self.tx_fee_sat.into_into_dart().into_dart(),
|
||||||
self.refund_tx_id.into_into_dart().into_dart(),
|
self.last_refund_tx_id.into_into_dart().into_dart(),
|
||||||
]
|
]
|
||||||
.into_dart()
|
.into_dart()
|
||||||
}
|
}
|
||||||
@@ -6522,6 +6524,7 @@ impl flutter_rust_bridge::IntoDart for crate::model::RefundableSwap {
|
|||||||
self.swap_address.into_into_dart().into_dart(),
|
self.swap_address.into_into_dart().into_dart(),
|
||||||
self.timestamp.into_into_dart().into_dart(),
|
self.timestamp.into_into_dart().into_dart(),
|
||||||
self.amount_sat.into_into_dart().into_dart(),
|
self.amount_sat.into_into_dart().into_dart(),
|
||||||
|
self.last_refund_tx_id.into_into_dart().into_dart(),
|
||||||
]
|
]
|
||||||
.into_dart()
|
.into_dart()
|
||||||
}
|
}
|
||||||
@@ -8358,7 +8361,7 @@ impl SseEncode for crate::model::PrepareRefundResponse {
|
|||||||
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
|
||||||
<u32>::sse_encode(self.tx_vsize, serializer);
|
<u32>::sse_encode(self.tx_vsize, serializer);
|
||||||
<u64>::sse_encode(self.tx_fee_sat, serializer);
|
<u64>::sse_encode(self.tx_fee_sat, serializer);
|
||||||
<Option<String>>::sse_encode(self.refund_tx_id, serializer);
|
<Option<String>>::sse_encode(self.last_refund_tx_id, serializer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -8435,6 +8438,7 @@ impl SseEncode for crate::model::RefundableSwap {
|
|||||||
<String>::sse_encode(self.swap_address, serializer);
|
<String>::sse_encode(self.swap_address, serializer);
|
||||||
<u32>::sse_encode(self.timestamp, serializer);
|
<u32>::sse_encode(self.timestamp, serializer);
|
||||||
<u64>::sse_encode(self.amount_sat, serializer);
|
<u64>::sse_encode(self.amount_sat, serializer);
|
||||||
|
<Option<String>>::sse_encode(self.last_refund_tx_id, serializer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -10398,7 +10402,7 @@ mod io {
|
|||||||
crate::model::PrepareRefundResponse {
|
crate::model::PrepareRefundResponse {
|
||||||
tx_vsize: self.tx_vsize.cst_decode(),
|
tx_vsize: self.tx_vsize.cst_decode(),
|
||||||
tx_fee_sat: self.tx_fee_sat.cst_decode(),
|
tx_fee_sat: self.tx_fee_sat.cst_decode(),
|
||||||
refund_tx_id: self.refund_tx_id.cst_decode(),
|
last_refund_tx_id: self.last_refund_tx_id.cst_decode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10484,6 +10488,7 @@ mod io {
|
|||||||
swap_address: self.swap_address.cst_decode(),
|
swap_address: self.swap_address.cst_decode(),
|
||||||
timestamp: self.timestamp.cst_decode(),
|
timestamp: self.timestamp.cst_decode(),
|
||||||
amount_sat: self.amount_sat.cst_decode(),
|
amount_sat: self.amount_sat.cst_decode(),
|
||||||
|
last_refund_tx_id: self.last_refund_tx_id.cst_decode(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11671,7 +11676,7 @@ mod io {
|
|||||||
Self {
|
Self {
|
||||||
tx_vsize: Default::default(),
|
tx_vsize: Default::default(),
|
||||||
tx_fee_sat: Default::default(),
|
tx_fee_sat: Default::default(),
|
||||||
refund_tx_id: core::ptr::null_mut(),
|
last_refund_tx_id: core::ptr::null_mut(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11793,6 +11798,7 @@ mod io {
|
|||||||
swap_address: core::ptr::null_mut(),
|
swap_address: core::ptr::null_mut(),
|
||||||
timestamp: Default::default(),
|
timestamp: Default::default(),
|
||||||
amount_sat: Default::default(),
|
amount_sat: Default::default(),
|
||||||
|
last_refund_tx_id: core::ptr::null_mut(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -13952,7 +13958,7 @@ mod io {
|
|||||||
pub struct wire_cst_prepare_refund_response {
|
pub struct wire_cst_prepare_refund_response {
|
||||||
tx_vsize: u32,
|
tx_vsize: u32,
|
||||||
tx_fee_sat: u64,
|
tx_fee_sat: u64,
|
||||||
refund_tx_id: *mut wire_cst_list_prim_u_8_strict,
|
last_refund_tx_id: *mut wire_cst_list_prim_u_8_strict,
|
||||||
}
|
}
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
@@ -14011,6 +14017,7 @@ mod io {
|
|||||||
swap_address: *mut wire_cst_list_prim_u_8_strict,
|
swap_address: *mut wire_cst_list_prim_u_8_strict,
|
||||||
timestamp: u32,
|
timestamp: u32,
|
||||||
amount_sat: u64,
|
amount_sat: u64,
|
||||||
|
last_refund_tx_id: *mut wire_cst_list_prim_u_8_strict,
|
||||||
}
|
}
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone, Copy)]
|
#[derive(Clone, Copy)]
|
||||||
|
|||||||
@@ -513,7 +513,8 @@ pub struct PrepareRefundRequest {
|
|||||||
pub struct PrepareRefundResponse {
|
pub struct PrepareRefundResponse {
|
||||||
pub tx_vsize: u32,
|
pub tx_vsize: u32,
|
||||||
pub tx_fee_sat: u64,
|
pub tx_fee_sat: u64,
|
||||||
pub refund_tx_id: Option<String>,
|
/// The txid of the last broadcasted refund tx, if any
|
||||||
|
pub last_refund_tx_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An argument when calling [crate::sdk::LiquidSdk::refund].
|
/// An argument when calling [crate::sdk::LiquidSdk::refund].
|
||||||
@@ -874,6 +875,7 @@ impl ChainSwap {
|
|||||||
swap_address: self.lockup_address.clone(),
|
swap_address: self.lockup_address.clone(),
|
||||||
timestamp: self.created_at,
|
timestamp: self.created_at,
|
||||||
amount_sat: refundable_amount_sat,
|
amount_sat: refundable_amount_sat,
|
||||||
|
last_refund_tx_id: self.refund_tx_id.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1119,6 +1121,8 @@ pub struct RefundableSwap {
|
|||||||
pub timestamp: u32,
|
pub timestamp: u32,
|
||||||
/// Amount that is refundable, from all UTXOs
|
/// Amount that is refundable, from all UTXOs
|
||||||
pub amount_sat: u64,
|
pub amount_sat: u64,
|
||||||
|
/// The txid of the last broadcasted refund tx, if any
|
||||||
|
pub last_refund_tx_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The payment state of an individual payment.
|
/// The payment state of an individual payment.
|
||||||
@@ -1232,7 +1236,9 @@ impl PaymentState {
|
|||||||
pub(crate) fn is_refundable(&self) -> bool {
|
pub(crate) fn is_refundable(&self) -> bool {
|
||||||
matches!(
|
matches!(
|
||||||
self,
|
self,
|
||||||
PaymentState::Refundable | PaymentState::WaitingFeeAcceptance
|
PaymentState::Refundable
|
||||||
|
| PaymentState::RefundPending
|
||||||
|
| PaymentState::WaitingFeeAcceptance
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ impl Persister {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn list_refundable_chain_swaps(&self) -> Result<Vec<ChainSwap>> {
|
pub(crate) fn list_refundable_chain_swaps(&self) -> Result<Vec<ChainSwap>> {
|
||||||
self.list_chain_swaps_by_state(vec![PaymentState::Refundable])
|
self.list_chain_swaps_by_state(vec![PaymentState::Refundable, PaymentState::RefundPending])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn list_local_chain_swaps(&self) -> Result<Vec<ChainSwap>> {
|
pub(crate) fn list_local_chain_swaps(&self) -> Result<Vec<ChainSwap>> {
|
||||||
|
|||||||
@@ -2227,7 +2227,7 @@ impl LiquidSdk {
|
|||||||
Ok(PrepareRefundResponse {
|
Ok(PrepareRefundResponse {
|
||||||
tx_vsize,
|
tx_vsize,
|
||||||
tx_fee_sat,
|
tx_fee_sat,
|
||||||
refund_tx_id,
|
last_refund_tx_id: refund_tx_id,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2928,7 +2928,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
return PrepareRefundResponse(
|
return PrepareRefundResponse(
|
||||||
txVsize: dco_decode_u_32(arr[0]),
|
txVsize: dco_decode_u_32(arr[0]),
|
||||||
txFeeSat: dco_decode_u_64(arr[1]),
|
txFeeSat: dco_decode_u_64(arr[1]),
|
||||||
refundTxId: dco_decode_opt_String(arr[2]),
|
lastRefundTxId: dco_decode_opt_String(arr[2]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3027,11 +3027,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
RefundableSwap dco_decode_refundable_swap(dynamic raw) {
|
RefundableSwap dco_decode_refundable_swap(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 != 4) throw Exception('unexpected arr length: expect 4 but see ${arr.length}');
|
||||||
return RefundableSwap(
|
return RefundableSwap(
|
||||||
swapAddress: dco_decode_String(arr[0]),
|
swapAddress: dco_decode_String(arr[0]),
|
||||||
timestamp: dco_decode_u_32(arr[1]),
|
timestamp: dco_decode_u_32(arr[1]),
|
||||||
amountSat: dco_decode_u_64(arr[2]),
|
amountSat: dco_decode_u_64(arr[2]),
|
||||||
|
lastRefundTxId: dco_decode_opt_String(arr[3]),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -5109,8 +5110,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
var var_txVsize = sse_decode_u_32(deserializer);
|
var var_txVsize = sse_decode_u_32(deserializer);
|
||||||
var var_txFeeSat = sse_decode_u_64(deserializer);
|
var var_txFeeSat = sse_decode_u_64(deserializer);
|
||||||
var var_refundTxId = sse_decode_opt_String(deserializer);
|
var var_lastRefundTxId = sse_decode_opt_String(deserializer);
|
||||||
return PrepareRefundResponse(txVsize: var_txVsize, txFeeSat: var_txFeeSat, refundTxId: var_refundTxId);
|
return PrepareRefundResponse(
|
||||||
|
txVsize: var_txVsize, txFeeSat: var_txFeeSat, lastRefundTxId: var_lastRefundTxId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
@@ -5197,7 +5199,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
var var_swapAddress = sse_decode_String(deserializer);
|
var var_swapAddress = sse_decode_String(deserializer);
|
||||||
var var_timestamp = sse_decode_u_32(deserializer);
|
var var_timestamp = sse_decode_u_32(deserializer);
|
||||||
var var_amountSat = sse_decode_u_64(deserializer);
|
var var_amountSat = sse_decode_u_64(deserializer);
|
||||||
return RefundableSwap(swapAddress: var_swapAddress, timestamp: var_timestamp, amountSat: var_amountSat);
|
var var_lastRefundTxId = sse_decode_opt_String(deserializer);
|
||||||
|
return RefundableSwap(
|
||||||
|
swapAddress: var_swapAddress,
|
||||||
|
timestamp: var_timestamp,
|
||||||
|
amountSat: var_amountSat,
|
||||||
|
lastRefundTxId: var_lastRefundTxId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
@@ -7081,7 +7088,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
// Codec=Sse (Serialization based), see doc to use other codecs
|
// Codec=Sse (Serialization based), see doc to use other codecs
|
||||||
sse_encode_u_32(self.txVsize, serializer);
|
sse_encode_u_32(self.txVsize, serializer);
|
||||||
sse_encode_u_64(self.txFeeSat, serializer);
|
sse_encode_u_64(self.txFeeSat, serializer);
|
||||||
sse_encode_opt_String(self.refundTxId, serializer);
|
sse_encode_opt_String(self.lastRefundTxId, serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
@@ -7149,6 +7156,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
|
|||||||
sse_encode_String(self.swapAddress, serializer);
|
sse_encode_String(self.swapAddress, serializer);
|
||||||
sse_encode_u_32(self.timestamp, serializer);
|
sse_encode_u_32(self.timestamp, serializer);
|
||||||
sse_encode_u_64(self.amountSat, serializer);
|
sse_encode_u_64(self.amountSat, serializer);
|
||||||
|
sse_encode_opt_String(self.lastRefundTxId, serializer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
|
|||||||
@@ -3185,7 +3185,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
PrepareRefundResponse apiObj, wire_cst_prepare_refund_response wireObj) {
|
PrepareRefundResponse apiObj, wire_cst_prepare_refund_response wireObj) {
|
||||||
wireObj.tx_vsize = cst_encode_u_32(apiObj.txVsize);
|
wireObj.tx_vsize = cst_encode_u_32(apiObj.txVsize);
|
||||||
wireObj.tx_fee_sat = cst_encode_u_64(apiObj.txFeeSat);
|
wireObj.tx_fee_sat = cst_encode_u_64(apiObj.txFeeSat);
|
||||||
wireObj.refund_tx_id = cst_encode_opt_String(apiObj.refundTxId);
|
wireObj.last_refund_tx_id = cst_encode_opt_String(apiObj.lastRefundTxId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
@@ -3248,6 +3248,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
|
|||||||
wireObj.swap_address = cst_encode_String(apiObj.swapAddress);
|
wireObj.swap_address = cst_encode_String(apiObj.swapAddress);
|
||||||
wireObj.timestamp = cst_encode_u_32(apiObj.timestamp);
|
wireObj.timestamp = cst_encode_u_32(apiObj.timestamp);
|
||||||
wireObj.amount_sat = cst_encode_u_64(apiObj.amountSat);
|
wireObj.amount_sat = cst_encode_u_64(apiObj.amountSat);
|
||||||
|
wireObj.last_refund_tx_id = cst_encode_opt_String(apiObj.lastRefundTxId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@protected
|
@protected
|
||||||
@@ -6701,6 +6702,8 @@ final class wire_cst_refundable_swap extends ffi.Struct {
|
|||||||
|
|
||||||
@ffi.Uint64()
|
@ffi.Uint64()
|
||||||
external int amount_sat;
|
external int amount_sat;
|
||||||
|
|
||||||
|
external ffi.Pointer<wire_cst_list_prim_u_8_strict> last_refund_tx_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
final class wire_cst_list_refundable_swap extends ffi.Struct {
|
final class wire_cst_list_refundable_swap extends ffi.Struct {
|
||||||
@@ -7136,7 +7139,7 @@ final class wire_cst_prepare_refund_response extends ffi.Struct {
|
|||||||
@ffi.Uint64()
|
@ffi.Uint64()
|
||||||
external int tx_fee_sat;
|
external int tx_fee_sat;
|
||||||
|
|
||||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> refund_tx_id;
|
external ffi.Pointer<wire_cst_list_prim_u_8_strict> last_refund_tx_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
final class wire_cst_receive_payment_response extends ffi.Struct {
|
final class wire_cst_receive_payment_response extends ffi.Struct {
|
||||||
|
|||||||
@@ -1231,16 +1231,18 @@ class PrepareRefundRequest {
|
|||||||
class PrepareRefundResponse {
|
class PrepareRefundResponse {
|
||||||
final int txVsize;
|
final int txVsize;
|
||||||
final BigInt txFeeSat;
|
final BigInt txFeeSat;
|
||||||
final String? refundTxId;
|
|
||||||
|
/// The txid of the last broadcasted refund tx, if any
|
||||||
|
final String? lastRefundTxId;
|
||||||
|
|
||||||
const PrepareRefundResponse({
|
const PrepareRefundResponse({
|
||||||
required this.txVsize,
|
required this.txVsize,
|
||||||
required this.txFeeSat,
|
required this.txFeeSat,
|
||||||
this.refundTxId,
|
this.lastRefundTxId,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => txVsize.hashCode ^ txFeeSat.hashCode ^ refundTxId.hashCode;
|
int get hashCode => txVsize.hashCode ^ txFeeSat.hashCode ^ lastRefundTxId.hashCode;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
@@ -1249,7 +1251,7 @@ class PrepareRefundResponse {
|
|||||||
runtimeType == other.runtimeType &&
|
runtimeType == other.runtimeType &&
|
||||||
txVsize == other.txVsize &&
|
txVsize == other.txVsize &&
|
||||||
txFeeSat == other.txFeeSat &&
|
txFeeSat == other.txFeeSat &&
|
||||||
refundTxId == other.refundTxId;
|
lastRefundTxId == other.lastRefundTxId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An argument when calling [crate::sdk::LiquidSdk::prepare_send_payment].
|
/// An argument when calling [crate::sdk::LiquidSdk::prepare_send_payment].
|
||||||
@@ -1440,14 +1442,19 @@ class RefundableSwap {
|
|||||||
/// Amount that is refundable, from all UTXOs
|
/// Amount that is refundable, from all UTXOs
|
||||||
final BigInt amountSat;
|
final BigInt amountSat;
|
||||||
|
|
||||||
|
/// The txid of the last broadcasted refund tx, if any
|
||||||
|
final String? lastRefundTxId;
|
||||||
|
|
||||||
const RefundableSwap({
|
const RefundableSwap({
|
||||||
required this.swapAddress,
|
required this.swapAddress,
|
||||||
required this.timestamp,
|
required this.timestamp,
|
||||||
required this.amountSat,
|
required this.amountSat,
|
||||||
|
this.lastRefundTxId,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => swapAddress.hashCode ^ timestamp.hashCode ^ amountSat.hashCode;
|
int get hashCode =>
|
||||||
|
swapAddress.hashCode ^ timestamp.hashCode ^ amountSat.hashCode ^ lastRefundTxId.hashCode;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
@@ -1456,7 +1463,8 @@ class RefundableSwap {
|
|||||||
runtimeType == other.runtimeType &&
|
runtimeType == other.runtimeType &&
|
||||||
swapAddress == other.swapAddress &&
|
swapAddress == other.swapAddress &&
|
||||||
timestamp == other.timestamp &&
|
timestamp == other.timestamp &&
|
||||||
amountSat == other.amountSat;
|
amountSat == other.amountSat &&
|
||||||
|
lastRefundTxId == other.lastRefundTxId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An argument when calling [crate::sdk::LiquidSdk::restore].
|
/// An argument when calling [crate::sdk::LiquidSdk::restore].
|
||||||
|
|||||||
@@ -5024,6 +5024,8 @@ final class wire_cst_refundable_swap extends ffi.Struct {
|
|||||||
|
|
||||||
@ffi.Uint64()
|
@ffi.Uint64()
|
||||||
external int amount_sat;
|
external int amount_sat;
|
||||||
|
|
||||||
|
external ffi.Pointer<wire_cst_list_prim_u_8_strict> last_refund_tx_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
final class wire_cst_list_refundable_swap extends ffi.Struct {
|
final class wire_cst_list_refundable_swap extends ffi.Struct {
|
||||||
@@ -5459,7 +5461,7 @@ final class wire_cst_prepare_refund_response extends ffi.Struct {
|
|||||||
@ffi.Uint64()
|
@ffi.Uint64()
|
||||||
external int tx_fee_sat;
|
external int tx_fee_sat;
|
||||||
|
|
||||||
external ffi.Pointer<wire_cst_list_prim_u_8_strict> refund_tx_id;
|
external ffi.Pointer<wire_cst_list_prim_u_8_strict> last_refund_tx_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
final class wire_cst_receive_payment_response extends ffi.Struct {
|
final class wire_cst_receive_payment_response extends ffi.Struct {
|
||||||
|
|||||||
@@ -2083,15 +2083,24 @@ fun asPrepareRefundResponse(prepareRefundResponse: ReadableMap): PrepareRefundRe
|
|||||||
}
|
}
|
||||||
val txVsize = prepareRefundResponse.getInt("txVsize").toUInt()
|
val txVsize = prepareRefundResponse.getInt("txVsize").toUInt()
|
||||||
val txFeeSat = prepareRefundResponse.getDouble("txFeeSat").toULong()
|
val txFeeSat = prepareRefundResponse.getDouble("txFeeSat").toULong()
|
||||||
val refundTxId = if (hasNonNullKey(prepareRefundResponse, "refundTxId")) prepareRefundResponse.getString("refundTxId") else null
|
val lastRefundTxId =
|
||||||
return PrepareRefundResponse(txVsize, txFeeSat, refundTxId)
|
if (hasNonNullKey(
|
||||||
|
prepareRefundResponse,
|
||||||
|
"lastRefundTxId",
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
prepareRefundResponse.getString("lastRefundTxId")
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
return PrepareRefundResponse(txVsize, txFeeSat, lastRefundTxId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun readableMapOf(prepareRefundResponse: PrepareRefundResponse): ReadableMap =
|
fun readableMapOf(prepareRefundResponse: PrepareRefundResponse): ReadableMap =
|
||||||
readableMapOf(
|
readableMapOf(
|
||||||
"txVsize" to prepareRefundResponse.txVsize,
|
"txVsize" to prepareRefundResponse.txVsize,
|
||||||
"txFeeSat" to prepareRefundResponse.txFeeSat,
|
"txFeeSat" to prepareRefundResponse.txFeeSat,
|
||||||
"refundTxId" to prepareRefundResponse.refundTxId,
|
"lastRefundTxId" to prepareRefundResponse.lastRefundTxId,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun asPrepareRefundResponseList(arr: ReadableArray): List<PrepareRefundResponse> {
|
fun asPrepareRefundResponseList(arr: ReadableArray): List<PrepareRefundResponse> {
|
||||||
@@ -2399,7 +2408,8 @@ fun asRefundableSwap(refundableSwap: ReadableMap): RefundableSwap? {
|
|||||||
val swapAddress = refundableSwap.getString("swapAddress")!!
|
val swapAddress = refundableSwap.getString("swapAddress")!!
|
||||||
val timestamp = refundableSwap.getInt("timestamp").toUInt()
|
val timestamp = refundableSwap.getInt("timestamp").toUInt()
|
||||||
val amountSat = refundableSwap.getDouble("amountSat").toULong()
|
val amountSat = refundableSwap.getDouble("amountSat").toULong()
|
||||||
return RefundableSwap(swapAddress, timestamp, amountSat)
|
val lastRefundTxId = if (hasNonNullKey(refundableSwap, "lastRefundTxId")) refundableSwap.getString("lastRefundTxId") else null
|
||||||
|
return RefundableSwap(swapAddress, timestamp, amountSat, lastRefundTxId)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun readableMapOf(refundableSwap: RefundableSwap): ReadableMap =
|
fun readableMapOf(refundableSwap: RefundableSwap): ReadableMap =
|
||||||
@@ -2407,6 +2417,7 @@ fun readableMapOf(refundableSwap: RefundableSwap): ReadableMap =
|
|||||||
"swapAddress" to refundableSwap.swapAddress,
|
"swapAddress" to refundableSwap.swapAddress,
|
||||||
"timestamp" to refundableSwap.timestamp,
|
"timestamp" to refundableSwap.timestamp,
|
||||||
"amountSat" to refundableSwap.amountSat,
|
"amountSat" to refundableSwap.amountSat,
|
||||||
|
"lastRefundTxId" to refundableSwap.lastRefundTxId,
|
||||||
)
|
)
|
||||||
|
|
||||||
fun asRefundableSwapList(arr: ReadableArray): List<RefundableSwap> {
|
fun asRefundableSwapList(arr: ReadableArray): List<RefundableSwap> {
|
||||||
|
|||||||
@@ -2399,22 +2399,22 @@ enum BreezSDKLiquidMapper {
|
|||||||
guard let txFeeSat = prepareRefundResponse["txFeeSat"] as? UInt64 else {
|
guard let txFeeSat = prepareRefundResponse["txFeeSat"] as? UInt64 else {
|
||||||
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "txFeeSat", typeName: "PrepareRefundResponse"))
|
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "txFeeSat", typeName: "PrepareRefundResponse"))
|
||||||
}
|
}
|
||||||
var refundTxId: String?
|
var lastRefundTxId: String?
|
||||||
if hasNonNilKey(data: prepareRefundResponse, key: "refundTxId") {
|
if hasNonNilKey(data: prepareRefundResponse, key: "lastRefundTxId") {
|
||||||
guard let refundTxIdTmp = prepareRefundResponse["refundTxId"] as? String else {
|
guard let lastRefundTxIdTmp = prepareRefundResponse["lastRefundTxId"] as? String else {
|
||||||
throw SdkError.Generic(message: errUnexpectedValue(fieldName: "refundTxId"))
|
throw SdkError.Generic(message: errUnexpectedValue(fieldName: "lastRefundTxId"))
|
||||||
}
|
}
|
||||||
refundTxId = refundTxIdTmp
|
lastRefundTxId = lastRefundTxIdTmp
|
||||||
}
|
}
|
||||||
|
|
||||||
return PrepareRefundResponse(txVsize: txVsize, txFeeSat: txFeeSat, refundTxId: refundTxId)
|
return PrepareRefundResponse(txVsize: txVsize, txFeeSat: txFeeSat, lastRefundTxId: lastRefundTxId)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func dictionaryOf(prepareRefundResponse: PrepareRefundResponse) -> [String: Any?] {
|
static func dictionaryOf(prepareRefundResponse: PrepareRefundResponse) -> [String: Any?] {
|
||||||
return [
|
return [
|
||||||
"txVsize": prepareRefundResponse.txVsize,
|
"txVsize": prepareRefundResponse.txVsize,
|
||||||
"txFeeSat": prepareRefundResponse.txFeeSat,
|
"txFeeSat": prepareRefundResponse.txFeeSat,
|
||||||
"refundTxId": prepareRefundResponse.refundTxId == nil ? nil : prepareRefundResponse.refundTxId,
|
"lastRefundTxId": prepareRefundResponse.lastRefundTxId == nil ? nil : prepareRefundResponse.lastRefundTxId,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2750,8 +2750,15 @@ enum BreezSDKLiquidMapper {
|
|||||||
guard let amountSat = refundableSwap["amountSat"] as? UInt64 else {
|
guard let amountSat = refundableSwap["amountSat"] as? UInt64 else {
|
||||||
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "amountSat", typeName: "RefundableSwap"))
|
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "amountSat", typeName: "RefundableSwap"))
|
||||||
}
|
}
|
||||||
|
var lastRefundTxId: String?
|
||||||
|
if hasNonNilKey(data: refundableSwap, key: "lastRefundTxId") {
|
||||||
|
guard let lastRefundTxIdTmp = refundableSwap["lastRefundTxId"] as? String else {
|
||||||
|
throw SdkError.Generic(message: errUnexpectedValue(fieldName: "lastRefundTxId"))
|
||||||
|
}
|
||||||
|
lastRefundTxId = lastRefundTxIdTmp
|
||||||
|
}
|
||||||
|
|
||||||
return RefundableSwap(swapAddress: swapAddress, timestamp: timestamp, amountSat: amountSat)
|
return RefundableSwap(swapAddress: swapAddress, timestamp: timestamp, amountSat: amountSat, lastRefundTxId: lastRefundTxId)
|
||||||
}
|
}
|
||||||
|
|
||||||
static func dictionaryOf(refundableSwap: RefundableSwap) -> [String: Any?] {
|
static func dictionaryOf(refundableSwap: RefundableSwap) -> [String: Any?] {
|
||||||
@@ -2759,6 +2766,7 @@ enum BreezSDKLiquidMapper {
|
|||||||
"swapAddress": refundableSwap.swapAddress,
|
"swapAddress": refundableSwap.swapAddress,
|
||||||
"timestamp": refundableSwap.timestamp,
|
"timestamp": refundableSwap.timestamp,
|
||||||
"amountSat": refundableSwap.amountSat,
|
"amountSat": refundableSwap.amountSat,
|
||||||
|
"lastRefundTxId": refundableSwap.lastRefundTxId == nil ? nil : refundableSwap.lastRefundTxId,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -358,7 +358,7 @@ export interface PrepareRefundRequest {
|
|||||||
export interface PrepareRefundResponse {
|
export interface PrepareRefundResponse {
|
||||||
txVsize: number
|
txVsize: number
|
||||||
txFeeSat: number
|
txFeeSat: number
|
||||||
refundTxId?: string
|
lastRefundTxId?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PrepareSendRequest {
|
export interface PrepareSendRequest {
|
||||||
@@ -408,6 +408,7 @@ export interface RefundableSwap {
|
|||||||
swapAddress: string
|
swapAddress: string
|
||||||
timestamp: number
|
timestamp: number
|
||||||
amountSat: number
|
amountSat: number
|
||||||
|
lastRefundTxId?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RestoreRequest {
|
export interface RestoreRequest {
|
||||||
|
|||||||
Reference in New Issue
Block a user