Multi-asset send/receive (#645)

* Multi-asset send/receive

* Apply suggestions from code review

Co-authored-by: Daniel Granhão <32176319+danielgranhao@users.noreply.github.com>

* Log the prepare asset_id

---------

Co-authored-by: Daniel Granhão <32176319+danielgranhao@users.noreply.github.com>
This commit is contained in:
Ross Savage
2025-01-24 16:55:51 +01:00
committed by GitHub
parent 7841939e6a
commit e196a91973
26 changed files with 2754 additions and 963 deletions

View File

@@ -33,10 +33,16 @@ pub(crate) enum Command {
#[arg(long)]
address: Option<String>,
/// The amount in satoshi to pay, in case of a direct Liquid address
/// or amount-less BIP21
/// The amount to pay, in case of a direct Liquid address or amount-less BIP21.
/// If an asset id is provided, it is the base unit of that asset depending on its
/// precision, otherwise in satoshi.
#[arg(short, long)]
amount_sat: Option<u64>,
receiver_amount: Option<u64>,
/// Optional id of the asset, in case of a direct Liquid address
/// or amount-less BIP21
#[clap(long = "asset")]
asset_id: Option<String>,
/// Whether or not this is a drain operation. If true, all available funds will be used.
#[arg(short, long)]
@@ -72,10 +78,15 @@ pub(crate) enum Command {
#[arg(short = 'm', long = "method")]
payment_method: Option<PaymentMethod>,
/// Amount the payer will send, in satoshi
/// If not specified, it will generate a BIP21 URI/Liquid address with no amount
/// The amount the payer should send. If an asset id is provided, it is the base
/// unit of that asset depending on its precision, otherwise in satoshi.
/// If not specified, it will generate a BIP21 URI/address with no amount.
#[arg(short, long)]
payer_amount_sat: Option<u64>,
payer_amount: Option<u64>,
/// Optional id of the asset to receive when the 'payment_method' is "liquid"
#[clap(long = "asset")]
asset_id: Option<String>,
/// Optional description for the invoice
#[clap(short = 'd', long = "description")]
@@ -118,6 +129,10 @@ pub(crate) enum Command {
#[clap(short = 'o', long = "offset")]
offset: Option<u32>,
/// Optional id of the asset for Liquid payment method
#[clap(long = "asset")]
asset_id: Option<String>,
/// Optional Liquid BIP21 URI/address for Liquid payment method
#[clap(short = 'd', long = "destination")]
destination: Option<String>,
@@ -270,19 +285,29 @@ pub(crate) async fn handle_command(
Ok(match command {
Command::ReceivePayment {
payment_method,
payer_amount_sat,
payer_amount,
asset_id,
description,
use_description_hash,
} => {
let amount = match asset_id {
Some(asset_id) => Some(ReceiveAmount::Asset {
asset_id,
payer_amount,
}),
None => {
payer_amount.map(|payer_amount_sat| ReceiveAmount::Bitcoin { payer_amount_sat })
}
};
let prepare_response = sdk
.prepare_receive_payment(&PrepareReceiveRequest {
payer_amount_sat,
payment_method: payment_method.unwrap_or(PaymentMethod::Lightning),
amount: amount.clone(),
})
.await?;
let fees = prepare_response.fees_sat;
let confirmation_msg = match payer_amount_sat {
let confirmation_msg = match amount {
Some(_) => format!("Fees: {fees} sat. Are the fees acceptable? (y/N)"),
None => {
let min = prepare_response.min_payer_amount_sat;
@@ -336,13 +361,14 @@ pub(crate) async fn handle_command(
invoice,
offer,
address,
amount_sat,
receiver_amount,
asset_id,
drain,
delay,
} => {
let destination = match (invoice, offer, address) {
(Some(invoice), None, None) => Ok(invoice),
(None, Some(offer), None) => match amount_sat {
(None, Some(offer), None) => match receiver_amount {
Some(_) => Ok(offer),
None => Err(anyhow!(
"Must specify an amount for a BOLT12 offer."
@@ -358,10 +384,16 @@ pub(crate) async fn handle_command(
"Must specify either a BOLT11 invoice, a BOLT12 offer or a direct/BIP21 address."
))
}?;
let amount = match (amount_sat, drain.unwrap_or(false)) {
(Some(amount_sat), _) => Some(PayAmount::Receiver { amount_sat }),
(_, true) => Some(PayAmount::Drain),
(_, _) => None,
let amount = match (asset_id, receiver_amount, drain.unwrap_or(false)) {
(Some(asset_id), Some(receiver_amount), _) => Some(PayAmount::Asset {
asset_id,
receiver_amount,
}),
(None, Some(receiver_amount_sat), _) => Some(PayAmount::Bitcoin {
receiver_amount_sat,
}),
(_, _, true) => Some(PayAmount::Drain),
_ => None,
};
let prepare_response = sdk
@@ -404,8 +436,8 @@ pub(crate) async fn handle_command(
} => {
let amount = match drain.unwrap_or(false) {
true => PayAmount::Drain,
false => PayAmount::Receiver {
amount_sat: receiver_amount_sat.ok_or(anyhow::anyhow!(
false => PayAmount::Bitcoin {
receiver_amount_sat: receiver_amount_sat.ok_or(anyhow::anyhow!(
"Must specify `receiver_amount_sat` if not draining"
))?,
},
@@ -492,13 +524,21 @@ pub(crate) async fn handle_command(
to_timestamp,
limit,
offset,
asset_id,
destination,
address,
sort_ascending,
} => {
let details = match (destination, address) {
(Some(destination), None) => Some(ListPaymentDetails::Liquid { destination }),
(None, Some(address)) => Some(ListPaymentDetails::Bitcoin { address }),
let details = match (asset_id.clone(), destination.clone(), address) {
(None, Some(_), None) | (Some(_), None, None) | (Some(_), Some(_), None) => {
Some(ListPaymentDetails::Liquid {
asset_id,
destination,
})
}
(None, None, Some(address)) => Some(ListPaymentDetails::Bitcoin {
address: Some(address),
}),
_ => None,
};

922
lib/Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -4,6 +4,7 @@ import android.content.Context
import breez_sdk_liquid.BindingLiquidSdk
import breez_sdk_liquid.PaymentMethod
import breez_sdk_liquid.PrepareReceiveRequest
import breez_sdk_liquid.ReceiveAmount
import breez_sdk_liquid.ReceivePaymentRequest
import breez_sdk_liquid_notification.Constants.DEFAULT_LNURL_PAY_INVOICE_NOTIFICATION_TITLE
import breez_sdk_liquid_notification.Constants.DEFAULT_LNURL_PAY_METADATA_PLAIN_TEXT
@@ -62,7 +63,7 @@ class LnurlPayInvoiceJob(
DEFAULT_LNURL_PAY_METADATA_PLAIN_TEXT
)
val prepareReceivePaymentRes = liquidSDK.prepareReceivePayment(
PrepareReceiveRequest(PaymentMethod.LIGHTNING, amountSat)
PrepareReceiveRequest(PaymentMethod.LIGHTNING, ReceiveAmount.Bitcoin(amountSat))
)
val receivePaymentResponse = liquidSDK.receivePayment(
ReceivePaymentRequest(

View File

@@ -102,6 +102,7 @@ typedef struct wire_cst_list_payment_state {
} wire_cst_list_payment_state;
typedef struct wire_cst_ListPaymentDetails_Liquid {
struct wire_cst_list_prim_u_8_strict *asset_id;
struct wire_cst_list_prim_u_8_strict *destination;
} wire_cst_ListPaymentDetails_Liquid;
@@ -353,12 +354,18 @@ typedef struct wire_cst_prepare_ln_url_pay_request {
bool *validate_success_action_url;
} wire_cst_prepare_ln_url_pay_request;
typedef struct wire_cst_PayAmount_Receiver {
uint64_t amount_sat;
} wire_cst_PayAmount_Receiver;
typedef struct wire_cst_PayAmount_Bitcoin {
uint64_t receiver_amount_sat;
} wire_cst_PayAmount_Bitcoin;
typedef struct wire_cst_PayAmount_Asset {
struct wire_cst_list_prim_u_8_strict *asset_id;
uint64_t receiver_amount;
} wire_cst_PayAmount_Asset;
typedef union PayAmountKind {
struct wire_cst_PayAmount_Receiver Receiver;
struct wire_cst_PayAmount_Bitcoin Bitcoin;
struct wire_cst_PayAmount_Asset Asset;
} PayAmountKind;
typedef struct wire_cst_pay_amount {
@@ -371,9 +378,28 @@ typedef struct wire_cst_prepare_pay_onchain_request {
uint32_t *fee_rate_sat_per_vbyte;
} wire_cst_prepare_pay_onchain_request;
typedef struct wire_cst_ReceiveAmount_Bitcoin {
uint64_t payer_amount_sat;
} wire_cst_ReceiveAmount_Bitcoin;
typedef struct wire_cst_ReceiveAmount_Asset {
struct wire_cst_list_prim_u_8_strict *asset_id;
uint64_t *payer_amount;
} wire_cst_ReceiveAmount_Asset;
typedef union ReceiveAmountKind {
struct wire_cst_ReceiveAmount_Bitcoin Bitcoin;
struct wire_cst_ReceiveAmount_Asset Asset;
} ReceiveAmountKind;
typedef struct wire_cst_receive_amount {
int32_t tag;
union ReceiveAmountKind kind;
} wire_cst_receive_amount;
typedef struct wire_cst_prepare_receive_request {
uint64_t *payer_amount_sat;
int32_t payment_method;
struct wire_cst_receive_amount *amount;
} wire_cst_prepare_receive_request;
typedef struct wire_cst_prepare_refund_request {
@@ -389,7 +415,7 @@ typedef struct wire_cst_prepare_send_request {
typedef struct wire_cst_prepare_receive_response {
int32_t payment_method;
uint64_t *payer_amount_sat;
struct wire_cst_receive_amount *amount;
uint64_t fees_sat;
uint64_t *min_payer_amount_sat;
uint64_t *max_payer_amount_sat;
@@ -502,6 +528,7 @@ typedef struct wire_cst_PaymentDetails_Lightning {
typedef struct wire_cst_PaymentDetails_Liquid {
struct wire_cst_list_prim_u_8_strict *destination;
struct wire_cst_list_prim_u_8_strict *description;
struct wire_cst_list_prim_u_8_strict *asset_id;
} wire_cst_PaymentDetails_Liquid;
typedef struct wire_cst_PaymentDetails_Bitcoin {
@@ -652,6 +679,16 @@ typedef struct wire_cst_symbol {
uint32_t *position;
} wire_cst_symbol;
typedef struct wire_cst_asset_balance {
struct wire_cst_list_prim_u_8_strict *asset_id;
uint64_t balance;
} wire_cst_asset_balance;
typedef struct wire_cst_list_asset_balance {
struct wire_cst_asset_balance *ptr;
int32_t len;
} wire_cst_list_asset_balance;
typedef struct wire_cst_localized_name {
struct wire_cst_list_prim_u_8_strict *locale;
struct wire_cst_list_prim_u_8_strict *name;
@@ -735,6 +772,7 @@ typedef struct wire_cst_wallet_info {
uint64_t pending_receive_sat;
struct wire_cst_list_prim_u_8_strict *fingerprint;
struct wire_cst_list_prim_u_8_strict *pubkey;
struct wire_cst_list_asset_balance *asset_balances;
} wire_cst_wallet_info;
typedef struct wire_cst_get_info_response {
@@ -1343,6 +1381,8 @@ struct wire_cst_prepare_refund_request *frbgen_breez_liquid_cst_new_box_autoadd_
struct wire_cst_prepare_send_request *frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_request(void);
struct wire_cst_receive_amount *frbgen_breez_liquid_cst_new_box_autoadd_receive_amount(void);
struct wire_cst_receive_payment_request *frbgen_breez_liquid_cst_new_box_autoadd_receive_payment_request(void);
struct wire_cst_refund_request *frbgen_breez_liquid_cst_new_box_autoadd_refund_request(void);
@@ -1369,6 +1409,8 @@ struct wire_cst_url_success_action_data *frbgen_breez_liquid_cst_new_box_autoadd
struct wire_cst_list_String *frbgen_breez_liquid_cst_new_list_String(int32_t len);
struct wire_cst_list_asset_balance *frbgen_breez_liquid_cst_new_list_asset_balance(int32_t len);
struct wire_cst_list_external_input_parser *frbgen_breez_liquid_cst_new_list_external_input_parser(int32_t len);
struct wire_cst_list_fiat_currency *frbgen_breez_liquid_cst_new_list_fiat_currency(int32_t len);
@@ -1437,6 +1479,7 @@ static int64_t dummy_method_to_enforce_bundling(void) {
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_receive_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_refund_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_receive_amount);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_receive_payment_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_refund_request);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_restore_request);
@@ -1450,6 +1493,7 @@ static int64_t dummy_method_to_enforce_bundling(void) {
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_u_64);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_box_autoadd_url_success_action_data);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_list_String);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_list_asset_balance);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_list_external_input_parser);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_list_fiat_currency);
dummy_var ^= ((int64_t) (void*) frbgen_breez_liquid_cst_new_list_ln_offer_blinded_path);

View File

@@ -45,7 +45,8 @@ class LnurlPayInvoiceTask : LnurlPayTask {
}
let plainTextMetadata = ResourceHelper.shared.getString(key: Constants.LNURL_PAY_METADATA_PLAIN_TEXT, fallback: Constants.DEFAULT_LNURL_PAY_METADATA_PLAIN_TEXT)
let metadata = "[[\"text/plain\",\"\(plainTextMetadata)\"]]"
let prepareReceivePaymentRes = try liquidSDK.prepareReceivePayment(req: PrepareReceiveRequest(paymentMethod: PaymentMethod.lightning, payerAmountSat: amountSat))
let amount = ReceiveAmount.bitcoin(payerAmountSat: amountSat)
let prepareReceivePaymentRes = try liquidSDK.prepareReceivePayment(req: PrepareReceiveRequest(paymentMethod: PaymentMethod.lightning, amount: amount))
let receivePaymentRes = try liquidSDK.receivePayment(req: ReceivePaymentRequest(prepareResponse: prepareReceivePaymentRes, description: metadata, useDescriptionHash: true))
self.replyServer(encodable: LnurlInvoiceResponse(pr: receivePaymentRes.destination, routes: []), replyURL: request!.reply_url)
} catch let e {

View File

@@ -355,6 +355,11 @@ dictionary ConnectWithSignerRequest {
Config config;
};
dictionary AssetBalance {
string asset_id;
u64 balance;
};
dictionary BlockchainInfo {
u32 liquid_tip;
u32 bitcoin_tip;
@@ -366,6 +371,7 @@ dictionary WalletInfo {
u64 pending_receive_sat;
string fingerprint;
string pubkey;
sequence<AssetBalance> asset_balances;
};
dictionary GetInfoResponse {
@@ -441,15 +447,21 @@ enum PaymentMethod {
"LiquidAddress",
};
[Enum]
interface ReceiveAmount {
Bitcoin(u64 payer_amount_sat);
Asset(string asset_id, u64? payer_amount);
};
dictionary PrepareReceiveRequest {
PaymentMethod payment_method;
u64? payer_amount_sat = null;
ReceiveAmount? amount = null;
};
dictionary PrepareReceiveResponse {
PaymentMethod payment_method;
u64 fees_sat;
u64? payer_amount_sat;
ReceiveAmount? amount;
u64? min_payer_amount_sat;
u64? max_payer_amount_sat;
f64? swapper_feerate;
@@ -483,7 +495,8 @@ dictionary OnchainPaymentLimitsResponse {
[Enum]
interface PayAmount {
Receiver(u64 amount_sat);
Bitcoin(u64 receiver_amount_sat);
Asset(string asset_id, u64 receiver_amount);
Drain();
};
@@ -544,8 +557,8 @@ dictionary ListPaymentsRequest {
[Enum]
interface ListPaymentDetails {
Liquid(string destination);
Bitcoin(string address);
Liquid(string? asset_id, string? destination);
Bitcoin(string? address);
};
[Enum]
@@ -581,7 +594,7 @@ dictionary LnUrlInfo {
[Enum]
interface PaymentDetails {
Lightning(string swap_id, string description, u32 liquid_expiration_blockheight, string? preimage, string? invoice, string? bolt12_offer, string? payment_hash, string? destination_pubkey, LnUrlInfo? lnurl_info, string? refund_tx_id, u64? refund_tx_amount_sat);
Liquid(string destination, string description);
Liquid(string asset_id, string destination, string description);
Bitcoin(string swap_id, string description, boolean auto_accepted_fees, u32? bitcoin_expiration_blockheight, u32? liquid_expiration_blockheight, string? refund_tx_id, u64? refund_tx_amount_sat);
};

View File

@@ -538,9 +538,9 @@ impl ChainSwapHandler {
self.persister.insert_or_update_payment(PaymentTxData {
tx_id: lockup_tx_id.clone(),
timestamp: Some(utils::now()),
amount_sat: swap.receiver_amount_sat,
// This should be: boltz fee + lockup fee + claim fee
fees_sat: lockup_tx_fees_sat + swap.claim_fees_sat,
asset_id: self.config.lbtc_asset_id().to_string(),
amount: create_response.lockup_details.amount,
fees_sat: lockup_tx_fees_sat,
payment_type: PaymentType::Send,
is_confirmed: false,
unblinding_data: None,
@@ -753,6 +753,7 @@ impl ChainSwapHandler {
.build_tx_or_drain_tx(
Some(LIQUID_FEE_RATE_MSAT_PER_VBYTE),
&lockup_details.lockup_address,
&self.config.lbtc_asset_id().to_string(),
lockup_details.amount,
)
.await?;
@@ -877,7 +878,8 @@ impl ChainSwapHandler {
PaymentTxData {
tx_id: claim_tx_id.clone(),
timestamp: Some(utils::now()),
amount_sat: swap.receiver_amount_sat,
asset_id: self.config.lbtc_asset_id().to_string(),
amount: swap.receiver_amount_sat,
fees_sat: 0,
payment_type: PaymentType::Receive,
is_confirmed: false,

View File

@@ -2379,6 +2379,18 @@ impl SseDecode for crate::bindings::Amount {
}
}
impl SseDecode for crate::model::AssetBalance {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_assetId = <String>::sse_decode(deserializer);
let mut var_balance = <u64>::sse_decode(deserializer);
return crate::model::AssetBalance {
asset_id: var_assetId,
balance: var_balance,
};
}
}
impl SseDecode for crate::model::BackupRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -2794,6 +2806,18 @@ impl SseDecode for Vec<String> {
}
}
impl SseDecode for Vec<crate::model::AssetBalance> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut len_ = <i32>::sse_decode(deserializer);
let mut ans_ = vec![];
for idx_ in 0..len_ {
ans_.push(<crate::model::AssetBalance>::sse_decode(deserializer));
}
return ans_;
}
}
impl SseDecode for Vec<crate::bindings::ExternalInputParser> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -2876,13 +2900,15 @@ impl SseDecode for crate::model::ListPaymentDetails {
let mut tag_ = <i32>::sse_decode(deserializer);
match tag_ {
0 => {
let mut var_destination = <String>::sse_decode(deserializer);
let mut var_assetId = <Option<String>>::sse_decode(deserializer);
let mut var_destination = <Option<String>>::sse_decode(deserializer);
return crate::model::ListPaymentDetails::Liquid {
asset_id: var_assetId,
destination: var_destination,
};
}
1 => {
let mut var_address = <String>::sse_decode(deserializer);
let mut var_address = <Option<String>>::sse_decode(deserializer);
return crate::model::ListPaymentDetails::Bitcoin {
address: var_address,
};
@@ -3607,6 +3633,17 @@ impl SseDecode for Option<crate::model::Payment> {
}
}
impl SseDecode for Option<crate::model::ReceiveAmount> {
// 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::ReceiveAmount>::sse_decode(deserializer));
} else {
return None;
}
}
}
impl SseDecode for Option<crate::bindings::SuccessAction> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -3705,12 +3742,20 @@ impl SseDecode for crate::model::PayAmount {
let mut tag_ = <i32>::sse_decode(deserializer);
match tag_ {
0 => {
let mut var_amountSat = <u64>::sse_decode(deserializer);
return crate::model::PayAmount::Receiver {
amount_sat: var_amountSat,
let mut var_receiverAmountSat = <u64>::sse_decode(deserializer);
return crate::model::PayAmount::Bitcoin {
receiver_amount_sat: var_receiverAmountSat,
};
}
1 => {
let mut var_assetId = <String>::sse_decode(deserializer);
let mut var_receiverAmount = <u64>::sse_decode(deserializer);
return crate::model::PayAmount::Asset {
asset_id: var_assetId,
receiver_amount: var_receiverAmount,
};
}
2 => {
return crate::model::PayAmount::Drain;
}
_ => {
@@ -3795,9 +3840,11 @@ impl SseDecode for crate::model::PaymentDetails {
1 => {
let mut var_destination = <String>::sse_decode(deserializer);
let mut var_description = <String>::sse_decode(deserializer);
let mut var_assetId = <String>::sse_decode(deserializer);
return crate::model::PaymentDetails::Liquid {
destination: var_destination,
description: var_description,
asset_id: var_assetId,
};
}
2 => {
@@ -4047,11 +4094,11 @@ impl SseDecode for crate::model::PreparePayOnchainResponse {
impl SseDecode for crate::model::PrepareReceiveRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_payerAmountSat = <Option<u64>>::sse_decode(deserializer);
let mut var_paymentMethod = <crate::model::PaymentMethod>::sse_decode(deserializer);
let mut var_amount = <Option<crate::model::ReceiveAmount>>::sse_decode(deserializer);
return crate::model::PrepareReceiveRequest {
payer_amount_sat: var_payerAmountSat,
payment_method: var_paymentMethod,
amount: var_amount,
};
}
}
@@ -4060,14 +4107,14 @@ impl SseDecode for crate::model::PrepareReceiveResponse {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut var_paymentMethod = <crate::model::PaymentMethod>::sse_decode(deserializer);
let mut var_payerAmountSat = <Option<u64>>::sse_decode(deserializer);
let mut var_amount = <Option<crate::model::ReceiveAmount>>::sse_decode(deserializer);
let mut var_feesSat = <u64>::sse_decode(deserializer);
let mut var_minPayerAmountSat = <Option<u64>>::sse_decode(deserializer);
let mut var_maxPayerAmountSat = <Option<u64>>::sse_decode(deserializer);
let mut var_swapperFeerate = <Option<f64>>::sse_decode(deserializer);
return crate::model::PrepareReceiveResponse {
payment_method: var_paymentMethod,
payer_amount_sat: var_payerAmountSat,
amount: var_amount,
fees_sat: var_feesSat,
min_payer_amount_sat: var_minPayerAmountSat,
max_payer_amount_sat: var_maxPayerAmountSat,
@@ -4140,6 +4187,32 @@ impl SseDecode for crate::bindings::Rate {
}
}
impl SseDecode for crate::model::ReceiveAmount {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
let mut tag_ = <i32>::sse_decode(deserializer);
match tag_ {
0 => {
let mut var_payerAmountSat = <u64>::sse_decode(deserializer);
return crate::model::ReceiveAmount::Bitcoin {
payer_amount_sat: var_payerAmountSat,
};
}
1 => {
let mut var_assetId = <String>::sse_decode(deserializer);
let mut var_payerAmount = <Option<u64>>::sse_decode(deserializer);
return crate::model::ReceiveAmount::Asset {
asset_id: var_assetId,
payer_amount: var_payerAmount,
};
}
_ => {
unimplemented!("");
}
}
}
}
impl SseDecode for crate::model::ReceivePaymentRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_decode(deserializer: &mut flutter_rust_bridge::for_generated::SseDeserializer) -> Self {
@@ -4557,12 +4630,14 @@ impl SseDecode for crate::model::WalletInfo {
let mut var_pendingReceiveSat = <u64>::sse_decode(deserializer);
let mut var_fingerprint = <String>::sse_decode(deserializer);
let mut var_pubkey = <String>::sse_decode(deserializer);
let mut var_assetBalances = <Vec<crate::model::AssetBalance>>::sse_decode(deserializer);
return crate::model::WalletInfo {
balance_sat: var_balanceSat,
pending_send_sat: var_pendingSendSat,
pending_receive_sat: var_pendingReceiveSat,
fingerprint: var_fingerprint,
pubkey: var_pubkey,
asset_balances: var_assetBalances,
};
}
}
@@ -4730,6 +4805,22 @@ impl flutter_rust_bridge::IntoIntoDart<FrbWrapper<crate::bindings::Amount>>
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::AssetBalance {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.asset_id.into_into_dart().into_dart(),
self.balance.into_into_dart().into_dart(),
]
.into_dart()
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::model::AssetBalance {}
impl flutter_rust_bridge::IntoIntoDart<crate::model::AssetBalance> for crate::model::AssetBalance {
fn into_into_dart(self) -> crate::model::AssetBalance {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::BackupRequest {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[self.backup_path.into_into_dart().into_dart()].into_dart()
@@ -5221,9 +5312,15 @@ impl flutter_rust_bridge::IntoIntoDart<crate::model::LiquidNetwork>
impl flutter_rust_bridge::IntoDart for crate::model::ListPaymentDetails {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
match self {
crate::model::ListPaymentDetails::Liquid { destination } => {
[0.into_dart(), destination.into_into_dart().into_dart()].into_dart()
}
crate::model::ListPaymentDetails::Liquid {
asset_id,
destination,
} => [
0.into_dart(),
asset_id.into_into_dart().into_dart(),
destination.into_into_dart().into_dart(),
]
.into_dart(),
crate::model::ListPaymentDetails::Bitcoin { address } => {
[1.into_dart(), address.into_into_dart().into_dart()].into_dart()
}
@@ -5889,10 +5986,23 @@ impl flutter_rust_bridge::IntoIntoDart<crate::model::OnchainPaymentLimitsRespons
impl flutter_rust_bridge::IntoDart for crate::model::PayAmount {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
match self {
crate::model::PayAmount::Receiver { amount_sat } => {
[0.into_dart(), amount_sat.into_into_dart().into_dart()].into_dart()
}
crate::model::PayAmount::Drain => [1.into_dart()].into_dart(),
crate::model::PayAmount::Bitcoin {
receiver_amount_sat,
} => [
0.into_dart(),
receiver_amount_sat.into_into_dart().into_dart(),
]
.into_dart(),
crate::model::PayAmount::Asset {
asset_id,
receiver_amount,
} => [
1.into_dart(),
asset_id.into_into_dart().into_dart(),
receiver_amount.into_into_dart().into_dart(),
]
.into_dart(),
crate::model::PayAmount::Drain => [2.into_dart()].into_dart(),
_ => {
unimplemented!("");
}
@@ -5984,10 +6094,12 @@ impl flutter_rust_bridge::IntoDart for crate::model::PaymentDetails {
crate::model::PaymentDetails::Liquid {
destination,
description,
asset_id,
} => [
1.into_dart(),
destination.into_into_dart().into_dart(),
description.into_into_dart().into_dart(),
asset_id.into_into_dart().into_dart(),
]
.into_dart(),
crate::model::PaymentDetails::Bitcoin {
@@ -6279,8 +6391,8 @@ impl flutter_rust_bridge::IntoIntoDart<crate::model::PreparePayOnchainResponse>
impl flutter_rust_bridge::IntoDart for crate::model::PrepareReceiveRequest {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.payer_amount_sat.into_into_dart().into_dart(),
self.payment_method.into_into_dart().into_dart(),
self.amount.into_into_dart().into_dart(),
]
.into_dart()
}
@@ -6301,7 +6413,7 @@ impl flutter_rust_bridge::IntoDart for crate::model::PrepareReceiveResponse {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
self.payment_method.into_into_dart().into_dart(),
self.payer_amount_sat.into_into_dart().into_dart(),
self.amount.into_into_dart().into_dart(),
self.fees_sat.into_into_dart().into_dart(),
self.min_payer_amount_sat.into_into_dart().into_dart(),
self.max_payer_amount_sat.into_into_dart().into_dart(),
@@ -6429,6 +6541,36 @@ impl flutter_rust_bridge::IntoIntoDart<FrbWrapper<crate::bindings::Rate>>
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::ReceiveAmount {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
match self {
crate::model::ReceiveAmount::Bitcoin { payer_amount_sat } => {
[0.into_dart(), payer_amount_sat.into_into_dart().into_dart()].into_dart()
}
crate::model::ReceiveAmount::Asset {
asset_id,
payer_amount,
} => [
1.into_dart(),
asset_id.into_into_dart().into_dart(),
payer_amount.into_into_dart().into_dart(),
]
.into_dart(),
_ => {
unimplemented!("");
}
}
}
}
impl flutter_rust_bridge::for_generated::IntoDartExceptPrimitive for crate::model::ReceiveAmount {}
impl flutter_rust_bridge::IntoIntoDart<crate::model::ReceiveAmount>
for crate::model::ReceiveAmount
{
fn into_into_dart(self) -> crate::model::ReceiveAmount {
self
}
}
// Codec=Dco (DartCObject based), see doc to use other codecs
impl flutter_rust_bridge::IntoDart for crate::model::ReceivePaymentRequest {
fn into_dart(self) -> flutter_rust_bridge::for_generated::DartAbi {
[
@@ -6881,6 +7023,7 @@ impl flutter_rust_bridge::IntoDart for crate::model::WalletInfo {
self.pending_receive_sat.into_into_dart().into_dart(),
self.fingerprint.into_into_dart().into_dart(),
self.pubkey.into_into_dart().into_dart(),
self.asset_balances.into_into_dart().into_dart(),
]
.into_dart()
}
@@ -7008,6 +7151,14 @@ impl SseEncode for crate::bindings::Amount {
}
}
impl SseEncode for crate::model::AssetBalance {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<String>::sse_encode(self.asset_id, serializer);
<u64>::sse_encode(self.balance, serializer);
}
}
impl SseEncode for crate::model::BackupRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@@ -7315,6 +7466,16 @@ impl SseEncode for Vec<String> {
}
}
impl SseEncode for Vec<crate::model::AssetBalance> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<i32>::sse_encode(self.len() as _, serializer);
for item in self {
<crate::model::AssetBalance>::sse_encode(item, serializer);
}
}
}
impl SseEncode for Vec<crate::bindings::ExternalInputParser> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@@ -7379,13 +7540,17 @@ impl SseEncode for crate::model::ListPaymentDetails {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
match self {
crate::model::ListPaymentDetails::Liquid { destination } => {
crate::model::ListPaymentDetails::Liquid {
asset_id,
destination,
} => {
<i32>::sse_encode(0, serializer);
<String>::sse_encode(destination, serializer);
<Option<String>>::sse_encode(asset_id, serializer);
<Option<String>>::sse_encode(destination, serializer);
}
crate::model::ListPaymentDetails::Bitcoin { address } => {
<i32>::sse_encode(1, serializer);
<String>::sse_encode(address, serializer);
<Option<String>>::sse_encode(address, serializer);
}
_ => {
unimplemented!("");
@@ -7953,6 +8118,16 @@ impl SseEncode for Option<crate::model::Payment> {
}
}
impl SseEncode for Option<crate::model::ReceiveAmount> {
// 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::ReceiveAmount>::sse_encode(value, serializer);
}
}
}
impl SseEncode for Option<crate::bindings::SuccessAction> {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@@ -8037,12 +8212,22 @@ impl SseEncode for 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) {
match self {
crate::model::PayAmount::Receiver { amount_sat } => {
crate::model::PayAmount::Bitcoin {
receiver_amount_sat,
} => {
<i32>::sse_encode(0, serializer);
<u64>::sse_encode(amount_sat, serializer);
<u64>::sse_encode(receiver_amount_sat, serializer);
}
crate::model::PayAmount::Asset {
asset_id,
receiver_amount,
} => {
<i32>::sse_encode(1, serializer);
<String>::sse_encode(asset_id, serializer);
<u64>::sse_encode(receiver_amount, serializer);
}
crate::model::PayAmount::Drain => {
<i32>::sse_encode(1, serializer);
<i32>::sse_encode(2, serializer);
}
_ => {
unimplemented!("");
@@ -8108,10 +8293,12 @@ impl SseEncode for crate::model::PaymentDetails {
crate::model::PaymentDetails::Liquid {
destination,
description,
asset_id,
} => {
<i32>::sse_encode(1, serializer);
<String>::sse_encode(destination, serializer);
<String>::sse_encode(description, serializer);
<String>::sse_encode(asset_id, serializer);
}
crate::model::PaymentDetails::Bitcoin {
swap_id,
@@ -8336,8 +8523,8 @@ impl SseEncode for crate::model::PreparePayOnchainResponse {
impl SseEncode for crate::model::PrepareReceiveRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<Option<u64>>::sse_encode(self.payer_amount_sat, serializer);
<crate::model::PaymentMethod>::sse_encode(self.payment_method, serializer);
<Option<crate::model::ReceiveAmount>>::sse_encode(self.amount, serializer);
}
}
@@ -8345,7 +8532,7 @@ impl SseEncode for crate::model::PrepareReceiveResponse {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
<crate::model::PaymentMethod>::sse_encode(self.payment_method, serializer);
<Option<u64>>::sse_encode(self.payer_amount_sat, serializer);
<Option<crate::model::ReceiveAmount>>::sse_encode(self.amount, serializer);
<u64>::sse_encode(self.fees_sat, serializer);
<Option<u64>>::sse_encode(self.min_payer_amount_sat, serializer);
<Option<u64>>::sse_encode(self.max_payer_amount_sat, serializer);
@@ -8395,6 +8582,29 @@ impl SseEncode for crate::bindings::Rate {
}
}
impl SseEncode for crate::model::ReceiveAmount {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
match self {
crate::model::ReceiveAmount::Bitcoin { payer_amount_sat } => {
<i32>::sse_encode(0, serializer);
<u64>::sse_encode(payer_amount_sat, serializer);
}
crate::model::ReceiveAmount::Asset {
asset_id,
payer_amount,
} => {
<i32>::sse_encode(1, serializer);
<String>::sse_encode(asset_id, serializer);
<Option<u64>>::sse_encode(payer_amount, serializer);
}
_ => {
unimplemented!("");
}
}
}
}
impl SseEncode for crate::model::ReceivePaymentRequest {
// Codec=Sse (Serialization based), see doc to use other codecs
fn sse_encode(self, serializer: &mut flutter_rust_bridge::for_generated::SseSerializer) {
@@ -8717,6 +8927,7 @@ impl SseEncode for crate::model::WalletInfo {
<u64>::sse_encode(self.pending_receive_sat, serializer);
<String>::sse_encode(self.fingerprint, serializer);
<String>::sse_encode(self.pubkey, serializer);
<Vec<crate::model::AssetBalance>>::sse_encode(self.asset_balances, serializer);
}
}
@@ -8882,6 +9093,15 @@ mod io {
}
}
}
impl CstDecode<crate::model::AssetBalance> for wire_cst_asset_balance {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::AssetBalance {
crate::model::AssetBalance {
asset_id: self.asset_id.cst_decode(),
balance: self.balance.cst_decode(),
}
}
}
impl CstDecode<crate::model::BackupRequest> for wire_cst_backup_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::BackupRequest {
@@ -9222,6 +9442,13 @@ mod io {
CstDecode::<crate::model::PrepareSendRequest>::cst_decode(*wrap).into()
}
}
impl CstDecode<crate::model::ReceiveAmount> for *mut wire_cst_receive_amount {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::ReceiveAmount {
let wrap = unsafe { flutter_rust_bridge::for_generated::box_from_leak_ptr(self) };
CstDecode::<crate::model::ReceiveAmount>::cst_decode(*wrap).into()
}
}
impl CstDecode<crate::model::ReceivePaymentRequest> for *mut wire_cst_receive_payment_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::ReceivePaymentRequest {
@@ -9556,6 +9783,16 @@ mod io {
vec.into_iter().map(CstDecode::cst_decode).collect()
}
}
impl CstDecode<Vec<crate::model::AssetBalance>> for *mut wire_cst_list_asset_balance {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> Vec<crate::model::AssetBalance> {
let vec = unsafe {
let wrap = flutter_rust_bridge::for_generated::box_from_leak_ptr(self);
flutter_rust_bridge::for_generated::vec_from_leak_ptr(wrap.ptr, wrap.len)
};
vec.into_iter().map(CstDecode::cst_decode).collect()
}
}
impl CstDecode<Vec<crate::bindings::ExternalInputParser>>
for *mut wire_cst_list_external_input_parser
{
@@ -9627,6 +9864,7 @@ mod io {
0 => {
let ans = unsafe { self.kind.Liquid };
crate::model::ListPaymentDetails::Liquid {
asset_id: ans.asset_id.cst_decode(),
destination: ans.destination.cst_decode(),
}
}
@@ -10145,12 +10383,19 @@ mod io {
fn cst_decode(self) -> crate::model::PayAmount {
match self.tag {
0 => {
let ans = unsafe { self.kind.Receiver };
crate::model::PayAmount::Receiver {
amount_sat: ans.amount_sat.cst_decode(),
let ans = unsafe { self.kind.Bitcoin };
crate::model::PayAmount::Bitcoin {
receiver_amount_sat: ans.receiver_amount_sat.cst_decode(),
}
}
1 => crate::model::PayAmount::Drain,
1 => {
let ans = unsafe { self.kind.Asset };
crate::model::PayAmount::Asset {
asset_id: ans.asset_id.cst_decode(),
receiver_amount: ans.receiver_amount.cst_decode(),
}
}
2 => crate::model::PayAmount::Drain,
_ => unreachable!(),
}
}
@@ -10208,6 +10453,7 @@ mod io {
crate::model::PaymentDetails::Liquid {
destination: ans.destination.cst_decode(),
description: ans.description.cst_decode(),
asset_id: ans.asset_id.cst_decode(),
}
}
2 => {
@@ -10375,8 +10621,8 @@ mod io {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::PrepareReceiveRequest {
crate::model::PrepareReceiveRequest {
payer_amount_sat: self.payer_amount_sat.cst_decode(),
payment_method: self.payment_method.cst_decode(),
amount: self.amount.cst_decode(),
}
}
}
@@ -10385,7 +10631,7 @@ mod io {
fn cst_decode(self) -> crate::model::PrepareReceiveResponse {
crate::model::PrepareReceiveResponse {
payment_method: self.payment_method.cst_decode(),
payer_amount_sat: self.payer_amount_sat.cst_decode(),
amount: self.amount.cst_decode(),
fees_sat: self.fees_sat.cst_decode(),
min_payer_amount_sat: self.min_payer_amount_sat.cst_decode(),
max_payer_amount_sat: self.max_payer_amount_sat.cst_decode(),
@@ -10440,6 +10686,27 @@ mod io {
}
}
}
impl CstDecode<crate::model::ReceiveAmount> for wire_cst_receive_amount {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::ReceiveAmount {
match self.tag {
0 => {
let ans = unsafe { self.kind.Bitcoin };
crate::model::ReceiveAmount::Bitcoin {
payer_amount_sat: ans.payer_amount_sat.cst_decode(),
}
}
1 => {
let ans = unsafe { self.kind.Asset };
crate::model::ReceiveAmount::Asset {
asset_id: ans.asset_id.cst_decode(),
payer_amount: ans.payer_amount.cst_decode(),
}
}
_ => unreachable!(),
}
}
}
impl CstDecode<crate::model::ReceivePaymentRequest> for wire_cst_receive_payment_request {
// Codec=Cst (C-struct based), see doc to use other codecs
fn cst_decode(self) -> crate::model::ReceivePaymentRequest {
@@ -10749,6 +11016,7 @@ mod io {
pending_receive_sat: self.pending_receive_sat.cst_decode(),
fingerprint: self.fingerprint.cst_decode(),
pubkey: self.pubkey.cst_decode(),
asset_balances: self.asset_balances.cst_decode(),
}
}
}
@@ -10817,6 +11085,19 @@ mod io {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_asset_balance {
fn new_with_null_ptr() -> Self {
Self {
asset_id: core::ptr::null_mut(),
balance: Default::default(),
}
}
}
impl Default for wire_cst_asset_balance {
fn default() -> Self {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_backup_request {
fn new_with_null_ptr() -> Self {
Self {
@@ -11637,8 +11918,8 @@ mod io {
impl NewWithNullPtr for wire_cst_prepare_receive_request {
fn new_with_null_ptr() -> Self {
Self {
payer_amount_sat: core::ptr::null_mut(),
payment_method: Default::default(),
amount: core::ptr::null_mut(),
}
}
}
@@ -11651,7 +11932,7 @@ mod io {
fn new_with_null_ptr() -> Self {
Self {
payment_method: Default::default(),
payer_amount_sat: core::ptr::null_mut(),
amount: core::ptr::null_mut(),
fees_sat: Default::default(),
min_payer_amount_sat: core::ptr::null_mut(),
max_payer_amount_sat: core::ptr::null_mut(),
@@ -11731,6 +12012,19 @@ mod io {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_receive_amount {
fn new_with_null_ptr() -> Self {
Self {
tag: -1,
kind: ReceiveAmountKind { nil__: () },
}
}
}
impl Default for wire_cst_receive_amount {
fn default() -> Self {
Self::new_with_null_ptr()
}
}
impl NewWithNullPtr for wire_cst_receive_payment_request {
fn new_with_null_ptr() -> Self {
Self {
@@ -12006,6 +12300,7 @@ mod io {
pending_receive_sat: Default::default(),
fingerprint: core::ptr::null_mut(),
pubkey: core::ptr::null_mut(),
asset_balances: core::ptr::null_mut(),
}
}
}
@@ -12699,6 +12994,14 @@ mod io {
)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_receive_amount(
) -> *mut wire_cst_receive_amount {
flutter_rust_bridge::for_generated::new_leak_box_ptr(
wire_cst_receive_amount::new_with_null_ptr(),
)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_box_autoadd_receive_payment_request(
) -> *mut wire_cst_receive_payment_request {
@@ -12798,6 +13101,20 @@ mod io {
flutter_rust_bridge::for_generated::new_leak_box_ptr(wrap)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_list_asset_balance(
len: i32,
) -> *mut wire_cst_list_asset_balance {
let wrap = wire_cst_list_asset_balance {
ptr: flutter_rust_bridge::for_generated::new_leak_vec_ptr(
<wire_cst_asset_balance>::new_with_null_ptr(),
len,
),
len,
};
flutter_rust_bridge::for_generated::new_leak_box_ptr(wrap)
}
#[no_mangle]
pub extern "C" fn frbgen_breez_liquid_cst_new_list_external_input_parser(
len: i32,
@@ -13036,6 +13353,12 @@ mod io {
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_asset_balance {
asset_id: *mut wire_cst_list_prim_u_8_strict,
balance: u64,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_backup_request {
backup_path: *mut wire_cst_list_prim_u_8_strict,
}
@@ -13263,6 +13586,12 @@ mod io {
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_list_asset_balance {
ptr: *mut wire_cst_asset_balance,
len: i32,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_list_external_input_parser {
ptr: *mut wire_cst_external_input_parser,
len: i32,
@@ -13313,6 +13642,7 @@ mod io {
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_ListPaymentDetails_Liquid {
asset_id: *mut wire_cst_list_prim_u_8_strict,
destination: *mut wire_cst_list_prim_u_8_strict,
}
#[repr(C)]
@@ -13749,13 +14079,20 @@ mod io {
#[repr(C)]
#[derive(Clone, Copy)]
pub union PayAmountKind {
Receiver: wire_cst_PayAmount_Receiver,
Bitcoin: wire_cst_PayAmount_Bitcoin,
Asset: wire_cst_PayAmount_Asset,
nil__: (),
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_PayAmount_Receiver {
amount_sat: u64,
pub struct wire_cst_PayAmount_Bitcoin {
receiver_amount_sat: u64,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_PayAmount_Asset {
asset_id: *mut wire_cst_list_prim_u_8_strict,
receiver_amount: u64,
}
#[repr(C)]
#[derive(Clone, Copy)]
@@ -13811,6 +14148,7 @@ mod io {
pub struct wire_cst_PaymentDetails_Liquid {
destination: *mut wire_cst_list_prim_u_8_strict,
description: *mut wire_cst_list_prim_u_8_strict,
asset_id: *mut wire_cst_list_prim_u_8_strict,
}
#[repr(C)]
#[derive(Clone, Copy)]
@@ -13941,14 +14279,14 @@ mod io {
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_prepare_receive_request {
payer_amount_sat: *mut u64,
payment_method: i32,
amount: *mut wire_cst_receive_amount,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_prepare_receive_response {
payment_method: i32,
payer_amount_sat: *mut u64,
amount: *mut wire_cst_receive_amount,
fees_sat: u64,
min_payer_amount_sat: *mut u64,
max_payer_amount_sat: *mut u64,
@@ -13988,6 +14326,30 @@ mod io {
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_receive_amount {
tag: i32,
kind: ReceiveAmountKind,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub union ReceiveAmountKind {
Bitcoin: wire_cst_ReceiveAmount_Bitcoin,
Asset: wire_cst_ReceiveAmount_Asset,
nil__: (),
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_ReceiveAmount_Bitcoin {
payer_amount_sat: u64,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_ReceiveAmount_Asset {
asset_id: *mut wire_cst_list_prim_u_8_strict,
payer_amount: *mut u64,
}
#[repr(C)]
#[derive(Clone, Copy)]
pub struct wire_cst_receive_payment_request {
prepare_response: wire_cst_prepare_receive_response,
description: *mut wire_cst_list_prim_u_8_strict,
@@ -14261,6 +14623,7 @@ mod io {
pending_receive_sat: u64,
fingerprint: *mut wire_cst_list_prim_u_8_strict,
pubkey: *mut wire_cst_list_prim_u_8_strict,
asset_balances: *mut wire_cst_list_asset_balance,
}
}
#[cfg(not(target_family = "wasm"))]

View File

@@ -136,6 +136,10 @@ impl Config {
.unwrap_or(DEFAULT_ZERO_CONF_MAX_SAT)
}
pub(crate) fn lbtc_asset_id(&self) -> String {
utils::lbtc_asset_id(self.network).to_string()
}
pub(crate) fn get_all_external_input_parsers(&self) -> Vec<ExternalInputParser> {
let mut external_input_parsers = Vec::new();
if self.use_default_external_input_parsers {
@@ -337,18 +341,32 @@ pub enum PaymentMethod {
LiquidAddress,
}
#[derive(Debug, Serialize, Clone)]
pub enum ReceiveAmount {
/// The amount in satoshi that should be paid
Bitcoin { payer_amount_sat: u64 },
/// The amount of an asset that should be paid
Asset {
asset_id: String,
payer_amount: Option<u64>,
},
}
/// An argument when calling [crate::sdk::LiquidSdk::prepare_receive_payment].
#[derive(Debug, Serialize)]
pub struct PrepareReceiveRequest {
pub payer_amount_sat: Option<u64>,
pub payment_method: PaymentMethod,
/// The amount to be paid in either Bitcoin or another asset
pub amount: Option<ReceiveAmount>,
}
/// Returned when calling [crate::sdk::LiquidSdk::prepare_receive_payment].
#[derive(Debug, Serialize)]
pub struct PrepareReceiveResponse {
pub payment_method: PaymentMethod,
pub payer_amount_sat: Option<u64>,
pub amount: Option<ReceiveAmount>,
/// Generally represents the total fees that would be paid to send or receive this payment.
///
@@ -469,8 +487,15 @@ pub struct SendPaymentResponse {
#[derive(Debug, Serialize, Clone)]
pub enum PayAmount {
/// The amount in satoshi that will be received
Receiver { amount_sat: u64 },
/// Indicates that all available funds should be sent
Bitcoin { receiver_amount_sat: u64 },
/// The amount of an asset that will be received
Asset {
asset_id: String,
receiver_amount: u64,
},
/// Indicates that all available Bitcoin funds should be sent
Drain,
}
@@ -534,6 +559,13 @@ pub struct RefundResponse {
pub refund_tx_id: String,
}
/// An asset balance to denote the balance for each asset.
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct AssetBalance {
pub asset_id: String,
pub balance: u64,
}
#[derive(Debug, Serialize, Deserialize, Default)]
pub struct BlockchainInfo {
pub liquid_tip: u32,
@@ -552,6 +584,39 @@ pub struct WalletInfo {
pub fingerprint: String,
/// The wallet's pubkey. Used to verify signed messages.
pub pubkey: String,
/// Asset balances of non Liquid Bitcoin assets
#[serde(default)]
pub asset_balances: Vec<AssetBalance>,
}
impl WalletInfo {
pub(crate) fn validate_sufficient_funds(
&self,
network: LiquidNetwork,
amount_sat: u64,
fees_sat: u64,
asset_id: &str,
) -> Result<(), PaymentError> {
if asset_id.eq(&utils::lbtc_asset_id(network).to_string()) {
ensure_sdk!(
amount_sat + fees_sat <= self.balance_sat,
PaymentError::InsufficientFunds
);
} else {
match self
.asset_balances
.iter()
.find(|ab| ab.asset_id.eq(asset_id))
{
Some(asset_balance) => ensure_sdk!(
amount_sat <= asset_balance.balance && fees_sat <= self.balance_sat,
PaymentError::InsufficientFunds
),
None => return Err(PaymentError::InsufficientFunds),
}
}
Ok(())
}
}
/// Returned when calling [crate::sdk::LiquidSdk::get_info].
@@ -629,11 +694,19 @@ pub struct ListPaymentsRequest {
/// An argument of [ListPaymentsRequest] when calling [crate::sdk::LiquidSdk::list_payments].
#[derive(Debug, Serialize)]
pub enum ListPaymentDetails {
/// The Liquid BIP21 URI or address of the payment
Liquid { destination: String },
/// A Liquid payment
Liquid {
/// Optional asset id
asset_id: Option<String>,
/// Optional BIP21 URI or address
destination: Option<String>,
},
/// The Bitcoin address of the payment
Bitcoin { address: String },
/// A Bitcoin payment
Bitcoin {
/// Optional address
address: Option<String>,
},
}
/// An argument when calling [crate::sdk::LiquidSdk::get_payment].
@@ -1307,10 +1380,13 @@ pub struct PaymentTxData {
/// The point in time when the underlying tx was included in a block.
pub timestamp: Option<u32>,
/// The asset id
pub asset_id: String,
/// The onchain tx amount.
///
/// In case of an outbound payment (Send), this is the payer amount. Otherwise it's the receiver amount.
pub amount_sat: u64,
pub amount: u64,
/// The onchain fees of this tx
pub fees_sat: u64,
@@ -1430,6 +1506,9 @@ pub enum PaymentDetails {
/// Represents the BIP21 `message` field
description: String,
/// The asset id
asset_id: String,
},
/// Swapping to or from the Bitcoin chain
Bitcoin {
@@ -1482,6 +1561,15 @@ impl PaymentDetails {
Self::Liquid { .. } => None,
}
}
pub(crate) fn is_lbtc_asset_id(&self, network: LiquidNetwork) -> bool {
match self {
Self::Liquid { asset_id, .. } => {
asset_id.eq(&utils::lbtc_asset_id(network).to_string())
}
_ => true,
}
}
}
/// Represents an SDK payment.
@@ -1608,13 +1696,13 @@ impl Payment {
.timestamp
.or(swap.as_ref().map(|s| s.created_at))
.unwrap_or(utils::now()),
amount_sat: tx.amount_sat,
amount_sat: tx.amount,
fees_sat: match swap.as_ref() {
Some(s) => match tx.payment_type {
// For receive swaps, to avoid some edge case issues related to potential past
// overpayments, we use the actual claim value as the final received amount
// for fee calculation.
PaymentType::Receive => s.payer_amount_sat.saturating_sub(tx.amount_sat),
PaymentType::Receive => s.payer_amount_sat.saturating_sub(tx.amount),
PaymentType::Send => s.payer_amount_sat.saturating_sub(s.receiver_amount_sat),
},
None => match tx.payment_type {

View File

@@ -1,4 +1,9 @@
pub(crate) fn current_migrations() -> Vec<&'static str> {
pub(crate) fn current_migrations(is_mainnet: bool) -> Vec<&'static str> {
let alter_payment_tx_data_add_asset_id = if is_mainnet {
"ALTER TABLE payment_tx_data ADD COLUMN asset_id TEXT NOT NULL DEFAULT '6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d';"
} else {
"ALTER TABLE payment_tx_data ADD COLUMN asset_id TEXT NOT NULL DEFAULT '144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a49';"
};
vec![
"CREATE TABLE IF NOT EXISTS receive_swaps (
id TEXT NOT NULL PRIMARY KEY,
@@ -249,5 +254,10 @@ pub(crate) fn current_migrations() -> Vec<&'static str> {
ALTER TABLE send_swaps ADD COLUMN destination_pubkey TEXT;
",
"ALTER TABLE chain_swaps ADD COLUMN auto_accepted_fees INTEGER NOT NULL DEFAULT 0;",
alter_payment_tx_data_add_asset_id,
"
ALTER TABLE payment_tx_data RENAME COLUMN amount_sat TO amount;
UPDATE payment_tx_data SET amount = amount - fees_sat WHERE payment_type = 1;
",
]
}

View File

@@ -83,7 +83,12 @@ impl Persister {
}
fn migrate_main_db(&self) -> Result<()> {
let migrations = Migrations::new(current_migrations().into_iter().map(M::up).collect());
let migrations = Migrations::new(
current_migrations(self.network.eq(&LiquidNetwork::Mainnet))
.into_iter()
.map(M::up)
.collect(),
);
let mut conn = self.get_connection()?;
migrations.to_latest(&mut conn)?;
Ok(())
@@ -105,20 +110,35 @@ impl Persister {
pub(crate) fn insert_or_update_payment_with_wallet_tx(&self, tx: &WalletTx) -> Result<()> {
let tx_id = tx.txid.to_string();
let is_tx_confirmed = tx.height.is_some();
let amount_sat = tx
.balance
.iter()
.filter_map(|(asset_id, balance)| {
if *asset_id == utils::lbtc_asset_id(self.network) {
return Some(balance);
}
None
})
.sum::<i64>();
if amount_sat == 0 {
log::warn!("Attempted to persist a payment with no output amount: tx_id {tx_id}");
return Ok(());
let mut tx_balances = tx.balance.clone();
// Remove the Liquid Bitcoin asset balance
let lbtc_asset_id = utils::lbtc_asset_id(self.network);
let mut balance = tx_balances
.remove(&lbtc_asset_id)
.map(|balance| (lbtc_asset_id.to_string(), balance));
// If the balances are still not empty pop the asset balance
if tx_balances.is_empty().not() {
balance = tx_balances
.pop_first()
.map(|(asset_id, balance)| (asset_id.to_hex(), balance));
}
let (asset_id, payment_type, amount) = match balance {
Some((asset_id, asset_amount)) => {
let payment_type = match asset_amount >= 0 {
true => PaymentType::Receive,
false => PaymentType::Send,
};
let mut amount = asset_amount.unsigned_abs();
if payment_type == PaymentType::Send && asset_id.eq(&lbtc_asset_id.to_string()) {
amount = amount.saturating_sub(tx.fee);
}
(asset_id, payment_type, amount)
}
None => {
log::warn!("Attempted to persist a payment with no balance: tx_id {tx_id}");
return Ok(());
}
};
let maybe_script_pubkey = tx
.outputs
.iter()
@@ -131,12 +151,10 @@ impl Persister {
PaymentTxData {
tx_id: tx_id.clone(),
timestamp: tx.timestamp,
amount_sat: amount_sat.unsigned_abs(),
asset_id,
amount,
fees_sat: tx.fee,
payment_type: match amount_sat >= 0 {
true => PaymentType::Receive,
false => PaymentType::Send,
},
payment_type,
is_confirmed: is_tx_confirmed,
unblinding_data: Some(unblinding_data),
},
@@ -154,7 +172,8 @@ impl Persister {
let mut stmt = con.prepare(
"SELECT tx_id,
timestamp,
amount_sat,
asset_id,
amount,
fees_sat,
payment_type,
is_confirmed,
@@ -167,11 +186,12 @@ impl Persister {
Ok(PaymentTxData {
tx_id: row.get(0)?,
timestamp: row.get(1)?,
amount_sat: row.get(2)?,
fees_sat: row.get(3)?,
payment_type: row.get(4)?,
is_confirmed: row.get(5)?,
unblinding_data: row.get(6)?,
asset_id: row.get(2)?,
amount: row.get(3)?,
fees_sat: row.get(4)?,
payment_type: row.get(5)?,
is_confirmed: row.get(6)?,
unblinding_data: row.get(7)?,
})
})?
.map(|i| i.unwrap())
@@ -191,16 +211,18 @@ impl Persister {
"INSERT INTO payment_tx_data (
tx_id,
timestamp,
amount_sat,
asset_id,
amount,
fees_sat,
payment_type,
is_confirmed,
unblinding_data
)
VALUES (?, ?, ?, ?, ?, ?, ?)
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT (tx_id)
DO UPDATE SET timestamp = CASE WHEN excluded.is_confirmed = 1 THEN excluded.timestamp ELSE timestamp END,
amount_sat = excluded.amount_sat,
asset_id = excluded.asset_id,
amount = excluded.amount,
fees_sat = excluded.fees_sat,
payment_type = excluded.payment_type,
is_confirmed = excluded.is_confirmed,
@@ -209,7 +231,8 @@ impl Persister {
(
&ptx.tx_id,
ptx.timestamp.or(Some(utils::now())),
ptx.amount_sat,
ptx.asset_id,
ptx.amount,
ptx.fees_sat,
ptx.payment_type,
ptx.is_confirmed,
@@ -362,7 +385,8 @@ impl Persister {
SELECT
ptx.tx_id,
ptx.timestamp,
ptx.amount_sat,
ptx.asset_id,
ptx.amount,
ptx.fees_sat,
ptx.payment_type,
ptx.is_confirmed,
@@ -408,7 +432,7 @@ impl Persister {
cs.actual_payer_amount_sat,
cs.accepted_receiver_amount_sat,
cs.auto_accepted_fees,
rtx.amount_sat,
rtx.amount,
pd.destination,
pd.description,
pd.lnurl_info_json
@@ -459,70 +483,71 @@ impl Persister {
Ok(ref tx_id) => Some(PaymentTxData {
tx_id: tx_id.to_string(),
timestamp: row.get(1)?,
amount_sat: row.get(2)?,
fees_sat: row.get(3)?,
payment_type: row.get(4)?,
is_confirmed: row.get(5)?,
unblinding_data: row.get(6)?,
asset_id: row.get(2)?,
amount: row.get(3)?,
fees_sat: row.get(4)?,
payment_type: row.get(5)?,
is_confirmed: row.get(6)?,
unblinding_data: row.get(7)?,
}),
_ => None,
};
let maybe_receive_swap_id: Option<String> = row.get(7)?;
let maybe_receive_swap_created_at: Option<u32> = row.get(8)?;
let maybe_receive_swap_timeout_block_height: Option<u32> = row.get(9)?;
let maybe_receive_swap_invoice: Option<String> = row.get(10)?;
let maybe_receive_swap_payment_hash: Option<String> = row.get(11)?;
let maybe_receive_swap_destination_pubkey: Option<String> = row.get(12)?;
let maybe_receive_swap_description: Option<String> = row.get(13)?;
let maybe_receive_swap_preimage: Option<String> = row.get(14)?;
let maybe_receive_swap_payer_amount_sat: Option<u64> = row.get(15)?;
let maybe_receive_swap_receiver_amount_sat: Option<u64> = row.get(16)?;
let maybe_receive_swap_receiver_state: Option<PaymentState> = row.get(17)?;
let maybe_receive_swap_pair_fees_json: Option<String> = row.get(18)?;
let maybe_receive_swap_id: Option<String> = row.get(8)?;
let maybe_receive_swap_created_at: Option<u32> = row.get(9)?;
let maybe_receive_swap_timeout_block_height: Option<u32> = row.get(10)?;
let maybe_receive_swap_invoice: Option<String> = row.get(11)?;
let maybe_receive_swap_payment_hash: Option<String> = row.get(12)?;
let maybe_receive_swap_destination_pubkey: Option<String> = row.get(13)?;
let maybe_receive_swap_description: Option<String> = row.get(14)?;
let maybe_receive_swap_preimage: Option<String> = row.get(15)?;
let maybe_receive_swap_payer_amount_sat: Option<u64> = row.get(16)?;
let maybe_receive_swap_receiver_amount_sat: Option<u64> = row.get(17)?;
let maybe_receive_swap_receiver_state: Option<PaymentState> = row.get(18)?;
let maybe_receive_swap_pair_fees_json: Option<String> = row.get(19)?;
let maybe_receive_swap_pair_fees: Option<ReversePair> =
maybe_receive_swap_pair_fees_json.and_then(|pair| serde_json::from_str(&pair).ok());
let maybe_send_swap_id: Option<String> = row.get(19)?;
let maybe_send_swap_created_at: Option<u32> = row.get(20)?;
let maybe_send_swap_timeout_block_height: Option<u32> = row.get(21)?;
let maybe_send_swap_invoice: Option<String> = row.get(22)?;
let maybe_send_swap_bolt12_offer: Option<String> = row.get(23)?;
let maybe_send_swap_payment_hash: Option<String> = row.get(24)?;
let maybe_send_swap_destination_pubkey: Option<String> = row.get(25)?;
let maybe_send_swap_description: Option<String> = row.get(26)?;
let maybe_send_swap_preimage: Option<String> = row.get(27)?;
let maybe_send_swap_refund_tx_id: Option<String> = row.get(28)?;
let maybe_send_swap_payer_amount_sat: Option<u64> = row.get(29)?;
let maybe_send_swap_receiver_amount_sat: Option<u64> = row.get(30)?;
let maybe_send_swap_state: Option<PaymentState> = row.get(31)?;
let maybe_send_swap_pair_fees_json: Option<String> = row.get(32)?;
let maybe_send_swap_id: Option<String> = row.get(20)?;
let maybe_send_swap_created_at: Option<u32> = row.get(21)?;
let maybe_send_swap_timeout_block_height: Option<u32> = row.get(22)?;
let maybe_send_swap_invoice: Option<String> = row.get(23)?;
let maybe_send_swap_bolt12_offer: Option<String> = row.get(24)?;
let maybe_send_swap_payment_hash: Option<String> = row.get(25)?;
let maybe_send_swap_destination_pubkey: Option<String> = row.get(26)?;
let maybe_send_swap_description: Option<String> = row.get(27)?;
let maybe_send_swap_preimage: Option<String> = row.get(28)?;
let maybe_send_swap_refund_tx_id: Option<String> = row.get(29)?;
let maybe_send_swap_payer_amount_sat: Option<u64> = row.get(30)?;
let maybe_send_swap_receiver_amount_sat: Option<u64> = row.get(31)?;
let maybe_send_swap_state: Option<PaymentState> = row.get(32)?;
let maybe_send_swap_pair_fees_json: Option<String> = row.get(33)?;
let maybe_send_swap_pair_fees: Option<SubmarinePair> =
maybe_send_swap_pair_fees_json.and_then(|pair| serde_json::from_str(&pair).ok());
let maybe_chain_swap_id: Option<String> = row.get(33)?;
let maybe_chain_swap_created_at: Option<u32> = row.get(34)?;
let maybe_chain_swap_timeout_block_height: Option<u32> = row.get(35)?;
let maybe_chain_swap_direction: Option<Direction> = row.get(36)?;
let maybe_chain_swap_preimage: Option<String> = row.get(37)?;
let maybe_chain_swap_description: Option<String> = row.get(38)?;
let maybe_chain_swap_refund_tx_id: Option<String> = row.get(39)?;
let maybe_chain_swap_payer_amount_sat: Option<u64> = row.get(40)?;
let maybe_chain_swap_receiver_amount_sat: Option<u64> = row.get(41)?;
let maybe_chain_swap_claim_address: Option<String> = row.get(42)?;
let maybe_chain_swap_state: Option<PaymentState> = row.get(43)?;
let maybe_chain_swap_pair_fees_json: Option<String> = row.get(44)?;
let maybe_chain_swap_id: Option<String> = row.get(34)?;
let maybe_chain_swap_created_at: Option<u32> = row.get(35)?;
let maybe_chain_swap_timeout_block_height: Option<u32> = row.get(36)?;
let maybe_chain_swap_direction: Option<Direction> = row.get(37)?;
let maybe_chain_swap_preimage: Option<String> = row.get(38)?;
let maybe_chain_swap_description: Option<String> = row.get(39)?;
let maybe_chain_swap_refund_tx_id: Option<String> = row.get(40)?;
let maybe_chain_swap_payer_amount_sat: Option<u64> = row.get(41)?;
let maybe_chain_swap_receiver_amount_sat: Option<u64> = row.get(42)?;
let maybe_chain_swap_claim_address: Option<String> = row.get(43)?;
let maybe_chain_swap_state: Option<PaymentState> = row.get(44)?;
let maybe_chain_swap_pair_fees_json: Option<String> = row.get(45)?;
let maybe_chain_swap_pair_fees: Option<ChainPair> =
maybe_chain_swap_pair_fees_json.and_then(|pair| serde_json::from_str(&pair).ok());
let maybe_chain_swap_actual_payer_amount_sat: Option<u64> = row.get(45)?;
let maybe_chain_swap_accepted_receiver_amount_sat: Option<u64> = row.get(46)?;
let maybe_chain_swap_auto_accepted_fees: Option<bool> = row.get(47)?;
let maybe_chain_swap_actual_payer_amount_sat: Option<u64> = row.get(46)?;
let maybe_chain_swap_accepted_receiver_amount_sat: Option<u64> = row.get(47)?;
let maybe_chain_swap_auto_accepted_fees: Option<bool> = row.get(48)?;
let maybe_swap_refund_tx_amount_sat: Option<u64> = row.get(48)?;
let maybe_swap_refund_tx_amount_sat: Option<u64> = row.get(49)?;
let maybe_payment_details_destination: Option<String> = row.get(49)?;
let maybe_payment_details_description: Option<String> = row.get(50)?;
let maybe_payment_details_lnurl_info_json: Option<String> = row.get(51)?;
let maybe_payment_details_destination: Option<String> = row.get(50)?;
let maybe_payment_details_description: Option<String> = row.get(51)?;
let maybe_payment_details_lnurl_info_json: Option<String> = row.get(52)?;
let maybe_payment_details_lnurl_info: Option<LnUrlInfo> =
maybe_payment_details_lnurl_info_json.and_then(|info| serde_json::from_str(&info).ok());
@@ -716,6 +741,11 @@ impl Persister {
}
}
_ => PaymentDetails::Liquid {
asset_id: tx
.clone()
.map_or(utils::lbtc_asset_id(self.network).to_string(), |ptd| {
ptd.asset_id
}),
destination: maybe_payment_details_destination
.unwrap_or("Destination unknown".to_string()),
description: maybe_payment_details_description
@@ -881,17 +911,30 @@ fn filter_to_where_clause(req: &ListPaymentsRequest) -> (String, Vec<Box<dyn ToS
if let Some(details) = &req.details {
match details {
ListPaymentDetails::Bitcoin { address } => {
// Use the lockup address if it's incoming, else use the claim address
where_clause.push(
"(cs.direction = 0 AND cs.lockup_address = ? OR cs.direction = 1 AND cs.claim_address = ?)"
.to_string(),
);
where_params.push(Box::new(address));
where_params.push(Box::new(address));
where_clause.push("cs.id IS NOT NULL".to_string());
if let Some(address) = address {
// Use the lockup address if it's incoming, else use the claim address
where_clause.push(
"(cs.direction = 0 AND cs.lockup_address = ? OR cs.direction = 1 AND cs.claim_address = ?)"
.to_string(),
);
where_params.push(Box::new(address));
where_params.push(Box::new(address));
}
}
ListPaymentDetails::Liquid { destination } => {
where_clause.push("pd.destination = ?".to_string());
where_params.push(Box::new(destination));
ListPaymentDetails::Liquid {
asset_id,
destination,
} => {
where_clause.push("COALESCE(rs.id, ss.id, cs.id) IS NULL".to_string());
if let Some(asset_id) = asset_id {
where_clause.push("ptx.asset_id = ?".to_string());
where_params.push(Box::new(asset_id));
}
if let Some(destination) = destination {
where_clause.push("pd.destination = ?".to_string());
where_params.push(Box::new(destination));
}
}
}
}
@@ -904,6 +947,7 @@ mod tests {
use anyhow::Result;
use crate::{
model::LiquidNetwork,
persist::PaymentTxDetails,
prelude::ListPaymentsRequest,
test_utils::persist::{
@@ -917,7 +961,7 @@ mod tests {
fn test_get_payments() -> Result<()> {
create_persister!(storage);
let payment_tx_data = new_payment_tx_data(PaymentType::Send);
let payment_tx_data = new_payment_tx_data(LiquidNetwork::Testnet, PaymentType::Send);
storage.insert_or_update_payment(
payment_tx_data.clone(),
Some(PaymentTxDetails {

View File

@@ -333,7 +333,8 @@ impl ReceiveSwapHandler {
PaymentTxData {
tx_id: claim_tx_id.clone(),
timestamp: Some(utils::now()),
amount_sat: swap.receiver_amount_sat,
asset_id: self.config.lbtc_asset_id(),
amount: swap.receiver_amount_sat,
fees_sat: 0,
payment_type: PaymentType::Receive,
is_confirmed: false,

View File

@@ -1,4 +1,4 @@
use std::collections::HashMap;
use std::collections::{BTreeMap, HashMap};
use std::ops::Not as _;
use std::time::Instant;
use std::{fs, path::PathBuf, str::FromStr, sync::Arc, time::Duration};
@@ -14,6 +14,7 @@ use futures_util::{StreamExt, TryFutureExt};
use lnurl::auth::SdkLnurlAuthSigner;
use log::{debug, error, info, warn};
use lwk_wollet::bitcoin::base64::Engine as _;
use lwk_wollet::elements::AssetId;
use lwk_wollet::elements_miniscript::elements::bitcoin::bip32::Xpub;
use lwk_wollet::hashes::{sha256, Hash};
use lwk_wollet::secp256k1::Message;
@@ -798,10 +799,16 @@ impl LiquidSdk {
&self,
amount_sat: u64,
address: &str,
asset_id: &str,
) -> Result<u64, PaymentError> {
let fee_sat = self
.onchain_wallet
.build_tx(Some(LIQUID_FEE_RATE_MSAT_PER_VBYTE), address, amount_sat)
.build_tx(
Some(LIQUID_FEE_RATE_MSAT_PER_VBYTE),
address,
asset_id,
amount_sat,
)
.await?
.all_fees()
.values()
@@ -825,8 +832,12 @@ impl LiquidSdk {
user_lockup_amount_sat: u64,
) -> Result<u64, PaymentError> {
let temp_p2tr_addr = self.get_temp_p2tr_addr();
self.estimate_onchain_tx_fee(user_lockup_amount_sat, temp_p2tr_addr)
.await
self.estimate_onchain_tx_fee(
user_lockup_amount_sat,
temp_p2tr_addr,
self.config.lbtc_asset_id().as_str(),
)
.await
}
async fn estimate_drain_tx_fee(
@@ -855,13 +866,18 @@ impl LiquidSdk {
&self,
amount_sat: u64,
address: &str,
asset_id: &str,
) -> Result<u64, PaymentError> {
match self.estimate_onchain_tx_fee(amount_sat, address).await {
match self
.estimate_onchain_tx_fee(amount_sat, address, asset_id)
.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(PaymentError::InsufficientFunds) if asset_id.eq(&self.config.lbtc_asset_id()) => {
self.estimate_drain_tx_fee(Some(amount_sat), Some(address))
.await
.map_err(|_| PaymentError::InsufficientFunds)
}
Err(e) => Err(e),
}
}
@@ -871,8 +887,12 @@ impl LiquidSdk {
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
self.estimate_onchain_tx_or_drain_tx_fee(
amount_sat,
temp_p2tr_addr,
&self.config.lbtc_asset_id(),
)
.await
}
/// Prepares to pay a Lightning invoice via a submarine swap.
@@ -883,8 +903,9 @@ impl LiquidSdk {
/// * `destination` - Either a Liquid BIP21 URI/address, a BOLT11 invoice or a BOLT12 offer
/// * `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
/// - [PayAmount::Drain] which uses all Bitcoin funds
/// - [PayAmount::Bitcoin] which sets the amount in satoshi that will be received
/// - [PayAmount::Asset] which sets the amount of an asset that will be received
///
/// # Returns
/// Returns a [PrepareSendResponse] containing:
@@ -899,22 +920,39 @@ impl LiquidSdk {
let get_info_res = self.get_info().await?;
let fees_sat;
let receiver_amount_sat;
let asset_id;
let payment_destination;
match self.parse(&req.destination).await {
Ok(InputType::LiquidAddress {
address: mut liquid_address_data,
}) => {
let amount = match (liquid_address_data.amount_sat, req.amount.clone()) {
(None, None) => {
let amount = match (
liquid_address_data.amount_sat,
liquid_address_data.asset_id,
req.amount.clone(),
) {
(None, _, None) => {
return Err(PaymentError::AmountMissing {
err: "Amount must be set when paying to a Liquid address".to_string(),
});
}
(Some(bip21_amount_sat), None) => PayAmount::Receiver {
amount_sat: bip21_amount_sat,
(Some(amount_sat), Some(asset_id), None) => {
if asset_id.eq(&self.config.lbtc_asset_id()) {
PayAmount::Bitcoin {
receiver_amount_sat: amount_sat,
}
} else {
PayAmount::Asset {
asset_id,
receiver_amount: amount_sat,
}
}
}
(Some(amount_sat), None, None) => PayAmount::Bitcoin {
receiver_amount_sat: amount_sat,
},
(_, Some(amount)) => amount,
(_, _, Some(amount)) => amount,
};
ensure_sdk!(
@@ -928,7 +966,7 @@ impl LiquidSdk {
}
);
(receiver_amount_sat, fees_sat) = match amount {
(asset_id, receiver_amount_sat, fees_sat) = match amount {
PayAmount::Drain => {
ensure_sdk!(
get_info_res.wallet_info.pending_receive_sat == 0
@@ -943,20 +981,42 @@ impl LiquidSdk {
let drain_amount_sat =
get_info_res.wallet_info.balance_sat - drain_fees_sat;
info!("Drain amount: {drain_amount_sat} sat");
(drain_amount_sat, drain_fees_sat)
(
self.config.lbtc_asset_id(),
drain_amount_sat,
drain_fees_sat,
)
}
PayAmount::Receiver { amount_sat } => {
PayAmount::Bitcoin {
receiver_amount_sat,
} => {
let asset_id = self.config.lbtc_asset_id();
let fees_sat = self
.estimate_onchain_tx_or_drain_tx_fee(
amount_sat,
receiver_amount_sat,
&liquid_address_data.address,
&asset_id,
)
.await?;
(amount_sat, fees_sat)
(asset_id, receiver_amount_sat, fees_sat)
}
PayAmount::Asset {
asset_id,
receiver_amount,
} => {
let fees_sat = self
.estimate_onchain_tx_or_drain_tx_fee(
receiver_amount,
&liquid_address_data.address,
&asset_id,
)
.await?;
(asset_id, receiver_amount, fees_sat)
}
};
liquid_address_data.amount_sat = Some(receiver_amount_sat);
liquid_address_data.asset_id = Some(asset_id.clone());
payment_destination = SendDestination::LiquidAddress {
address_data: liquid_address_data,
};
@@ -977,7 +1037,10 @@ impl LiquidSdk {
"Expected invoice with an amount",
))? / 1000;
if let Some(PayAmount::Receiver { amount_sat }) = req.amount {
if let Some(PayAmount::Bitcoin {
receiver_amount_sat: amount_sat,
}) = req.amount
{
ensure_sdk!(
receiver_amount_sat == amount_sat,
PaymentError::Generic {
@@ -988,10 +1051,15 @@ impl LiquidSdk {
let lbtc_pair = self.validate_submarine_pairs(receiver_amount_sat)?;
asset_id = self.config.lbtc_asset_id();
fees_sat = match self.swapper.check_for_mrh(&invoice.bolt11)? {
Some((lbtc_address, _)) => {
self.estimate_onchain_tx_or_drain_tx_fee(receiver_amount_sat, &lbtc_address)
.await?
self.estimate_onchain_tx_or_drain_tx_fee(
receiver_amount_sat,
&lbtc_address,
&asset_id,
)
.await?
}
None => {
let boltz_fees_total = lbtc_pair.fees.total(receiver_amount_sat);
@@ -1006,7 +1074,9 @@ impl LiquidSdk {
}
Ok(InputType::Bolt12Offer { offer }) => {
receiver_amount_sat = match req.amount {
Some(PayAmount::Receiver { amount_sat }) => Ok(amount_sat),
Some(PayAmount::Bitcoin {
receiver_amount_sat: amount_sat,
}) => Ok(amount_sat),
_ => Err(PaymentError::amount_missing(
"Expected PayAmount of type Receiver when processing a Bolt12 offer",
)),
@@ -1026,6 +1096,7 @@ impl LiquidSdk {
let lockup_fees_sat = self
.estimate_lockup_tx_or_drain_tx_fee(receiver_amount_sat + boltz_fees_total)
.await?;
asset_id = self.config.lbtc_asset_id();
fees_sat = boltz_fees_total + lockup_fees_sat;
payment_destination = SendDestination::Bolt12 {
@@ -1038,11 +1109,12 @@ impl LiquidSdk {
}
};
let payer_amount_sat = receiver_amount_sat + fees_sat;
ensure_sdk!(
payer_amount_sat <= get_info_res.wallet_info.balance_sat,
PaymentError::InsufficientFunds
);
get_info_res.wallet_info.validate_sufficient_funds(
self.config.network,
receiver_amount_sat,
fees_sat,
&asset_id,
)?;
Ok(PrepareSendResponse {
destination: payment_destination,
@@ -1090,6 +1162,9 @@ impl LiquidSdk {
let Some(amount_sat) = liquid_address_data.amount_sat else {
return Err(PaymentError::AmountMissing { err: "`amount_sat` must be present when paying to a `SendDestination::LiquidAddress`".to_string() });
};
let Some(ref asset_id) = liquid_address_data.asset_id else {
return Err(PaymentError::Generic { err: "`asset_id` must be present when paying to a `SendDestination::LiquidAddress`".to_string() });
};
ensure_sdk!(
liquid_address_data.network == self.config.network.into(),
@@ -1102,12 +1177,15 @@ impl LiquidSdk {
}
);
let payer_amount_sat = amount_sat + fees_sat;
ensure_sdk!(
payer_amount_sat <= self.get_info().await?.wallet_info.balance_sat,
PaymentError::InsufficientFunds
);
self.get_info()
.await?
.wallet_info
.validate_sufficient_funds(
self.config.network,
amount_sat,
*fees_sat,
asset_id,
)?;
self.pay_liquid(liquid_address_data.clone(), amount_sat, *fees_sat, true)
.await
}
@@ -1221,9 +1299,11 @@ impl LiquidSdk {
let destination = address_data
.to_uri()
.unwrap_or(address_data.address.clone());
let asset_id = address_data.asset_id.unwrap_or(self.config.lbtc_asset_id());
let payments = self.persister.get_payments(&ListPaymentsRequest {
details: Some(ListPaymentDetails::Liquid {
destination: destination.clone(),
asset_id: Some(asset_id.clone()),
destination: Some(destination.clone()),
}),
..Default::default()
})?;
@@ -1237,14 +1317,14 @@ impl LiquidSdk {
.build_tx_or_drain_tx(
Some(LIQUID_FEE_RATE_MSAT_PER_VBYTE),
&address_data.address,
&asset_id,
receiver_amount_sat,
)
.await?;
let tx_id = tx.txid().to_string();
let tx_fees_sat = tx.all_fees().values().sum::<u64>();
ensure_sdk!(tx_fees_sat <= fees_sat, PaymentError::InvalidOrExpiredFees);
let tx_id = tx.txid().to_string();
let payer_amount_sat = receiver_amount_sat + tx_fees_sat;
info!(
"Built onchain L-BTC tx with receiver_amount_sat = {receiver_amount_sat}, fees_sat = {fees_sat} and txid = {tx_id}"
);
@@ -1257,11 +1337,12 @@ impl LiquidSdk {
let tx_data = PaymentTxData {
tx_id: tx_id.clone(),
timestamp: Some(utils::now()),
amount_sat: payer_amount_sat,
amount: receiver_amount_sat,
fees_sat,
payment_type: PaymentType::Send,
is_confirmed: false,
unblinding_data: None,
asset_id: asset_id.clone(),
};
let description = address_data.message;
@@ -1279,6 +1360,7 @@ impl LiquidSdk {
self.emit_payment_updated(Some(tx_id)).await?; // Emit Pending event
let payment_details = PaymentDetails::Liquid {
asset_id,
destination,
description: description.unwrap_or("Liquid transfer".to_string()),
};
@@ -1473,7 +1555,7 @@ impl LiquidSdk {
///
/// * `req` - the [PreparePayOnchainRequest] containing:
/// * `amount` - which can be of two types: [PayAmount::Drain], which uses all funds,
/// and [PayAmount::Receiver], which sets the amount the receiver should receive
/// and [PayAmount::Bitcoin], 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
pub async fn prepare_pay_onchain(
&self,
@@ -1491,7 +1573,9 @@ impl LiquidSdk {
info!("Preparing for onchain payment of kind: {:?}", req.amount);
let (payer_amount_sat, receiver_amount_sat, total_fees_sat) = match req.amount {
PayAmount::Receiver { amount_sat } => {
PayAmount::Bitcoin {
receiver_amount_sat: amount_sat,
} => {
let receiver_amount_sat = amount_sat;
let user_lockup_amount_sat_without_service_fee =
@@ -1536,6 +1620,11 @@ impl LiquidSdk {
(payer_amount_sat, receiver_amount_sat, total_fees_sat)
}
PayAmount::Asset { .. } => {
return Err(PaymentError::generic(
"Cannot send an asset to a Bitcoin address",
))
}
};
let res = PreparePayOnchainResponse {
@@ -1757,8 +1846,10 @@ impl LiquidSdk {
/// # Arguments
///
/// * `req` - the [PrepareReceiveRequest] containing:
/// * `payer_amount_sat` - the amount in satoshis to be paid by the payer
/// * `payment_method` - the supported payment methods; either an invoice, a Liquid address or a Bitcoin address
/// * `amount` - The optional amount of type [ReceiveAmount] to be paid.
/// - [ReceiveAmount::Bitcoin] which sets the amount in satoshi that should be paid
/// - [ReceiveAmount::Asset] which sets the amount of an asset that should be paid
pub async fn prepare_receive_payment(
&self,
req: &PrepareReceiveRequest,
@@ -1771,8 +1862,18 @@ impl LiquidSdk {
let fees_sat;
match req.payment_method {
PaymentMethod::Lightning => {
let Some(payer_amount_sat) = req.payer_amount_sat else {
return Err(PaymentError::AmountMissing { err: "`payer_amount_sat` must be specified when `PaymentMethod::Lightning` is used.".to_string() });
let payer_amount_sat = match req.amount {
Some(ReceiveAmount::Asset { .. }) => {
return Err(PaymentError::generic(
"Cannot receive an asset when the payment method is Lightning",
));
}
Some(ReceiveAmount::Bitcoin { payer_amount_sat }) => payer_amount_sat,
None => {
return Err(PaymentError::generic(
"Bitcoin payer amount must be set when the payment method is Lightning",
));
}
};
let reverse_pair = self
.swapper
@@ -1797,7 +1898,15 @@ impl LiquidSdk {
);
}
PaymentMethod::BitcoinAddress => {
let payer_amount_sat = req.payer_amount_sat;
let payer_amount_sat = match req.amount {
Some(ReceiveAmount::Asset { .. }) => {
return Err(PaymentError::generic(
"Cannot receive an asset when the payment method is Bitcoin",
));
}
Some(ReceiveAmount::Bitcoin { payer_amount_sat }) => Some(payer_amount_sat),
None => None,
};
let pair =
self.get_and_validate_chain_pair(Direction::Incoming, payer_amount_sat)?;
let claim_fees_sat = pair.fees.claim_estimate();
@@ -1814,14 +1923,23 @@ impl LiquidSdk {
debug!("Preparing Chain Receive Swap with: payer_amount_sat {payer_amount_sat:?}, fees_sat {fees_sat}");
}
PaymentMethod::LiquidAddress => {
let (asset_id, amount_sat) = match req.amount.clone() {
Some(ReceiveAmount::Asset {
payer_amount,
asset_id,
}) => (asset_id, payer_amount),
Some(ReceiveAmount::Bitcoin { payer_amount_sat }) => {
(self.config.lbtc_asset_id(), Some(payer_amount_sat))
}
None => (self.config.lbtc_asset_id(), None),
};
fees_sat = 0;
let payer_amount_sat = req.payer_amount_sat;
debug!("Preparing Liquid Receive Swap with: amount_sat {payer_amount_sat:?}, fees_sat {fees_sat}");
debug!("Preparing Liquid Receive with: asset_id {asset_id}, amount_sat {amount_sat:?}, fees_sat {fees_sat}");
}
};
Ok(PrepareReceiveResponse {
payer_amount_sat: req.payer_amount_sat,
amount: req.amount.clone(),
fees_sat,
payment_method: req.payment_method.clone(),
min_payer_amount_sat,
@@ -1852,15 +1970,25 @@ impl LiquidSdk {
let PrepareReceiveResponse {
payment_method,
payer_amount_sat: amount_sat,
amount,
fees_sat,
..
} = &req.prepare_response;
match payment_method {
PaymentMethod::Lightning => {
let Some(amount_sat) = amount_sat else {
return Err(PaymentError::AmountMissing { err: "`amount_sat` must be specified when `PaymentMethod::Lightning` is used.".to_string() });
let amount_sat = match amount.clone() {
Some(ReceiveAmount::Asset { .. }) => {
return Err(PaymentError::generic(
"Cannot receive an asset when the payment method is Lightning",
));
}
Some(ReceiveAmount::Bitcoin { payer_amount_sat }) => payer_amount_sat,
None => {
return Err(PaymentError::generic(
"Bitcoin payer amount must be set when the payment method is Lightning",
));
}
};
let (description, description_hash) = match (
req.description.clone(),
@@ -1877,19 +2005,40 @@ impl LiquidSdk {
})
}
};
self.create_receive_swap(*amount_sat, *fees_sat, description, description_hash)
self.create_receive_swap(amount_sat, *fees_sat, description, description_hash)
.await
}
PaymentMethod::BitcoinAddress => self.receive_onchain(*amount_sat, *fees_sat).await,
PaymentMethod::BitcoinAddress => {
let amount_sat = match amount.clone() {
Some(ReceiveAmount::Asset { .. }) => {
return Err(PaymentError::generic(
"Cannot receive an asset when the payment method is Bitcoin",
));
}
Some(ReceiveAmount::Bitcoin { payer_amount_sat }) => Some(payer_amount_sat),
None => None,
};
self.receive_onchain(amount_sat, *fees_sat).await
}
PaymentMethod::LiquidAddress => {
let address = self.onchain_wallet.next_unused_address().await?.to_string();
let (asset_id, amount_sat) = match amount.clone() {
Some(ReceiveAmount::Asset {
asset_id,
payer_amount,
}) => (asset_id, payer_amount),
Some(ReceiveAmount::Bitcoin { payer_amount_sat }) => {
(self.config.lbtc_asset_id(), Some(payer_amount_sat))
}
None => (self.config.lbtc_asset_id(), None),
};
let address = self.onchain_wallet.next_unused_address().await?.to_string();
let receive_destination = match amount_sat {
Some(amount_sat) => LiquidAddressData {
address: address.to_string(),
network: self.config.network.into(),
amount_sat: Some(*amount_sat),
asset_id: Some(utils::lbtc_asset_id(self.config.network).to_string()),
amount_sat: Some(amount_sat),
asset_id: Some(asset_id.clone()),
label: None,
message: req.description.clone(),
}
@@ -2328,15 +2477,20 @@ impl LiquidSdk {
let res = self
.prepare_receive_payment(&PrepareReceiveRequest {
payment_method: PaymentMethod::BitcoinAddress,
payer_amount_sat: Some(req.amount_sat),
amount: Some(ReceiveAmount::Bitcoin {
payer_amount_sat: req.amount_sat,
}),
})
.await?;
let Some(amount_sat) = res.payer_amount_sat else {
let Some(ReceiveAmount::Bitcoin {
payer_amount_sat: amount_sat,
}) = res.amount
else {
return Err(PaymentError::Generic {
err: format!(
"Expected field `amount_sat` from response, got {:?}",
res.payer_amount_sat
"Error preparing receive payment, got amount: {:?}",
res.amount
),
});
};
@@ -2541,18 +2695,29 @@ impl LiquidSdk {
async fn update_wallet_info(&self) -> Result<()> {
let transactions = self.onchain_wallet.transactions().await?;
let mut wallet_amount_sat: i64 = 0;
transactions.into_iter().for_each(|tx| {
tx.balance.into_iter().for_each(|(asset_id, balance)| {
if asset_id == utils::lbtc_asset_id(self.config.network) {
//consider only confirmed unspent outputs (confirmed transactions output reduced by unconfirmed spent outputs)
let asset_balances = transactions
.into_iter()
.fold(BTreeMap::<AssetId, i64>::new(), |mut acc, tx| {
tx.balance.into_iter().for_each(|(asset_id, balance)| {
// Consider only confirmed unspent outputs (confirmed transactions output reduced by unconfirmed spent outputs)
if tx.height.is_some() || balance < 0 {
wallet_amount_sat += balance;
*acc.entry(asset_id).or_default() += balance;
}
}
});
acc
})
});
debug!("Onchain wallet balance: {wallet_amount_sat} sats");
.into_iter()
.map(|(asset_id, balance)| AssetBalance {
asset_id: asset_id.to_hex(),
balance: balance.unsigned_abs(),
})
.collect::<Vec<AssetBalance>>();
let balance_sat = asset_balances
.clone()
.into_iter()
.find(|ab| ab.asset_id.eq(&self.config.lbtc_asset_id()))
.map_or(0, |ab| ab.balance);
debug!("Onchain wallet balance: {balance_sat} sats");
let mut pending_send_sat = 0;
let mut pending_receive_sat = 0;
@@ -2566,21 +2731,27 @@ impl LiquidSdk {
})?;
for payment in payments {
let total_sat = if payment.details.is_lbtc_asset_id(self.config.network) {
payment.amount_sat + payment.fees_sat
} else {
payment.fees_sat
};
match payment.payment_type {
PaymentType::Send => match payment.details.get_refund_tx_amount_sat() {
Some(refund_tx_amount_sat) => pending_receive_sat += refund_tx_amount_sat,
None => pending_send_sat += payment.amount_sat,
None => pending_send_sat += total_sat,
},
PaymentType::Receive => pending_receive_sat += payment.amount_sat,
PaymentType::Receive => pending_receive_sat += total_sat,
}
}
let info_response = WalletInfo {
balance_sat: wallet_amount_sat as u64,
balance_sat,
pending_send_sat,
pending_receive_sat,
fingerprint: self.onchain_wallet.fingerprint()?,
pubkey: self.onchain_wallet.pubkey()?,
asset_balances,
};
self.persister.set_wallet_info(&info_response)
}
@@ -2968,7 +3139,9 @@ impl LiquidSdk {
.prepare_receive_payment(&{
PrepareReceiveRequest {
payment_method: PaymentMethod::Lightning,
payer_amount_sat: Some(req.amount_msat / 1_000),
amount: Some(ReceiveAmount::Bitcoin {
payer_amount_sat: req.amount_msat / 1_000,
}),
}
})
.await?;

View File

@@ -197,6 +197,7 @@ impl SendSwapHandler {
.build_tx_or_drain_tx(
Some(LIQUID_FEE_RATE_MSAT_PER_VBYTE),
&create_response.address,
&self.config.lbtc_asset_id(),
create_response.expected_amount,
)
.await?;
@@ -225,7 +226,8 @@ impl SendSwapHandler {
PaymentTxData {
tx_id: lockup_tx_id.clone(),
timestamp: Some(utils::now()),
amount_sat: swap.payer_amount_sat,
asset_id: self.config.lbtc_asset_id(),
amount: create_response.expected_amount,
fees_sat: lockup_tx_fees_sat,
payment_type: PaymentType::Send,
is_confirmed: false,

View File

@@ -12,7 +12,7 @@ use sdk_common::{
};
use crate::{
model::{PaymentState, PaymentTxData, PaymentType, ReceiveSwap, SendSwap},
model::{LiquidNetwork, PaymentState, PaymentTxData, PaymentType, ReceiveSwap, SendSwap},
test_utils::generate_random_string,
utils,
};
@@ -161,11 +161,15 @@ macro_rules! create_persister {
}
pub(crate) use create_persister;
pub(crate) fn new_payment_tx_data(payment_type: PaymentType) -> PaymentTxData {
pub(crate) fn new_payment_tx_data(
network: LiquidNetwork,
payment_type: PaymentType,
) -> PaymentTxData {
PaymentTxData {
tx_id: generate_random_string(4),
timestamp: None,
amount_sat: 0,
asset_id: utils::lbtc_asset_id(network).to_string(),
amount: 0,
fees_sat: 0,
payment_type,
is_confirmed: false,

View File

@@ -55,6 +55,7 @@ impl OnchainWallet for MockWallet {
&self,
_fee_rate: Option<f32>,
_recipient_address: &str,
_asset_id: &str,
_amount_sat: u64,
) -> Result<Transaction, PaymentError> {
Ok(TEST_LIQUID_TX.clone())
@@ -73,6 +74,7 @@ impl OnchainWallet for MockWallet {
&self,
_fee_rate_sats_per_kvb: Option<f32>,
_recipient_address: &str,
_asset_id: &str,
_amount_sat: u64,
) -> Result<Transaction, PaymentError> {
Ok(TEST_LIQUID_TX.clone())

View File

@@ -10,7 +10,7 @@ use boltz_client::ElementsAddress;
use log::{debug, warn};
use lwk_common::Signer as LwkSigner;
use lwk_common::{singlesig_desc, Singlesig};
use lwk_wollet::elements::Txid;
use lwk_wollet::elements::{AssetId, Txid};
use lwk_wollet::{
elements::{hex::ToHex, Address, Transaction},
ElectrumClient, ElectrumUrl, ElementsNetwork, FsPersister, Tip, WalletTx, Wollet,
@@ -46,6 +46,7 @@ pub trait OnchainWallet: Send + Sync {
&self,
fee_rate_sats_per_kvb: Option<f32>,
recipient_address: &str,
asset_id: &str,
amount_sat: u64,
) -> Result<Transaction, PaymentError>;
@@ -70,6 +71,7 @@ pub trait OnchainWallet: Send + Sync {
&self,
fee_rate_sats_per_kvb: Option<f32>,
recipient_address: &str,
asset_id: &str,
amount_sat: u64,
) -> Result<Transaction, PaymentError>;
@@ -203,23 +205,26 @@ impl OnchainWallet for LiquidOnchainWallet {
&self,
fee_rate_sats_per_kvb: Option<f32>,
recipient_address: &str,
asset_id: &str,
amount_sat: u64,
) -> Result<Transaction, PaymentError> {
let lwk_wollet = self.wallet.lock().await;
let mut pset = lwk_wollet::TxBuilder::new(self.config.network.into())
.add_lbtc_recipient(
&ElementsAddress::from_str(recipient_address).map_err(|e| {
PaymentError::Generic {
err: format!(
"Recipient address {recipient_address} is not a valid ElementsAddress: {e:?}"
),
}
})?,
amount_sat,
)?
let address =
ElementsAddress::from_str(recipient_address).map_err(|e| PaymentError::Generic {
err: format!(
"Recipient address {recipient_address} is not a valid ElementsAddress: {e:?}"
),
})?;
let mut tx_builder = lwk_wollet::TxBuilder::new(self.config.network.into())
.fee_rate(fee_rate_sats_per_kvb)
.enable_ct_discount()
.finish(&lwk_wollet)?;
.enable_ct_discount();
if asset_id.eq(&self.config.lbtc_asset_id()) {
tx_builder = tx_builder.add_lbtc_recipient(&address, amount_sat)?;
} else {
let asset = AssetId::from_str(asset_id)?;
tx_builder = tx_builder.add_recipient(&address, amount_sat, asset)?;
}
let mut pset = tx_builder.finish(&lwk_wollet)?;
self.signer
.sign(&mut pset)
.map_err(|e| PaymentError::Generic {
@@ -279,14 +284,20 @@ impl OnchainWallet for LiquidOnchainWallet {
&self,
fee_rate_sats_per_kvb: Option<f32>,
recipient_address: &str,
asset_id: &str,
amount_sat: u64,
) -> Result<Transaction, PaymentError> {
match self
.build_tx(fee_rate_sats_per_kvb, recipient_address, amount_sat)
.build_tx(
fee_rate_sats_per_kvb,
recipient_address,
asset_id,
amount_sat,
)
.await
{
Ok(tx) => Ok(tx),
Err(PaymentError::InsufficientFunds) => {
Err(PaymentError::InsufficientFunds) if asset_id.eq(&self.config.lbtc_asset_id()) => {
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

View File

@@ -1378,6 +1378,17 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
AssetBalance dco_decode_asset_balance(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}');
return AssetBalance(
assetId: dco_decode_String(arr[0]),
balance: dco_decode_u_64(arr[1]),
);
}
@protected
BackupRequest dco_decode_backup_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -1675,6 +1686,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return dco_decode_prepare_send_request(raw);
}
@protected
ReceiveAmount dco_decode_box_autoadd_receive_amount(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return dco_decode_receive_amount(raw);
}
@protected
ReceivePaymentRequest dco_decode_box_autoadd_receive_payment_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -2023,6 +2040,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return (raw as List<dynamic>).map(dco_decode_String).toList();
}
@protected
List<AssetBalance> dco_decode_list_asset_balance(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return (raw as List<dynamic>).map(dco_decode_asset_balance).toList();
}
@protected
List<ExternalInputParser> dco_decode_list_external_input_parser(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -2065,11 +2088,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
switch (raw[0]) {
case 0:
return ListPaymentDetails_Liquid(
destination: dco_decode_String(raw[1]),
assetId: dco_decode_opt_String(raw[1]),
destination: dco_decode_opt_String(raw[2]),
);
case 1:
return ListPaymentDetails_Bitcoin(
address: dco_decode_String(raw[1]),
address: dco_decode_opt_String(raw[1]),
);
default:
throw Exception("unreachable");
@@ -2589,6 +2613,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return raw == null ? null : dco_decode_box_autoadd_payment(raw);
}
@protected
ReceiveAmount? dco_decode_opt_box_autoadd_receive_amount(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
return raw == null ? null : dco_decode_box_autoadd_receive_amount(raw);
}
@protected
SuccessAction? dco_decode_opt_box_autoadd_success_action(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -2642,10 +2672,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
// Codec=Dco (DartCObject based), see doc to use other codecs
switch (raw[0]) {
case 0:
return PayAmount_Receiver(
amountSat: dco_decode_u_64(raw[1]),
return PayAmount_Bitcoin(
receiverAmountSat: dco_decode_u_64(raw[1]),
);
case 1:
return PayAmount_Asset(
assetId: dco_decode_String(raw[1]),
receiverAmount: dco_decode_u_64(raw[2]),
);
case 2:
return PayAmount_Drain();
default:
throw Exception("unreachable");
@@ -2704,6 +2739,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return PaymentDetails_Liquid(
destination: dco_decode_String(raw[1]),
description: dco_decode_String(raw[2]),
assetId: dco_decode_String(raw[3]),
);
case 2:
return PaymentDetails_Bitcoin(
@@ -2889,8 +2925,8 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
final arr = raw as List<dynamic>;
if (arr.length != 2) throw Exception('unexpected arr length: expect 2 but see ${arr.length}');
return PrepareReceiveRequest(
payerAmountSat: dco_decode_opt_box_autoadd_u_64(arr[0]),
paymentMethod: dco_decode_payment_method(arr[1]),
paymentMethod: dco_decode_payment_method(arr[0]),
amount: dco_decode_opt_box_autoadd_receive_amount(arr[1]),
);
}
@@ -2901,7 +2937,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
if (arr.length != 6) throw Exception('unexpected arr length: expect 6 but see ${arr.length}');
return PrepareReceiveResponse(
paymentMethod: dco_decode_payment_method(arr[0]),
payerAmountSat: dco_decode_opt_box_autoadd_u_64(arr[1]),
amount: dco_decode_opt_box_autoadd_receive_amount(arr[1]),
feesSat: dco_decode_u_64(arr[2]),
minPayerAmountSat: dco_decode_opt_box_autoadd_u_64(arr[3]),
maxPayerAmountSat: dco_decode_opt_box_autoadd_u_64(arr[4]),
@@ -2966,6 +3002,24 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
);
}
@protected
ReceiveAmount dco_decode_receive_amount(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
switch (raw[0]) {
case 0:
return ReceiveAmount_Bitcoin(
payerAmountSat: dco_decode_u_64(raw[1]),
);
case 1:
return ReceiveAmount_Asset(
assetId: dco_decode_String(raw[1]),
payerAmount: dco_decode_opt_box_autoadd_u_64(raw[2]),
);
default:
throw Exception("unreachable");
}
}
@protected
ReceivePaymentRequest dco_decode_receive_payment_request(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
@@ -3306,13 +3360,14 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
WalletInfo dco_decode_wallet_info(dynamic raw) {
// Codec=Dco (DartCObject based), see doc to use other codecs
final arr = raw as List<dynamic>;
if (arr.length != 5) throw Exception('unexpected arr length: expect 5 but see ${arr.length}');
if (arr.length != 6) throw Exception('unexpected arr length: expect 6 but see ${arr.length}');
return WalletInfo(
balanceSat: dco_decode_u_64(arr[0]),
pendingSendSat: dco_decode_u_64(arr[1]),
pendingReceiveSat: dco_decode_u_64(arr[2]),
fingerprint: dco_decode_String(arr[3]),
pubkey: dco_decode_String(arr[4]),
assetBalances: dco_decode_list_asset_balance(arr[5]),
);
}
@@ -3428,6 +3483,14 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
AssetBalance sse_decode_asset_balance(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_assetId = sse_decode_String(deserializer);
var var_balance = sse_decode_u_64(deserializer);
return AssetBalance(assetId: var_assetId, balance: var_balance);
}
@protected
BackupRequest sse_decode_backup_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -3722,6 +3785,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return (sse_decode_prepare_send_request(deserializer));
}
@protected
ReceiveAmount sse_decode_box_autoadd_receive_amount(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
return (sse_decode_receive_amount(deserializer));
}
@protected
ReceivePaymentRequest sse_decode_box_autoadd_receive_payment_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -4063,6 +4132,18 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return ans_;
}
@protected
List<AssetBalance> sse_decode_list_asset_balance(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var len_ = sse_decode_i_32(deserializer);
var ans_ = <AssetBalance>[];
for (var idx_ = 0; idx_ < len_; ++idx_) {
ans_.add(sse_decode_asset_balance(deserializer));
}
return ans_;
}
@protected
List<ExternalInputParser> sse_decode_list_external_input_parser(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -4142,10 +4223,11 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
var tag_ = sse_decode_i_32(deserializer);
switch (tag_) {
case 0:
var var_destination = sse_decode_String(deserializer);
return ListPaymentDetails_Liquid(destination: var_destination);
var var_assetId = sse_decode_opt_String(deserializer);
var var_destination = sse_decode_opt_String(deserializer);
return ListPaymentDetails_Liquid(assetId: var_assetId, destination: var_destination);
case 1:
var var_address = sse_decode_String(deserializer);
var var_address = sse_decode_opt_String(deserializer);
return ListPaymentDetails_Bitcoin(address: var_address);
default:
throw UnimplementedError('');
@@ -4725,6 +4807,17 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
ReceiveAmount? sse_decode_opt_box_autoadd_receive_amount(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
if (sse_decode_bool(deserializer)) {
return (sse_decode_box_autoadd_receive_amount(deserializer));
} else {
return null;
}
}
@protected
SuccessAction? sse_decode_opt_box_autoadd_success_action(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -4820,9 +4913,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
var tag_ = sse_decode_i_32(deserializer);
switch (tag_) {
case 0:
var var_amountSat = sse_decode_u_64(deserializer);
return PayAmount_Receiver(amountSat: var_amountSat);
var var_receiverAmountSat = sse_decode_u_64(deserializer);
return PayAmount_Bitcoin(receiverAmountSat: var_receiverAmountSat);
case 1:
var var_assetId = sse_decode_String(deserializer);
var var_receiverAmount = sse_decode_u_64(deserializer);
return PayAmount_Asset(assetId: var_assetId, receiverAmount: var_receiverAmount);
case 2:
return PayAmount_Drain();
default:
throw UnimplementedError('');
@@ -4896,7 +4993,9 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
case 1:
var var_destination = sse_decode_String(deserializer);
var var_description = sse_decode_String(deserializer);
return PaymentDetails_Liquid(destination: var_destination, description: var_description);
var var_assetId = sse_decode_String(deserializer);
return PaymentDetails_Liquid(
destination: var_destination, description: var_description, assetId: var_assetId);
case 2:
var var_swapId = sse_decode_String(deserializer);
var var_description = sse_decode_String(deserializer);
@@ -5073,23 +5172,23 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
@protected
PrepareReceiveRequest sse_decode_prepare_receive_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_payerAmountSat = sse_decode_opt_box_autoadd_u_64(deserializer);
var var_paymentMethod = sse_decode_payment_method(deserializer);
return PrepareReceiveRequest(payerAmountSat: var_payerAmountSat, paymentMethod: var_paymentMethod);
var var_amount = sse_decode_opt_box_autoadd_receive_amount(deserializer);
return PrepareReceiveRequest(paymentMethod: var_paymentMethod, amount: var_amount);
}
@protected
PrepareReceiveResponse sse_decode_prepare_receive_response(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var var_paymentMethod = sse_decode_payment_method(deserializer);
var var_payerAmountSat = sse_decode_opt_box_autoadd_u_64(deserializer);
var var_amount = sse_decode_opt_box_autoadd_receive_amount(deserializer);
var var_feesSat = sse_decode_u_64(deserializer);
var var_minPayerAmountSat = sse_decode_opt_box_autoadd_u_64(deserializer);
var var_maxPayerAmountSat = sse_decode_opt_box_autoadd_u_64(deserializer);
var var_swapperFeerate = sse_decode_opt_box_autoadd_f_64(deserializer);
return PrepareReceiveResponse(
paymentMethod: var_paymentMethod,
payerAmountSat: var_payerAmountSat,
amount: var_amount,
feesSat: var_feesSat,
minPayerAmountSat: var_minPayerAmountSat,
maxPayerAmountSat: var_maxPayerAmountSat,
@@ -5142,6 +5241,24 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
return Rate(coin: var_coin, value: var_value);
}
@protected
ReceiveAmount sse_decode_receive_amount(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
var tag_ = sse_decode_i_32(deserializer);
switch (tag_) {
case 0:
var var_payerAmountSat = sse_decode_u_64(deserializer);
return ReceiveAmount_Bitcoin(payerAmountSat: var_payerAmountSat);
case 1:
var var_assetId = sse_decode_String(deserializer);
var var_payerAmount = sse_decode_opt_box_autoadd_u_64(deserializer);
return ReceiveAmount_Asset(assetId: var_assetId, payerAmount: var_payerAmount);
default:
throw UnimplementedError('');
}
}
@protected
ReceivePaymentRequest sse_decode_receive_payment_request(SseDeserializer deserializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -5454,12 +5571,14 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
var var_pendingReceiveSat = sse_decode_u_64(deserializer);
var var_fingerprint = sse_decode_String(deserializer);
var var_pubkey = sse_decode_String(deserializer);
var var_assetBalances = sse_decode_list_asset_balance(deserializer);
return WalletInfo(
balanceSat: var_balanceSat,
pendingSendSat: var_pendingSendSat,
pendingReceiveSat: var_pendingReceiveSat,
fingerprint: var_fingerprint,
pubkey: var_pubkey);
pubkey: var_pubkey,
assetBalances: var_assetBalances);
}
@protected
@@ -5671,6 +5790,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
void sse_encode_asset_balance(AssetBalance self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_String(self.assetId, serializer);
sse_encode_u_64(self.balance, serializer);
}
@protected
void sse_encode_backup_request(BackupRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -5962,6 +6088,12 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_prepare_send_request(self, serializer);
}
@protected
void sse_encode_box_autoadd_receive_amount(ReceiveAmount self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_receive_amount(self, serializer);
}
@protected
void sse_encode_box_autoadd_receive_payment_request(ReceivePaymentRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -6246,6 +6378,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
void sse_encode_list_asset_balance(List<AssetBalance> self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_i_32(self.length, serializer);
for (final item in self) {
sse_encode_asset_balance(item, serializer);
}
}
@protected
void sse_encode_list_external_input_parser(List<ExternalInputParser> self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -6304,12 +6445,13 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
void sse_encode_list_payment_details(ListPaymentDetails self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
switch (self) {
case ListPaymentDetails_Liquid(destination: final destination):
case ListPaymentDetails_Liquid(assetId: final assetId, destination: final destination):
sse_encode_i_32(0, serializer);
sse_encode_String(destination, serializer);
sse_encode_opt_String(assetId, serializer);
sse_encode_opt_String(destination, serializer);
case ListPaymentDetails_Bitcoin(address: final address):
sse_encode_i_32(1, serializer);
sse_encode_String(address, serializer);
sse_encode_opt_String(address, serializer);
}
}
@@ -6767,6 +6909,16 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
}
}
@protected
void sse_encode_opt_box_autoadd_receive_amount(ReceiveAmount? 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_receive_amount(self, serializer);
}
}
@protected
void sse_encode_opt_box_autoadd_success_action(SuccessAction? self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -6852,11 +7004,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
void sse_encode_pay_amount(PayAmount self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
switch (self) {
case PayAmount_Receiver(amountSat: final amountSat):
case PayAmount_Bitcoin(receiverAmountSat: final receiverAmountSat):
sse_encode_i_32(0, serializer);
sse_encode_u_64(amountSat, serializer);
case PayAmount_Drain():
sse_encode_u_64(receiverAmountSat, serializer);
case PayAmount_Asset(assetId: final assetId, receiverAmount: final receiverAmount):
sse_encode_i_32(1, serializer);
sse_encode_String(assetId, serializer);
sse_encode_u_64(receiverAmount, serializer);
case PayAmount_Drain():
sse_encode_i_32(2, serializer);
}
}
@@ -6911,10 +7067,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_opt_box_autoadd_ln_url_info(lnurlInfo, serializer);
sse_encode_opt_String(refundTxId, serializer);
sse_encode_opt_box_autoadd_u_64(refundTxAmountSat, serializer);
case PaymentDetails_Liquid(destination: final destination, description: final description):
case PaymentDetails_Liquid(
destination: final destination,
description: final description,
assetId: final assetId
):
sse_encode_i_32(1, serializer);
sse_encode_String(destination, serializer);
sse_encode_String(description, serializer);
sse_encode_String(assetId, serializer);
case PaymentDetails_Bitcoin(
swapId: final swapId,
description: final description,
@@ -7065,15 +7226,15 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
@protected
void sse_encode_prepare_receive_request(PrepareReceiveRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_opt_box_autoadd_u_64(self.payerAmountSat, serializer);
sse_encode_payment_method(self.paymentMethod, serializer);
sse_encode_opt_box_autoadd_receive_amount(self.amount, serializer);
}
@protected
void sse_encode_prepare_receive_response(PrepareReceiveResponse self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
sse_encode_payment_method(self.paymentMethod, serializer);
sse_encode_opt_box_autoadd_u_64(self.payerAmountSat, serializer);
sse_encode_opt_box_autoadd_receive_amount(self.amount, serializer);
sse_encode_u_64(self.feesSat, serializer);
sse_encode_opt_box_autoadd_u_64(self.minPayerAmountSat, serializer);
sse_encode_opt_box_autoadd_u_64(self.maxPayerAmountSat, serializer);
@@ -7117,6 +7278,20 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_f_64(self.value, serializer);
}
@protected
void sse_encode_receive_amount(ReceiveAmount self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
switch (self) {
case ReceiveAmount_Bitcoin(payerAmountSat: final payerAmountSat):
sse_encode_i_32(0, serializer);
sse_encode_u_64(payerAmountSat, serializer);
case ReceiveAmount_Asset(assetId: final assetId, payerAmount: final payerAmount):
sse_encode_i_32(1, serializer);
sse_encode_String(assetId, serializer);
sse_encode_opt_box_autoadd_u_64(payerAmount, serializer);
}
}
@protected
void sse_encode_receive_payment_request(ReceivePaymentRequest self, SseSerializer serializer) {
// Codec=Sse (Serialization based), see doc to use other codecs
@@ -7371,6 +7546,7 @@ class RustLibApiImpl extends RustLibApiImplPlatform implements RustLibApi {
sse_encode_u_64(self.pendingReceiveSat, serializer);
sse_encode_String(self.fingerprint, serializer);
sse_encode_String(self.pubkey, serializer);
sse_encode_list_asset_balance(self.assetBalances, serializer);
}
}

View File

@@ -65,6 +65,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
Amount dco_decode_amount(dynamic raw);
@protected
AssetBalance dco_decode_asset_balance(dynamic raw);
@protected
BackupRequest dco_decode_backup_request(dynamic raw);
@@ -203,6 +206,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
PrepareSendRequest dco_decode_box_autoadd_prepare_send_request(dynamic raw);
@protected
ReceiveAmount dco_decode_box_autoadd_receive_amount(dynamic raw);
@protected
ReceivePaymentRequest dco_decode_box_autoadd_receive_payment_request(dynamic raw);
@@ -305,6 +311,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
List<String> dco_decode_list_String(dynamic raw);
@protected
List<AssetBalance> dco_decode_list_asset_balance(dynamic raw);
@protected
List<ExternalInputParser> dco_decode_list_external_input_parser(dynamic raw);
@@ -452,6 +461,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
Payment? dco_decode_opt_box_autoadd_payment(dynamic raw);
@protected
ReceiveAmount? dco_decode_opt_box_autoadd_receive_amount(dynamic raw);
@protected
SuccessAction? dco_decode_opt_box_autoadd_success_action(dynamic raw);
@@ -539,6 +551,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
Rate dco_decode_rate(dynamic raw);
@protected
ReceiveAmount dco_decode_receive_amount(dynamic raw);
@protected
ReceivePaymentRequest dco_decode_receive_payment_request(dynamic raw);
@@ -662,6 +677,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
Amount sse_decode_amount(SseDeserializer deserializer);
@protected
AssetBalance sse_decode_asset_balance(SseDeserializer deserializer);
@protected
BackupRequest sse_decode_backup_request(SseDeserializer deserializer);
@@ -804,6 +822,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
PrepareSendRequest sse_decode_box_autoadd_prepare_send_request(SseDeserializer deserializer);
@protected
ReceiveAmount sse_decode_box_autoadd_receive_amount(SseDeserializer deserializer);
@protected
ReceivePaymentRequest sse_decode_box_autoadd_receive_payment_request(SseDeserializer deserializer);
@@ -908,6 +929,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
List<String> sse_decode_list_String(SseDeserializer deserializer);
@protected
List<AssetBalance> sse_decode_list_asset_balance(SseDeserializer deserializer);
@protected
List<ExternalInputParser> sse_decode_list_external_input_parser(SseDeserializer deserializer);
@@ -1055,6 +1079,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
Payment? sse_decode_opt_box_autoadd_payment(SseDeserializer deserializer);
@protected
ReceiveAmount? sse_decode_opt_box_autoadd_receive_amount(SseDeserializer deserializer);
@protected
SuccessAction? sse_decode_opt_box_autoadd_success_action(SseDeserializer deserializer);
@@ -1142,6 +1169,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
Rate sse_decode_rate(SseDeserializer deserializer);
@protected
ReceiveAmount sse_decode_receive_amount(SseDeserializer deserializer);
@protected
ReceivePaymentRequest sse_decode_receive_payment_request(SseDeserializer deserializer);
@@ -1607,6 +1637,14 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
return ptr;
}
@protected
ffi.Pointer<wire_cst_receive_amount> cst_encode_box_autoadd_receive_amount(ReceiveAmount raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
final ptr = wire.cst_new_box_autoadd_receive_amount();
cst_api_fill_to_wire_receive_amount(raw, ptr.ref);
return ptr;
}
@protected
ffi.Pointer<wire_cst_receive_payment_request> cst_encode_box_autoadd_receive_payment_request(
ReceivePaymentRequest raw) {
@@ -1720,6 +1758,16 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
return ans;
}
@protected
ffi.Pointer<wire_cst_list_asset_balance> cst_encode_list_asset_balance(List<AssetBalance> raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
final ans = wire.cst_new_list_asset_balance(raw.length);
for (var i = 0; i < raw.length; ++i) {
cst_api_fill_to_wire_asset_balance(raw[i], ans.ref.ptr[i]);
}
return ans;
}
@protected
ffi.Pointer<wire_cst_list_external_input_parser> cst_encode_list_external_input_parser(
List<ExternalInputParser> raw) {
@@ -1905,6 +1953,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
return raw == null ? ffi.nullptr : cst_encode_box_autoadd_payment(raw);
}
@protected
ffi.Pointer<wire_cst_receive_amount> cst_encode_opt_box_autoadd_receive_amount(ReceiveAmount? raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
return raw == null ? ffi.nullptr : cst_encode_box_autoadd_receive_amount(raw);
}
@protected
ffi.Pointer<wire_cst_success_action> cst_encode_opt_box_autoadd_success_action(SuccessAction? raw) {
// Codec=Cst (C-struct based), see doc to use other codecs
@@ -2023,6 +2077,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
}
}
@protected
void cst_api_fill_to_wire_asset_balance(AssetBalance apiObj, wire_cst_asset_balance wireObj) {
wireObj.asset_id = cst_encode_String(apiObj.assetId);
wireObj.balance = cst_encode_u_64(apiObj.balance);
}
@protected
void cst_api_fill_to_wire_backup_request(BackupRequest apiObj, wire_cst_backup_request wireObj) {
wireObj.backup_path = cst_encode_opt_String(apiObj.backupPath);
@@ -2277,6 +2337,12 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
cst_api_fill_to_wire_prepare_send_request(apiObj, wireObj.ref);
}
@protected
void cst_api_fill_to_wire_box_autoadd_receive_amount(
ReceiveAmount apiObj, ffi.Pointer<wire_cst_receive_amount> wireObj) {
cst_api_fill_to_wire_receive_amount(apiObj, wireObj.ref);
}
@protected
void cst_api_fill_to_wire_box_autoadd_receive_payment_request(
ReceivePaymentRequest apiObj, ffi.Pointer<wire_cst_receive_payment_request> wireObj) {
@@ -2531,13 +2597,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
void cst_api_fill_to_wire_list_payment_details(
ListPaymentDetails apiObj, wire_cst_list_payment_details wireObj) {
if (apiObj is ListPaymentDetails_Liquid) {
var pre_destination = cst_encode_String(apiObj.destination);
var pre_asset_id = cst_encode_opt_String(apiObj.assetId);
var pre_destination = cst_encode_opt_String(apiObj.destination);
wireObj.tag = 0;
wireObj.kind.Liquid.asset_id = pre_asset_id;
wireObj.kind.Liquid.destination = pre_destination;
return;
}
if (apiObj is ListPaymentDetails_Bitcoin) {
var pre_address = cst_encode_String(apiObj.address);
var pre_address = cst_encode_opt_String(apiObj.address);
wireObj.tag = 1;
wireObj.kind.Bitcoin.address = pre_address;
return;
@@ -2906,14 +2974,22 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void cst_api_fill_to_wire_pay_amount(PayAmount apiObj, wire_cst_pay_amount wireObj) {
if (apiObj is PayAmount_Receiver) {
var pre_amount_sat = cst_encode_u_64(apiObj.amountSat);
if (apiObj is PayAmount_Bitcoin) {
var pre_receiver_amount_sat = cst_encode_u_64(apiObj.receiverAmountSat);
wireObj.tag = 0;
wireObj.kind.Receiver.amount_sat = pre_amount_sat;
wireObj.kind.Bitcoin.receiver_amount_sat = pre_receiver_amount_sat;
return;
}
if (apiObj is PayAmount_Asset) {
var pre_asset_id = cst_encode_String(apiObj.assetId);
var pre_receiver_amount = cst_encode_u_64(apiObj.receiverAmount);
wireObj.tag = 1;
wireObj.kind.Asset.asset_id = pre_asset_id;
wireObj.kind.Asset.receiver_amount = pre_receiver_amount;
return;
}
if (apiObj is PayAmount_Drain) {
wireObj.tag = 1;
wireObj.tag = 2;
return;
}
}
@@ -2970,9 +3046,11 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
if (apiObj is PaymentDetails_Liquid) {
var pre_destination = cst_encode_String(apiObj.destination);
var pre_description = cst_encode_String(apiObj.description);
var pre_asset_id = cst_encode_String(apiObj.assetId);
wireObj.tag = 1;
wireObj.kind.Liquid.destination = pre_destination;
wireObj.kind.Liquid.description = pre_description;
wireObj.kind.Liquid.asset_id = pre_asset_id;
return;
}
if (apiObj is PaymentDetails_Bitcoin) {
@@ -3159,15 +3237,15 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void cst_api_fill_to_wire_prepare_receive_request(
PrepareReceiveRequest apiObj, wire_cst_prepare_receive_request wireObj) {
wireObj.payer_amount_sat = cst_encode_opt_box_autoadd_u_64(apiObj.payerAmountSat);
wireObj.payment_method = cst_encode_payment_method(apiObj.paymentMethod);
wireObj.amount = cst_encode_opt_box_autoadd_receive_amount(apiObj.amount);
}
@protected
void cst_api_fill_to_wire_prepare_receive_response(
PrepareReceiveResponse apiObj, wire_cst_prepare_receive_response wireObj) {
wireObj.payment_method = cst_encode_payment_method(apiObj.paymentMethod);
wireObj.payer_amount_sat = cst_encode_opt_box_autoadd_u_64(apiObj.payerAmountSat);
wireObj.amount = cst_encode_opt_box_autoadd_receive_amount(apiObj.amount);
wireObj.fees_sat = cst_encode_u_64(apiObj.feesSat);
wireObj.min_payer_amount_sat = cst_encode_opt_box_autoadd_u_64(apiObj.minPayerAmountSat);
wireObj.max_payer_amount_sat = cst_encode_opt_box_autoadd_u_64(apiObj.maxPayerAmountSat);
@@ -3210,6 +3288,24 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
wireObj.value = cst_encode_f_64(apiObj.value);
}
@protected
void cst_api_fill_to_wire_receive_amount(ReceiveAmount apiObj, wire_cst_receive_amount wireObj) {
if (apiObj is ReceiveAmount_Bitcoin) {
var pre_payer_amount_sat = cst_encode_u_64(apiObj.payerAmountSat);
wireObj.tag = 0;
wireObj.kind.Bitcoin.payer_amount_sat = pre_payer_amount_sat;
return;
}
if (apiObj is ReceiveAmount_Asset) {
var pre_asset_id = cst_encode_String(apiObj.assetId);
var pre_payer_amount = cst_encode_opt_box_autoadd_u_64(apiObj.payerAmount);
wireObj.tag = 1;
wireObj.kind.Asset.asset_id = pre_asset_id;
wireObj.kind.Asset.payer_amount = pre_payer_amount;
return;
}
}
@protected
void cst_api_fill_to_wire_receive_payment_request(
ReceivePaymentRequest apiObj, wire_cst_receive_payment_request wireObj) {
@@ -3470,6 +3566,7 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
wireObj.pending_receive_sat = cst_encode_u_64(apiObj.pendingReceiveSat);
wireObj.fingerprint = cst_encode_String(apiObj.fingerprint);
wireObj.pubkey = cst_encode_String(apiObj.pubkey);
wireObj.asset_balances = cst_encode_list_asset_balance(apiObj.assetBalances);
}
@protected
@@ -3564,6 +3661,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_amount(Amount self, SseSerializer serializer);
@protected
void sse_encode_asset_balance(AssetBalance self, SseSerializer serializer);
@protected
void sse_encode_backup_request(BackupRequest self, SseSerializer serializer);
@@ -3712,6 +3812,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_box_autoadd_prepare_send_request(PrepareSendRequest self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_receive_amount(ReceiveAmount self, SseSerializer serializer);
@protected
void sse_encode_box_autoadd_receive_payment_request(ReceivePaymentRequest self, SseSerializer serializer);
@@ -3817,6 +3920,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_list_String(List<String> self, SseSerializer serializer);
@protected
void sse_encode_list_asset_balance(List<AssetBalance> self, SseSerializer serializer);
@protected
void sse_encode_list_external_input_parser(List<ExternalInputParser> self, SseSerializer serializer);
@@ -3965,6 +4071,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_opt_box_autoadd_payment(Payment? self, SseSerializer serializer);
@protected
void sse_encode_opt_box_autoadd_receive_amount(ReceiveAmount? self, SseSerializer serializer);
@protected
void sse_encode_opt_box_autoadd_success_action(SuccessAction? self, SseSerializer serializer);
@@ -4053,6 +4162,9 @@ abstract class RustLibApiImplPlatform extends BaseApiImpl<RustLibWire> {
@protected
void sse_encode_rate(Rate self, SseSerializer serializer);
@protected
void sse_encode_receive_amount(ReceiveAmount self, SseSerializer serializer);
@protected
void sse_encode_receive_payment_request(ReceivePaymentRequest self, SseSerializer serializer);
@@ -5408,6 +5520,16 @@ class RustLibWire implements BaseWire {
late final _cst_new_box_autoadd_prepare_send_request = _cst_new_box_autoadd_prepare_send_requestPtr
.asFunction<ffi.Pointer<wire_cst_prepare_send_request> Function()>();
ffi.Pointer<wire_cst_receive_amount> cst_new_box_autoadd_receive_amount() {
return _cst_new_box_autoadd_receive_amount();
}
late final _cst_new_box_autoadd_receive_amountPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_receive_amount> Function()>>(
'frbgen_breez_liquid_cst_new_box_autoadd_receive_amount');
late final _cst_new_box_autoadd_receive_amount =
_cst_new_box_autoadd_receive_amountPtr.asFunction<ffi.Pointer<wire_cst_receive_amount> Function()>();
ffi.Pointer<wire_cst_receive_payment_request> cst_new_box_autoadd_receive_payment_request() {
return _cst_new_box_autoadd_receive_payment_request();
}
@@ -5550,6 +5672,20 @@ class RustLibWire implements BaseWire {
late final _cst_new_list_String =
_cst_new_list_StringPtr.asFunction<ffi.Pointer<wire_cst_list_String> Function(int)>();
ffi.Pointer<wire_cst_list_asset_balance> cst_new_list_asset_balance(
int len,
) {
return _cst_new_list_asset_balance(
len,
);
}
late final _cst_new_list_asset_balancePtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_list_asset_balance> Function(ffi.Int32)>>(
'frbgen_breez_liquid_cst_new_list_asset_balance');
late final _cst_new_list_asset_balance =
_cst_new_list_asset_balancePtr.asFunction<ffi.Pointer<wire_cst_list_asset_balance> Function(int)>();
ffi.Pointer<wire_cst_list_external_input_parser> cst_new_list_external_input_parser(
int len,
) {
@@ -5836,6 +5972,8 @@ final class wire_cst_list_payment_state extends ffi.Struct {
}
final class wire_cst_ListPaymentDetails_Liquid extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> asset_id;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> destination;
}
@@ -6205,13 +6343,22 @@ final class wire_cst_prepare_ln_url_pay_request extends ffi.Struct {
external ffi.Pointer<ffi.Bool> validate_success_action_url;
}
final class wire_cst_PayAmount_Receiver extends ffi.Struct {
final class wire_cst_PayAmount_Bitcoin extends ffi.Struct {
@ffi.Uint64()
external int amount_sat;
external int receiver_amount_sat;
}
final class wire_cst_PayAmount_Asset extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> asset_id;
@ffi.Uint64()
external int receiver_amount;
}
final class PayAmountKind extends ffi.Union {
external wire_cst_PayAmount_Receiver Receiver;
external wire_cst_PayAmount_Bitcoin Bitcoin;
external wire_cst_PayAmount_Asset Asset;
}
final class wire_cst_pay_amount extends ffi.Struct {
@@ -6227,11 +6374,35 @@ final class wire_cst_prepare_pay_onchain_request extends ffi.Struct {
external ffi.Pointer<ffi.Uint32> fee_rate_sat_per_vbyte;
}
final class wire_cst_prepare_receive_request extends ffi.Struct {
external ffi.Pointer<ffi.Uint64> payer_amount_sat;
final class wire_cst_ReceiveAmount_Bitcoin extends ffi.Struct {
@ffi.Uint64()
external int payer_amount_sat;
}
final class wire_cst_ReceiveAmount_Asset extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> asset_id;
external ffi.Pointer<ffi.Uint64> payer_amount;
}
final class ReceiveAmountKind extends ffi.Union {
external wire_cst_ReceiveAmount_Bitcoin Bitcoin;
external wire_cst_ReceiveAmount_Asset Asset;
}
final class wire_cst_receive_amount extends ffi.Struct {
@ffi.Int32()
external int tag;
external ReceiveAmountKind kind;
}
final class wire_cst_prepare_receive_request extends ffi.Struct {
@ffi.Int32()
external int payment_method;
external ffi.Pointer<wire_cst_receive_amount> amount;
}
final class wire_cst_prepare_refund_request extends ffi.Struct {
@@ -6253,7 +6424,7 @@ final class wire_cst_prepare_receive_response extends ffi.Struct {
@ffi.Int32()
external int payment_method;
external ffi.Pointer<ffi.Uint64> payer_amount_sat;
external ffi.Pointer<wire_cst_receive_amount> amount;
@ffi.Uint64()
external int fees_sat;
@@ -6404,6 +6575,8 @@ final class wire_cst_PaymentDetails_Liquid extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> destination;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> description;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> asset_id;
}
final class wire_cst_PaymentDetails_Bitcoin extends ffi.Struct {
@@ -6620,6 +6793,20 @@ final class wire_cst_symbol extends ffi.Struct {
external ffi.Pointer<ffi.Uint32> position;
}
final class wire_cst_asset_balance extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> asset_id;
@ffi.Uint64()
external int balance;
}
final class wire_cst_list_asset_balance extends ffi.Struct {
external ffi.Pointer<wire_cst_asset_balance> ptr;
@ffi.Int32()
external int len;
}
final class wire_cst_localized_name extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> locale;
@@ -6744,6 +6931,8 @@ final class wire_cst_wallet_info extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> fingerprint;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> pubkey;
external ffi.Pointer<wire_cst_list_asset_balance> asset_balances;
}
final class wire_cst_get_info_response extends ffi.Struct {

View File

@@ -28,6 +28,28 @@ class AcceptPaymentProposedFeesRequest {
response == other.response;
}
/// An asset balance to denote the balance for each asset.
class AssetBalance {
final String assetId;
final BigInt balance;
const AssetBalance({
required this.assetId,
required this.balance,
});
@override
int get hashCode => assetId.hashCode ^ balance.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is AssetBalance &&
runtimeType == other.runtimeType &&
assetId == other.assetId &&
balance == other.balance;
}
/// An argument when calling [crate::sdk::LiquidSdk::backup].
class BackupRequest {
/// Path to the backup.
@@ -430,14 +452,19 @@ enum LiquidNetwork {
sealed class ListPaymentDetails with _$ListPaymentDetails {
const ListPaymentDetails._();
/// The Liquid BIP21 URI or address of the payment
/// A Liquid payment
const factory ListPaymentDetails.liquid({
required String destination,
/// Optional asset id
String? assetId,
/// Optional BIP21 URI or address
String? destination,
}) = ListPaymentDetails_Liquid;
/// The Bitcoin address of the payment
/// A Bitcoin payment
const factory ListPaymentDetails.bitcoin({
required String address,
/// Optional address
String? address,
}) = ListPaymentDetails_Bitcoin;
}
@@ -642,11 +669,17 @@ sealed class PayAmount with _$PayAmount {
const PayAmount._();
/// The amount in satoshi that will be received
const factory PayAmount.receiver({
required BigInt amountSat,
}) = PayAmount_Receiver;
const factory PayAmount.bitcoin({
required BigInt receiverAmountSat,
}) = PayAmount_Bitcoin;
/// Indicates that all available funds should be sent
/// The amount of an asset that will be received
const factory PayAmount.asset({
required String assetId,
required BigInt receiverAmount,
}) = PayAmount_Asset;
/// Indicates that all available Bitcoin funds should be sent
const factory PayAmount.drain() = PayAmount_Drain;
}
@@ -819,6 +852,9 @@ sealed class PaymentDetails with _$PaymentDetails {
/// Represents the BIP21 `message` field
required String description,
/// The asset id
required String assetId,
}) = PaymentDetails_Liquid;
/// Swapping to or from the Bitcoin chain
@@ -1121,30 +1157,32 @@ class PreparePayOnchainResponse {
/// An argument when calling [crate::sdk::LiquidSdk::prepare_receive_payment].
class PrepareReceiveRequest {
final BigInt? payerAmountSat;
final PaymentMethod paymentMethod;
/// The amount to be paid in either Bitcoin or another asset
final ReceiveAmount? amount;
const PrepareReceiveRequest({
this.payerAmountSat,
required this.paymentMethod,
this.amount,
});
@override
int get hashCode => payerAmountSat.hashCode ^ paymentMethod.hashCode;
int get hashCode => paymentMethod.hashCode ^ amount.hashCode;
@override
bool operator ==(Object other) =>
identical(this, other) ||
other is PrepareReceiveRequest &&
runtimeType == other.runtimeType &&
payerAmountSat == other.payerAmountSat &&
paymentMethod == other.paymentMethod;
paymentMethod == other.paymentMethod &&
amount == other.amount;
}
/// Returned when calling [crate::sdk::LiquidSdk::prepare_receive_payment].
class PrepareReceiveResponse {
final PaymentMethod paymentMethod;
final BigInt? payerAmountSat;
final ReceiveAmount? amount;
/// Generally represents the total fees that would be paid to send or receive this payment.
///
@@ -1173,7 +1211,7 @@ class PrepareReceiveResponse {
const PrepareReceiveResponse({
required this.paymentMethod,
this.payerAmountSat,
this.amount,
required this.feesSat,
this.minPayerAmountSat,
this.maxPayerAmountSat,
@@ -1183,7 +1221,7 @@ class PrepareReceiveResponse {
@override
int get hashCode =>
paymentMethod.hashCode ^
payerAmountSat.hashCode ^
amount.hashCode ^
feesSat.hashCode ^
minPayerAmountSat.hashCode ^
maxPayerAmountSat.hashCode ^
@@ -1195,7 +1233,7 @@ class PrepareReceiveResponse {
other is PrepareReceiveResponse &&
runtimeType == other.runtimeType &&
paymentMethod == other.paymentMethod &&
payerAmountSat == other.payerAmountSat &&
amount == other.amount &&
feesSat == other.feesSat &&
minPayerAmountSat == other.minPayerAmountSat &&
maxPayerAmountSat == other.maxPayerAmountSat &&
@@ -1308,6 +1346,22 @@ class PrepareSendResponse {
feesSat == other.feesSat;
}
@freezed
sealed class ReceiveAmount with _$ReceiveAmount {
const ReceiveAmount._();
/// The amount in satoshi that should be paid
const factory ReceiveAmount.bitcoin({
required BigInt payerAmountSat,
}) = ReceiveAmount_Bitcoin;
/// The amount of an asset that should be paid
const factory ReceiveAmount.asset({
required String assetId,
BigInt? payerAmount,
}) = ReceiveAmount_Asset;
}
/// An argument when calling [crate::sdk::LiquidSdk::receive_payment].
class ReceivePaymentRequest {
final PrepareReceiveResponse prepareResponse;
@@ -1622,12 +1676,16 @@ class WalletInfo {
/// The wallet's pubkey. Used to verify signed messages.
final String pubkey;
/// Asset balances of non Liquid Bitcoin assets
final List<AssetBalance> assetBalances;
const WalletInfo({
required this.balanceSat,
required this.pendingSendSat,
required this.pendingReceiveSat,
required this.fingerprint,
required this.pubkey,
required this.assetBalances,
});
@override
@@ -1636,7 +1694,8 @@ class WalletInfo {
pendingSendSat.hashCode ^
pendingReceiveSat.hashCode ^
fingerprint.hashCode ^
pubkey.hashCode;
pubkey.hashCode ^
assetBalances.hashCode;
@override
bool operator ==(Object other) =>
@@ -1647,5 +1706,6 @@ class WalletInfo {
pendingSendSat == other.pendingSendSat &&
pendingReceiveSat == other.pendingReceiveSat &&
fingerprint == other.fingerprint &&
pubkey == other.pubkey;
pubkey == other.pubkey &&
assetBalances == other.assetBalances;
}

View File

@@ -170,7 +170,7 @@ abstract class _$$ListPaymentDetails_LiquidImplCopyWith<$Res> {
_$ListPaymentDetails_LiquidImpl value, $Res Function(_$ListPaymentDetails_LiquidImpl) then) =
__$$ListPaymentDetails_LiquidImplCopyWithImpl<$Res>;
@useResult
$Res call({String destination});
$Res call({String? assetId, String? destination});
}
/// @nodoc
@@ -186,13 +186,18 @@ class __$$ListPaymentDetails_LiquidImplCopyWithImpl<$Res>
@pragma('vm:prefer-inline')
@override
$Res call({
Object? destination = null,
Object? assetId = freezed,
Object? destination = freezed,
}) {
return _then(_$ListPaymentDetails_LiquidImpl(
destination: null == destination
assetId: freezed == assetId
? _value.assetId
: assetId // ignore: cast_nullable_to_non_nullable
as String?,
destination: freezed == destination
? _value.destination
: destination // ignore: cast_nullable_to_non_nullable
as String,
as String?,
));
}
}
@@ -200,14 +205,19 @@ class __$$ListPaymentDetails_LiquidImplCopyWithImpl<$Res>
/// @nodoc
class _$ListPaymentDetails_LiquidImpl extends ListPaymentDetails_Liquid {
const _$ListPaymentDetails_LiquidImpl({required this.destination}) : super._();
const _$ListPaymentDetails_LiquidImpl({this.assetId, this.destination}) : super._();
/// Optional asset id
@override
final String destination;
final String? assetId;
/// Optional BIP21 URI or address
@override
final String? destination;
@override
String toString() {
return 'ListPaymentDetails.liquid(destination: $destination)';
return 'ListPaymentDetails.liquid(assetId: $assetId, destination: $destination)';
}
@override
@@ -215,11 +225,12 @@ class _$ListPaymentDetails_LiquidImpl extends ListPaymentDetails_Liquid {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ListPaymentDetails_LiquidImpl &&
(identical(other.assetId, assetId) || other.assetId == assetId) &&
(identical(other.destination, destination) || other.destination == destination));
}
@override
int get hashCode => Object.hash(runtimeType, destination);
int get hashCode => Object.hash(runtimeType, assetId, destination);
/// Create a copy of ListPaymentDetails
/// with the given fields replaced by the non-null parameter values.
@@ -231,11 +242,15 @@ class _$ListPaymentDetails_LiquidImpl extends ListPaymentDetails_Liquid {
}
abstract class ListPaymentDetails_Liquid extends ListPaymentDetails {
const factory ListPaymentDetails_Liquid({required final String destination}) =
const factory ListPaymentDetails_Liquid({final String? assetId, final String? destination}) =
_$ListPaymentDetails_LiquidImpl;
const ListPaymentDetails_Liquid._() : super._();
String get destination;
/// Optional asset id
String? get assetId;
/// Optional BIP21 URI or address
String? get destination;
/// Create a copy of ListPaymentDetails
/// with the given fields replaced by the non-null parameter values.
@@ -250,7 +265,7 @@ abstract class _$$ListPaymentDetails_BitcoinImplCopyWith<$Res> {
_$ListPaymentDetails_BitcoinImpl value, $Res Function(_$ListPaymentDetails_BitcoinImpl) then) =
__$$ListPaymentDetails_BitcoinImplCopyWithImpl<$Res>;
@useResult
$Res call({String address});
$Res call({String? address});
}
/// @nodoc
@@ -266,13 +281,13 @@ class __$$ListPaymentDetails_BitcoinImplCopyWithImpl<$Res>
@pragma('vm:prefer-inline')
@override
$Res call({
Object? address = null,
Object? address = freezed,
}) {
return _then(_$ListPaymentDetails_BitcoinImpl(
address: null == address
address: freezed == address
? _value.address
: address // ignore: cast_nullable_to_non_nullable
as String,
as String?,
));
}
}
@@ -280,10 +295,11 @@ class __$$ListPaymentDetails_BitcoinImplCopyWithImpl<$Res>
/// @nodoc
class _$ListPaymentDetails_BitcoinImpl extends ListPaymentDetails_Bitcoin {
const _$ListPaymentDetails_BitcoinImpl({required this.address}) : super._();
const _$ListPaymentDetails_BitcoinImpl({this.address}) : super._();
/// Optional address
@override
final String address;
final String? address;
@override
String toString() {
@@ -311,11 +327,11 @@ class _$ListPaymentDetails_BitcoinImpl extends ListPaymentDetails_Bitcoin {
}
abstract class ListPaymentDetails_Bitcoin extends ListPaymentDetails {
const factory ListPaymentDetails_Bitcoin({required final String address}) =
_$ListPaymentDetails_BitcoinImpl;
const factory ListPaymentDetails_Bitcoin({final String? address}) = _$ListPaymentDetails_BitcoinImpl;
const ListPaymentDetails_Bitcoin._() : super._();
String get address;
/// Optional address
String? get address;
/// Create a copy of ListPaymentDetails
/// with the given fields replaced by the non-null parameter values.
@@ -616,20 +632,20 @@ class _$PayAmountCopyWithImpl<$Res, $Val extends PayAmount> implements $PayAmoun
}
/// @nodoc
abstract class _$$PayAmount_ReceiverImplCopyWith<$Res> {
factory _$$PayAmount_ReceiverImplCopyWith(
_$PayAmount_ReceiverImpl value, $Res Function(_$PayAmount_ReceiverImpl) then) =
__$$PayAmount_ReceiverImplCopyWithImpl<$Res>;
abstract class _$$PayAmount_BitcoinImplCopyWith<$Res> {
factory _$$PayAmount_BitcoinImplCopyWith(
_$PayAmount_BitcoinImpl value, $Res Function(_$PayAmount_BitcoinImpl) then) =
__$$PayAmount_BitcoinImplCopyWithImpl<$Res>;
@useResult
$Res call({BigInt amountSat});
$Res call({BigInt receiverAmountSat});
}
/// @nodoc
class __$$PayAmount_ReceiverImplCopyWithImpl<$Res>
extends _$PayAmountCopyWithImpl<$Res, _$PayAmount_ReceiverImpl>
implements _$$PayAmount_ReceiverImplCopyWith<$Res> {
__$$PayAmount_ReceiverImplCopyWithImpl(
_$PayAmount_ReceiverImpl _value, $Res Function(_$PayAmount_ReceiverImpl) _then)
class __$$PayAmount_BitcoinImplCopyWithImpl<$Res>
extends _$PayAmountCopyWithImpl<$Res, _$PayAmount_BitcoinImpl>
implements _$$PayAmount_BitcoinImplCopyWith<$Res> {
__$$PayAmount_BitcoinImplCopyWithImpl(
_$PayAmount_BitcoinImpl _value, $Res Function(_$PayAmount_BitcoinImpl) _then)
: super(_value, _then);
/// Create a copy of PayAmount
@@ -637,12 +653,12 @@ class __$$PayAmount_ReceiverImplCopyWithImpl<$Res>
@pragma('vm:prefer-inline')
@override
$Res call({
Object? amountSat = null,
Object? receiverAmountSat = null,
}) {
return _then(_$PayAmount_ReceiverImpl(
amountSat: null == amountSat
? _value.amountSat
: amountSat // ignore: cast_nullable_to_non_nullable
return _then(_$PayAmount_BitcoinImpl(
receiverAmountSat: null == receiverAmountSat
? _value.receiverAmountSat
: receiverAmountSat // ignore: cast_nullable_to_non_nullable
as BigInt,
));
}
@@ -650,50 +666,138 @@ class __$$PayAmount_ReceiverImplCopyWithImpl<$Res>
/// @nodoc
class _$PayAmount_ReceiverImpl extends PayAmount_Receiver {
const _$PayAmount_ReceiverImpl({required this.amountSat}) : super._();
class _$PayAmount_BitcoinImpl extends PayAmount_Bitcoin {
const _$PayAmount_BitcoinImpl({required this.receiverAmountSat}) : super._();
@override
final BigInt amountSat;
final BigInt receiverAmountSat;
@override
String toString() {
return 'PayAmount.receiver(amountSat: $amountSat)';
return 'PayAmount.bitcoin(receiverAmountSat: $receiverAmountSat)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$PayAmount_ReceiverImpl &&
(identical(other.amountSat, amountSat) || other.amountSat == amountSat));
other is _$PayAmount_BitcoinImpl &&
(identical(other.receiverAmountSat, receiverAmountSat) ||
other.receiverAmountSat == receiverAmountSat));
}
@override
int get hashCode => Object.hash(runtimeType, amountSat);
int get hashCode => Object.hash(runtimeType, receiverAmountSat);
/// Create a copy of PayAmount
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$PayAmount_ReceiverImplCopyWith<_$PayAmount_ReceiverImpl> get copyWith =>
__$$PayAmount_ReceiverImplCopyWithImpl<_$PayAmount_ReceiverImpl>(this, _$identity);
_$$PayAmount_BitcoinImplCopyWith<_$PayAmount_BitcoinImpl> get copyWith =>
__$$PayAmount_BitcoinImplCopyWithImpl<_$PayAmount_BitcoinImpl>(this, _$identity);
}
abstract class PayAmount_Receiver extends PayAmount {
const factory PayAmount_Receiver({required final BigInt amountSat}) = _$PayAmount_ReceiverImpl;
const PayAmount_Receiver._() : super._();
abstract class PayAmount_Bitcoin extends PayAmount {
const factory PayAmount_Bitcoin({required final BigInt receiverAmountSat}) = _$PayAmount_BitcoinImpl;
const PayAmount_Bitcoin._() : super._();
BigInt get amountSat;
BigInt get receiverAmountSat;
/// Create a copy of PayAmount
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$PayAmount_ReceiverImplCopyWith<_$PayAmount_ReceiverImpl> get copyWith =>
_$$PayAmount_BitcoinImplCopyWith<_$PayAmount_BitcoinImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$PayAmount_AssetImplCopyWith<$Res> {
factory _$$PayAmount_AssetImplCopyWith(
_$PayAmount_AssetImpl value, $Res Function(_$PayAmount_AssetImpl) then) =
__$$PayAmount_AssetImplCopyWithImpl<$Res>;
@useResult
$Res call({String assetId, BigInt receiverAmount});
}
/// @nodoc
class __$$PayAmount_AssetImplCopyWithImpl<$Res> extends _$PayAmountCopyWithImpl<$Res, _$PayAmount_AssetImpl>
implements _$$PayAmount_AssetImplCopyWith<$Res> {
__$$PayAmount_AssetImplCopyWithImpl(
_$PayAmount_AssetImpl _value, $Res Function(_$PayAmount_AssetImpl) _then)
: super(_value, _then);
/// Create a copy of PayAmount
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? assetId = null,
Object? receiverAmount = null,
}) {
return _then(_$PayAmount_AssetImpl(
assetId: null == assetId
? _value.assetId
: assetId // ignore: cast_nullable_to_non_nullable
as String,
receiverAmount: null == receiverAmount
? _value.receiverAmount
: receiverAmount // ignore: cast_nullable_to_non_nullable
as BigInt,
));
}
}
/// @nodoc
class _$PayAmount_AssetImpl extends PayAmount_Asset {
const _$PayAmount_AssetImpl({required this.assetId, required this.receiverAmount}) : super._();
@override
final String assetId;
@override
final BigInt receiverAmount;
@override
String toString() {
return 'PayAmount.asset(assetId: $assetId, receiverAmount: $receiverAmount)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$PayAmount_AssetImpl &&
(identical(other.assetId, assetId) || other.assetId == assetId) &&
(identical(other.receiverAmount, receiverAmount) || other.receiverAmount == receiverAmount));
}
@override
int get hashCode => Object.hash(runtimeType, assetId, receiverAmount);
/// Create a copy of PayAmount
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$PayAmount_AssetImplCopyWith<_$PayAmount_AssetImpl> get copyWith =>
__$$PayAmount_AssetImplCopyWithImpl<_$PayAmount_AssetImpl>(this, _$identity);
}
abstract class PayAmount_Asset extends PayAmount {
const factory PayAmount_Asset({required final String assetId, required final BigInt receiverAmount}) =
_$PayAmount_AssetImpl;
const PayAmount_Asset._() : super._();
String get assetId;
BigInt get receiverAmount;
/// Create a copy of PayAmount
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$PayAmount_AssetImplCopyWith<_$PayAmount_AssetImpl> get copyWith => throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$PayAmount_DrainImplCopyWith<$Res> {
factory _$$PayAmount_DrainImplCopyWith(
@@ -1038,7 +1142,7 @@ abstract class _$$PaymentDetails_LiquidImplCopyWith<$Res> implements $PaymentDet
__$$PaymentDetails_LiquidImplCopyWithImpl<$Res>;
@override
@useResult
$Res call({String destination, String description});
$Res call({String destination, String description, String assetId});
}
/// @nodoc
@@ -1056,6 +1160,7 @@ class __$$PaymentDetails_LiquidImplCopyWithImpl<$Res>
$Res call({
Object? destination = null,
Object? description = null,
Object? assetId = null,
}) {
return _then(_$PaymentDetails_LiquidImpl(
destination: null == destination
@@ -1066,6 +1171,10 @@ class __$$PaymentDetails_LiquidImplCopyWithImpl<$Res>
? _value.description
: description // ignore: cast_nullable_to_non_nullable
as String,
assetId: null == assetId
? _value.assetId
: assetId // ignore: cast_nullable_to_non_nullable
as String,
));
}
}
@@ -1073,7 +1182,9 @@ class __$$PaymentDetails_LiquidImplCopyWithImpl<$Res>
/// @nodoc
class _$PaymentDetails_LiquidImpl extends PaymentDetails_Liquid {
const _$PaymentDetails_LiquidImpl({required this.destination, required this.description}) : super._();
const _$PaymentDetails_LiquidImpl(
{required this.destination, required this.description, required this.assetId})
: super._();
/// Represents either a Liquid BIP21 URI or pure address
@override
@@ -1083,9 +1194,13 @@ class _$PaymentDetails_LiquidImpl extends PaymentDetails_Liquid {
@override
final String description;
/// The asset id
@override
final String assetId;
@override
String toString() {
return 'PaymentDetails.liquid(destination: $destination, description: $description)';
return 'PaymentDetails.liquid(destination: $destination, description: $description, assetId: $assetId)';
}
@override
@@ -1094,11 +1209,12 @@ class _$PaymentDetails_LiquidImpl extends PaymentDetails_Liquid {
(other.runtimeType == runtimeType &&
other is _$PaymentDetails_LiquidImpl &&
(identical(other.destination, destination) || other.destination == destination) &&
(identical(other.description, description) || other.description == description));
(identical(other.description, description) || other.description == description) &&
(identical(other.assetId, assetId) || other.assetId == assetId));
}
@override
int get hashCode => Object.hash(runtimeType, destination, description);
int get hashCode => Object.hash(runtimeType, destination, description, assetId);
/// Create a copy of PaymentDetails
/// with the given fields replaced by the non-null parameter values.
@@ -1111,7 +1227,9 @@ class _$PaymentDetails_LiquidImpl extends PaymentDetails_Liquid {
abstract class PaymentDetails_Liquid extends PaymentDetails {
const factory PaymentDetails_Liquid(
{required final String destination, required final String description}) = _$PaymentDetails_LiquidImpl;
{required final String destination,
required final String description,
required final String assetId}) = _$PaymentDetails_LiquidImpl;
const PaymentDetails_Liquid._() : super._();
/// Represents either a Liquid BIP21 URI or pure address
@@ -1121,6 +1239,9 @@ abstract class PaymentDetails_Liquid extends PaymentDetails {
@override
String get description;
/// The asset id
String get assetId;
/// Create a copy of PaymentDetails
/// with the given fields replaced by the non-null parameter values.
@override
@@ -1324,6 +1445,196 @@ abstract class PaymentDetails_Bitcoin extends PaymentDetails {
throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$ReceiveAmount {}
/// @nodoc
abstract class $ReceiveAmountCopyWith<$Res> {
factory $ReceiveAmountCopyWith(ReceiveAmount value, $Res Function(ReceiveAmount) then) =
_$ReceiveAmountCopyWithImpl<$Res, ReceiveAmount>;
}
/// @nodoc
class _$ReceiveAmountCopyWithImpl<$Res, $Val extends ReceiveAmount> implements $ReceiveAmountCopyWith<$Res> {
_$ReceiveAmountCopyWithImpl(this._value, this._then);
// ignore: unused_field
final $Val _value;
// ignore: unused_field
final $Res Function($Val) _then;
/// Create a copy of ReceiveAmount
/// with the given fields replaced by the non-null parameter values.
}
/// @nodoc
abstract class _$$ReceiveAmount_BitcoinImplCopyWith<$Res> {
factory _$$ReceiveAmount_BitcoinImplCopyWith(
_$ReceiveAmount_BitcoinImpl value, $Res Function(_$ReceiveAmount_BitcoinImpl) then) =
__$$ReceiveAmount_BitcoinImplCopyWithImpl<$Res>;
@useResult
$Res call({BigInt payerAmountSat});
}
/// @nodoc
class __$$ReceiveAmount_BitcoinImplCopyWithImpl<$Res>
extends _$ReceiveAmountCopyWithImpl<$Res, _$ReceiveAmount_BitcoinImpl>
implements _$$ReceiveAmount_BitcoinImplCopyWith<$Res> {
__$$ReceiveAmount_BitcoinImplCopyWithImpl(
_$ReceiveAmount_BitcoinImpl _value, $Res Function(_$ReceiveAmount_BitcoinImpl) _then)
: super(_value, _then);
/// Create a copy of ReceiveAmount
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? payerAmountSat = null,
}) {
return _then(_$ReceiveAmount_BitcoinImpl(
payerAmountSat: null == payerAmountSat
? _value.payerAmountSat
: payerAmountSat // ignore: cast_nullable_to_non_nullable
as BigInt,
));
}
}
/// @nodoc
class _$ReceiveAmount_BitcoinImpl extends ReceiveAmount_Bitcoin {
const _$ReceiveAmount_BitcoinImpl({required this.payerAmountSat}) : super._();
@override
final BigInt payerAmountSat;
@override
String toString() {
return 'ReceiveAmount.bitcoin(payerAmountSat: $payerAmountSat)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ReceiveAmount_BitcoinImpl &&
(identical(other.payerAmountSat, payerAmountSat) || other.payerAmountSat == payerAmountSat));
}
@override
int get hashCode => Object.hash(runtimeType, payerAmountSat);
/// Create a copy of ReceiveAmount
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ReceiveAmount_BitcoinImplCopyWith<_$ReceiveAmount_BitcoinImpl> get copyWith =>
__$$ReceiveAmount_BitcoinImplCopyWithImpl<_$ReceiveAmount_BitcoinImpl>(this, _$identity);
}
abstract class ReceiveAmount_Bitcoin extends ReceiveAmount {
const factory ReceiveAmount_Bitcoin({required final BigInt payerAmountSat}) = _$ReceiveAmount_BitcoinImpl;
const ReceiveAmount_Bitcoin._() : super._();
BigInt get payerAmountSat;
/// Create a copy of ReceiveAmount
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ReceiveAmount_BitcoinImplCopyWith<_$ReceiveAmount_BitcoinImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
abstract class _$$ReceiveAmount_AssetImplCopyWith<$Res> {
factory _$$ReceiveAmount_AssetImplCopyWith(
_$ReceiveAmount_AssetImpl value, $Res Function(_$ReceiveAmount_AssetImpl) then) =
__$$ReceiveAmount_AssetImplCopyWithImpl<$Res>;
@useResult
$Res call({String assetId, BigInt? payerAmount});
}
/// @nodoc
class __$$ReceiveAmount_AssetImplCopyWithImpl<$Res>
extends _$ReceiveAmountCopyWithImpl<$Res, _$ReceiveAmount_AssetImpl>
implements _$$ReceiveAmount_AssetImplCopyWith<$Res> {
__$$ReceiveAmount_AssetImplCopyWithImpl(
_$ReceiveAmount_AssetImpl _value, $Res Function(_$ReceiveAmount_AssetImpl) _then)
: super(_value, _then);
/// Create a copy of ReceiveAmount
/// with the given fields replaced by the non-null parameter values.
@pragma('vm:prefer-inline')
@override
$Res call({
Object? assetId = null,
Object? payerAmount = freezed,
}) {
return _then(_$ReceiveAmount_AssetImpl(
assetId: null == assetId
? _value.assetId
: assetId // ignore: cast_nullable_to_non_nullable
as String,
payerAmount: freezed == payerAmount
? _value.payerAmount
: payerAmount // ignore: cast_nullable_to_non_nullable
as BigInt?,
));
}
}
/// @nodoc
class _$ReceiveAmount_AssetImpl extends ReceiveAmount_Asset {
const _$ReceiveAmount_AssetImpl({required this.assetId, this.payerAmount}) : super._();
@override
final String assetId;
@override
final BigInt? payerAmount;
@override
String toString() {
return 'ReceiveAmount.asset(assetId: $assetId, payerAmount: $payerAmount)';
}
@override
bool operator ==(Object other) {
return identical(this, other) ||
(other.runtimeType == runtimeType &&
other is _$ReceiveAmount_AssetImpl &&
(identical(other.assetId, assetId) || other.assetId == assetId) &&
(identical(other.payerAmount, payerAmount) || other.payerAmount == payerAmount));
}
@override
int get hashCode => Object.hash(runtimeType, assetId, payerAmount);
/// Create a copy of ReceiveAmount
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
@override
@pragma('vm:prefer-inline')
_$$ReceiveAmount_AssetImplCopyWith<_$ReceiveAmount_AssetImpl> get copyWith =>
__$$ReceiveAmount_AssetImplCopyWithImpl<_$ReceiveAmount_AssetImpl>(this, _$identity);
}
abstract class ReceiveAmount_Asset extends ReceiveAmount {
const factory ReceiveAmount_Asset({required final String assetId, final BigInt? payerAmount}) =
_$ReceiveAmount_AssetImpl;
const ReceiveAmount_Asset._() : super._();
String get assetId;
BigInt? get payerAmount;
/// Create a copy of ReceiveAmount
/// with the given fields replaced by the non-null parameter values.
@JsonKey(includeFromJson: false, includeToJson: false)
_$$ReceiveAmount_AssetImplCopyWith<_$ReceiveAmount_AssetImpl> get copyWith =>
throw _privateConstructorUsedError;
}
/// @nodoc
mixin _$SdkEvent {}

View File

@@ -1338,6 +1338,17 @@ class FlutterBreezLiquidBindings {
_frbgen_breez_liquid_cst_new_box_autoadd_prepare_send_requestPtr
.asFunction<ffi.Pointer<wire_cst_prepare_send_request> Function()>();
ffi.Pointer<wire_cst_receive_amount> frbgen_breez_liquid_cst_new_box_autoadd_receive_amount() {
return _frbgen_breez_liquid_cst_new_box_autoadd_receive_amount();
}
late final _frbgen_breez_liquid_cst_new_box_autoadd_receive_amountPtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_receive_amount> Function()>>(
'frbgen_breez_liquid_cst_new_box_autoadd_receive_amount');
late final _frbgen_breez_liquid_cst_new_box_autoadd_receive_amount =
_frbgen_breez_liquid_cst_new_box_autoadd_receive_amountPtr
.asFunction<ffi.Pointer<wire_cst_receive_amount> Function()>();
ffi.Pointer<wire_cst_receive_payment_request>
frbgen_breez_liquid_cst_new_box_autoadd_receive_payment_request() {
return _frbgen_breez_liquid_cst_new_box_autoadd_receive_payment_request();
@@ -1493,6 +1504,21 @@ class FlutterBreezLiquidBindings {
late final _frbgen_breez_liquid_cst_new_list_String = _frbgen_breez_liquid_cst_new_list_StringPtr
.asFunction<ffi.Pointer<wire_cst_list_String> Function(int)>();
ffi.Pointer<wire_cst_list_asset_balance> frbgen_breez_liquid_cst_new_list_asset_balance(
int len,
) {
return _frbgen_breez_liquid_cst_new_list_asset_balance(
len,
);
}
late final _frbgen_breez_liquid_cst_new_list_asset_balancePtr =
_lookup<ffi.NativeFunction<ffi.Pointer<wire_cst_list_asset_balance> Function(ffi.Int32)>>(
'frbgen_breez_liquid_cst_new_list_asset_balance');
late final _frbgen_breez_liquid_cst_new_list_asset_balance =
_frbgen_breez_liquid_cst_new_list_asset_balancePtr
.asFunction<ffi.Pointer<wire_cst_list_asset_balance> Function(int)>();
ffi.Pointer<wire_cst_list_external_input_parser> frbgen_breez_liquid_cst_new_list_external_input_parser(
int len,
) {
@@ -4156,6 +4182,8 @@ final class wire_cst_list_payment_state extends ffi.Struct {
}
final class wire_cst_ListPaymentDetails_Liquid extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> asset_id;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> destination;
}
@@ -4525,13 +4553,22 @@ final class wire_cst_prepare_ln_url_pay_request extends ffi.Struct {
external ffi.Pointer<ffi.Bool> validate_success_action_url;
}
final class wire_cst_PayAmount_Receiver extends ffi.Struct {
final class wire_cst_PayAmount_Bitcoin extends ffi.Struct {
@ffi.Uint64()
external int amount_sat;
external int receiver_amount_sat;
}
final class wire_cst_PayAmount_Asset extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> asset_id;
@ffi.Uint64()
external int receiver_amount;
}
final class PayAmountKind extends ffi.Union {
external wire_cst_PayAmount_Receiver Receiver;
external wire_cst_PayAmount_Bitcoin Bitcoin;
external wire_cst_PayAmount_Asset Asset;
}
final class wire_cst_pay_amount extends ffi.Struct {
@@ -4547,11 +4584,35 @@ final class wire_cst_prepare_pay_onchain_request extends ffi.Struct {
external ffi.Pointer<ffi.Uint32> fee_rate_sat_per_vbyte;
}
final class wire_cst_prepare_receive_request extends ffi.Struct {
external ffi.Pointer<ffi.Uint64> payer_amount_sat;
final class wire_cst_ReceiveAmount_Bitcoin extends ffi.Struct {
@ffi.Uint64()
external int payer_amount_sat;
}
final class wire_cst_ReceiveAmount_Asset extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> asset_id;
external ffi.Pointer<ffi.Uint64> payer_amount;
}
final class ReceiveAmountKind extends ffi.Union {
external wire_cst_ReceiveAmount_Bitcoin Bitcoin;
external wire_cst_ReceiveAmount_Asset Asset;
}
final class wire_cst_receive_amount extends ffi.Struct {
@ffi.Int32()
external int tag;
external ReceiveAmountKind kind;
}
final class wire_cst_prepare_receive_request extends ffi.Struct {
@ffi.Int32()
external int payment_method;
external ffi.Pointer<wire_cst_receive_amount> amount;
}
final class wire_cst_prepare_refund_request extends ffi.Struct {
@@ -4573,7 +4634,7 @@ final class wire_cst_prepare_receive_response extends ffi.Struct {
@ffi.Int32()
external int payment_method;
external ffi.Pointer<ffi.Uint64> payer_amount_sat;
external ffi.Pointer<wire_cst_receive_amount> amount;
@ffi.Uint64()
external int fees_sat;
@@ -4724,6 +4785,8 @@ final class wire_cst_PaymentDetails_Liquid extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> destination;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> description;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> asset_id;
}
final class wire_cst_PaymentDetails_Bitcoin extends ffi.Struct {
@@ -4940,6 +5003,20 @@ final class wire_cst_symbol extends ffi.Struct {
external ffi.Pointer<ffi.Uint32> position;
}
final class wire_cst_asset_balance extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> asset_id;
@ffi.Uint64()
external int balance;
}
final class wire_cst_list_asset_balance extends ffi.Struct {
external ffi.Pointer<wire_cst_asset_balance> ptr;
@ffi.Int32()
external int len;
}
final class wire_cst_localized_name extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> locale;
@@ -5064,6 +5141,8 @@ final class wire_cst_wallet_info extends ffi.Struct {
external ffi.Pointer<wire_cst_list_prim_u_8_strict> fingerprint;
external ffi.Pointer<wire_cst_list_prim_u_8_strict> pubkey;
external ffi.Pointer<wire_cst_list_asset_balance> asset_balances;
}
final class wire_cst_get_info_response extends ffi.Struct {

View File

@@ -102,6 +102,39 @@ fun asAesSuccessActionDataDecryptedList(arr: ReadableArray): List<AesSuccessActi
return list
}
fun asAssetBalance(assetBalance: ReadableMap): AssetBalance? {
if (!validateMandatoryFields(
assetBalance,
arrayOf(
"assetId",
"balance",
),
)
) {
return null
}
val assetId = assetBalance.getString("assetId")!!
val balance = assetBalance.getDouble("balance").toULong()
return AssetBalance(assetId, balance)
}
fun readableMapOf(assetBalance: AssetBalance): ReadableMap =
readableMapOf(
"assetId" to assetBalance.assetId,
"balance" to assetBalance.balance,
)
fun asAssetBalanceList(arr: ReadableArray): List<AssetBalance> {
val list = ArrayList<AssetBalance>()
for (value in arr.toList()) {
when (value) {
is ReadableMap -> list.add(asAssetBalance(value)!!)
else -> throw SdkException.Generic(errUnexpectedType(value))
}
}
return list
}
fun asBackupRequest(backupRequest: ReadableMap): BackupRequest? {
if (!validateMandatoryFields(
backupRequest,
@@ -1927,23 +1960,21 @@ fun asPrepareReceiveRequest(prepareReceiveRequest: ReadableMap): PrepareReceiveR
return null
}
val paymentMethod = prepareReceiveRequest.getString("paymentMethod")?.let { asPaymentMethod(it) }!!
val payerAmountSat =
if (hasNonNullKey(
prepareReceiveRequest,
"payerAmountSat",
)
) {
prepareReceiveRequest.getDouble("payerAmountSat").toULong()
val amount =
if (hasNonNullKey(prepareReceiveRequest, "amount")) {
prepareReceiveRequest.getMap("amount")?.let {
asReceiveAmount(it)
}
} else {
null
}
return PrepareReceiveRequest(paymentMethod, payerAmountSat)
return PrepareReceiveRequest(paymentMethod, amount)
}
fun readableMapOf(prepareReceiveRequest: PrepareReceiveRequest): ReadableMap =
readableMapOf(
"paymentMethod" to prepareReceiveRequest.paymentMethod.name.lowercase(),
"payerAmountSat" to prepareReceiveRequest.payerAmountSat,
"amount" to prepareReceiveRequest.amount?.let { readableMapOf(it) },
)
fun asPrepareReceiveRequestList(arr: ReadableArray): List<PrepareReceiveRequest> {
@@ -1970,13 +2001,11 @@ fun asPrepareReceiveResponse(prepareReceiveResponse: ReadableMap): PrepareReceiv
}
val paymentMethod = prepareReceiveResponse.getString("paymentMethod")?.let { asPaymentMethod(it) }!!
val feesSat = prepareReceiveResponse.getDouble("feesSat").toULong()
val payerAmountSat =
if (hasNonNullKey(
prepareReceiveResponse,
"payerAmountSat",
)
) {
prepareReceiveResponse.getDouble("payerAmountSat").toULong()
val amount =
if (hasNonNullKey(prepareReceiveResponse, "amount")) {
prepareReceiveResponse.getMap("amount")?.let {
asReceiveAmount(it)
}
} else {
null
}
@@ -2010,14 +2039,14 @@ fun asPrepareReceiveResponse(prepareReceiveResponse: ReadableMap): PrepareReceiv
} else {
null
}
return PrepareReceiveResponse(paymentMethod, feesSat, payerAmountSat, minPayerAmountSat, maxPayerAmountSat, swapperFeerate)
return PrepareReceiveResponse(paymentMethod, feesSat, amount, minPayerAmountSat, maxPayerAmountSat, swapperFeerate)
}
fun readableMapOf(prepareReceiveResponse: PrepareReceiveResponse): ReadableMap =
readableMapOf(
"paymentMethod" to prepareReceiveResponse.paymentMethod.name.lowercase(),
"feesSat" to prepareReceiveResponse.feesSat,
"payerAmountSat" to prepareReceiveResponse.payerAmountSat,
"amount" to prepareReceiveResponse.amount?.let { readableMapOf(it) },
"minPayerAmountSat" to prepareReceiveResponse.minPayerAmountSat,
"maxPayerAmountSat" to prepareReceiveResponse.maxPayerAmountSat,
"swapperFeerate" to prepareReceiveResponse.swapperFeerate,
@@ -2742,6 +2771,7 @@ fun asWalletInfo(walletInfo: ReadableMap): WalletInfo? {
"pendingReceiveSat",
"fingerprint",
"pubkey",
"assetBalances",
),
)
) {
@@ -2752,7 +2782,8 @@ fun asWalletInfo(walletInfo: ReadableMap): WalletInfo? {
val pendingReceiveSat = walletInfo.getDouble("pendingReceiveSat").toULong()
val fingerprint = walletInfo.getString("fingerprint")!!
val pubkey = walletInfo.getString("pubkey")!!
return WalletInfo(balanceSat, pendingSendSat, pendingReceiveSat, fingerprint, pubkey)
val assetBalances = walletInfo.getArray("assetBalances")?.let { asAssetBalanceList(it) }!!
return WalletInfo(balanceSat, pendingSendSat, pendingReceiveSat, fingerprint, pubkey, assetBalances)
}
fun readableMapOf(walletInfo: WalletInfo): ReadableMap =
@@ -2762,6 +2793,7 @@ fun readableMapOf(walletInfo: WalletInfo): ReadableMap =
"pendingReceiveSat" to walletInfo.pendingReceiveSat,
"fingerprint" to walletInfo.fingerprint,
"pubkey" to walletInfo.pubkey,
"assetBalances" to readableArrayOf(walletInfo.assetBalances),
)
fun asWalletInfoList(arr: ReadableArray): List<WalletInfo> {
@@ -3023,11 +3055,12 @@ fun asListPaymentDetails(listPaymentDetails: ReadableMap): ListPaymentDetails? {
val type = listPaymentDetails.getString("type")
if (type == "liquid") {
val destination = listPaymentDetails.getString("destination")!!
return ListPaymentDetails.Liquid(destination)
val assetId = if (hasNonNullKey(listPaymentDetails, "assetId")) listPaymentDetails.getString("assetId") else null
val destination = if (hasNonNullKey(listPaymentDetails, "destination")) listPaymentDetails.getString("destination") else null
return ListPaymentDetails.Liquid(assetId, destination)
}
if (type == "bitcoin") {
val address = listPaymentDetails.getString("address")!!
val address = if (hasNonNullKey(listPaymentDetails, "address")) listPaymentDetails.getString("address") else null
return ListPaymentDetails.Bitcoin(address)
}
return null
@@ -3038,6 +3071,7 @@ fun readableMapOf(listPaymentDetails: ListPaymentDetails): ReadableMap? {
when (listPaymentDetails) {
is ListPaymentDetails.Liquid -> {
pushToMap(map, "type", "liquid")
pushToMap(map, "assetId", listPaymentDetails.assetId)
pushToMap(map, "destination", listPaymentDetails.destination)
}
is ListPaymentDetails.Bitcoin -> {
@@ -3209,9 +3243,14 @@ fun asNetworkList(arr: ReadableArray): List<Network> {
fun asPayAmount(payAmount: ReadableMap): PayAmount? {
val type = payAmount.getString("type")
if (type == "receiver") {
val amountSat = payAmount.getDouble("amountSat").toULong()
return PayAmount.Receiver(amountSat)
if (type == "bitcoin") {
val receiverAmountSat = payAmount.getDouble("receiverAmountSat").toULong()
return PayAmount.Bitcoin(receiverAmountSat)
}
if (type == "asset") {
val assetId = payAmount.getString("assetId")!!
val receiverAmount = payAmount.getDouble("receiverAmount").toULong()
return PayAmount.Asset(assetId, receiverAmount)
}
if (type == "drain") {
return PayAmount.Drain
@@ -3222,9 +3261,14 @@ fun asPayAmount(payAmount: ReadableMap): PayAmount? {
fun readableMapOf(payAmount: PayAmount): ReadableMap? {
val map = Arguments.createMap()
when (payAmount) {
is PayAmount.Receiver -> {
pushToMap(map, "type", "receiver")
pushToMap(map, "amountSat", payAmount.amountSat)
is PayAmount.Bitcoin -> {
pushToMap(map, "type", "bitcoin")
pushToMap(map, "receiverAmountSat", payAmount.receiverAmountSat)
}
is PayAmount.Asset -> {
pushToMap(map, "type", "asset")
pushToMap(map, "assetId", payAmount.assetId)
pushToMap(map, "receiverAmount", payAmount.receiverAmount)
}
is PayAmount.Drain -> {
pushToMap(map, "type", "drain")
@@ -3301,9 +3345,10 @@ fun asPaymentDetails(paymentDetails: ReadableMap): PaymentDetails? {
)
}
if (type == "liquid") {
val assetId = paymentDetails.getString("assetId")!!
val destination = paymentDetails.getString("destination")!!
val description = paymentDetails.getString("description")!!
return PaymentDetails.Liquid(destination, description)
return PaymentDetails.Liquid(assetId, destination, description)
}
if (type == "bitcoin") {
val swapId = paymentDetails.getString("swapId")!!
@@ -3372,6 +3417,7 @@ fun readableMapOf(paymentDetails: PaymentDetails): ReadableMap? {
}
is PaymentDetails.Liquid -> {
pushToMap(map, "type", "liquid")
pushToMap(map, "assetId", paymentDetails.assetId)
pushToMap(map, "destination", paymentDetails.destination)
pushToMap(map, "description", paymentDetails.description)
}
@@ -3439,6 +3485,48 @@ fun asPaymentTypeList(arr: ReadableArray): List<PaymentType> {
return list
}
fun asReceiveAmount(receiveAmount: ReadableMap): ReceiveAmount? {
val type = receiveAmount.getString("type")
if (type == "bitcoin") {
val payerAmountSat = receiveAmount.getDouble("payerAmountSat").toULong()
return ReceiveAmount.Bitcoin(payerAmountSat)
}
if (type == "asset") {
val assetId = receiveAmount.getString("assetId")!!
val payerAmount = if (hasNonNullKey(receiveAmount, "payerAmount")) receiveAmount.getDouble("payerAmount").toULong() else null
return ReceiveAmount.Asset(assetId, payerAmount)
}
return null
}
fun readableMapOf(receiveAmount: ReceiveAmount): ReadableMap? {
val map = Arguments.createMap()
when (receiveAmount) {
is ReceiveAmount.Bitcoin -> {
pushToMap(map, "type", "bitcoin")
pushToMap(map, "payerAmountSat", receiveAmount.payerAmountSat)
}
is ReceiveAmount.Asset -> {
pushToMap(map, "type", "asset")
pushToMap(map, "assetId", receiveAmount.assetId)
pushToMap(map, "payerAmount", receiveAmount.payerAmount)
}
}
return map
}
fun asReceiveAmountList(arr: ReadableArray): List<ReceiveAmount> {
val list = ArrayList<ReceiveAmount>()
for (value in arr.toList()) {
when (value) {
is ReadableMap -> list.add(asReceiveAmount(value)!!)
else -> throw SdkException.Generic(errUnexpectedType(value))
}
}
return list
}
fun asSdkEvent(sdkEvent: ReadableMap): SdkEvent? {
val type = sdkEvent.getString("type")
@@ -3709,6 +3797,7 @@ fun pushToArray(
) {
when (value) {
null -> array.pushNull()
is AssetBalance -> array.pushMap(readableMapOf(value))
is ExternalInputParser -> array.pushMap(readableMapOf(value))
is FiatCurrency -> array.pushMap(readableMapOf(value))
is LnOfferBlindedPath -> array.pushMap(readableMapOf(value))

View File

@@ -18,6 +18,7 @@ import {
removeEventListener,
prepareReceivePayment,
prepareSendPayment,
ReceiveAmountVariant,
receivePayment,
sendPayment,
PaymentMethod
@@ -84,8 +85,8 @@ const App = () => {
addLine("addEventListener", listenerId)
/* Receive lightning payment */
let prepareReceiveRes = await prepareReceivePayment({ payerAmountSat: 1000, paymentMethod: PaymentMethod.LIGHTNING })
let amount = { type: ReceiveAmountVariant.BITCOIN, payerAmountSat: 1000 }
let prepareReceiveRes = await prepareReceivePayment({ amount, paymentMethod: PaymentMethod.LIGHTNING })
addLine("prepareReceivePayment", JSON.stringify(prepareReceiveRes))
// Get the fees required for this payment
addLine("Payment fees", `${prepareReceiveRes.feesSat}`)

View File

@@ -108,6 +108,41 @@ enum BreezSDKLiquidMapper {
return aesSuccessActionDataDecryptedList.map { v -> [String: Any?] in return dictionaryOf(aesSuccessActionDataDecrypted: v) }
}
static func asAssetBalance(assetBalance: [String: Any?]) throws -> AssetBalance {
guard let assetId = assetBalance["assetId"] as? String else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "assetId", typeName: "AssetBalance"))
}
guard let balance = assetBalance["balance"] as? UInt64 else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "balance", typeName: "AssetBalance"))
}
return AssetBalance(assetId: assetId, balance: balance)
}
static func dictionaryOf(assetBalance: AssetBalance) -> [String: Any?] {
return [
"assetId": assetBalance.assetId,
"balance": assetBalance.balance,
]
}
static func asAssetBalanceList(arr: [Any]) throws -> [AssetBalance] {
var list = [AssetBalance]()
for value in arr {
if let val = value as? [String: Any?] {
var assetBalance = try asAssetBalance(assetBalance: val)
list.append(assetBalance)
} else {
throw SdkError.Generic(message: errUnexpectedType(typeName: "AssetBalance"))
}
}
return list
}
static func arrayOf(assetBalanceList: [AssetBalance]) -> [Any] {
return assetBalanceList.map { v -> [String: Any?] in return dictionaryOf(assetBalance: v) }
}
static func asBackupRequest(backupRequest: [String: Any?]) throws -> BackupRequest {
var backupPath: String?
if hasNonNilKey(data: backupRequest, key: "backupPath") {
@@ -2249,21 +2284,18 @@ enum BreezSDKLiquidMapper {
}
let paymentMethod = try asPaymentMethod(paymentMethod: paymentMethodTmp)
var payerAmountSat: UInt64?
if hasNonNilKey(data: prepareReceiveRequest, key: "payerAmountSat") {
guard let payerAmountSatTmp = prepareReceiveRequest["payerAmountSat"] as? UInt64 else {
throw SdkError.Generic(message: errUnexpectedValue(fieldName: "payerAmountSat"))
}
payerAmountSat = payerAmountSatTmp
var amount: ReceiveAmount?
if let amountTmp = prepareReceiveRequest["amount"] as? [String: Any?] {
amount = try asReceiveAmount(receiveAmount: amountTmp)
}
return PrepareReceiveRequest(paymentMethod: paymentMethod, payerAmountSat: payerAmountSat)
return PrepareReceiveRequest(paymentMethod: paymentMethod, amount: amount)
}
static func dictionaryOf(prepareReceiveRequest: PrepareReceiveRequest) -> [String: Any?] {
return [
"paymentMethod": valueOf(paymentMethod: prepareReceiveRequest.paymentMethod),
"payerAmountSat": prepareReceiveRequest.payerAmountSat == nil ? nil : prepareReceiveRequest.payerAmountSat,
"amount": prepareReceiveRequest.amount == nil ? nil : dictionaryOf(receiveAmount: prepareReceiveRequest.amount!),
]
}
@@ -2293,13 +2325,11 @@ enum BreezSDKLiquidMapper {
guard let feesSat = prepareReceiveResponse["feesSat"] as? UInt64 else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "feesSat", typeName: "PrepareReceiveResponse"))
}
var payerAmountSat: UInt64?
if hasNonNilKey(data: prepareReceiveResponse, key: "payerAmountSat") {
guard let payerAmountSatTmp = prepareReceiveResponse["payerAmountSat"] as? UInt64 else {
throw SdkError.Generic(message: errUnexpectedValue(fieldName: "payerAmountSat"))
}
payerAmountSat = payerAmountSatTmp
var amount: ReceiveAmount?
if let amountTmp = prepareReceiveResponse["amount"] as? [String: Any?] {
amount = try asReceiveAmount(receiveAmount: amountTmp)
}
var minPayerAmountSat: UInt64?
if hasNonNilKey(data: prepareReceiveResponse, key: "minPayerAmountSat") {
guard let minPayerAmountSatTmp = prepareReceiveResponse["minPayerAmountSat"] as? UInt64 else {
@@ -2322,14 +2352,14 @@ enum BreezSDKLiquidMapper {
swapperFeerate = swapperFeerateTmp
}
return PrepareReceiveResponse(paymentMethod: paymentMethod, feesSat: feesSat, payerAmountSat: payerAmountSat, minPayerAmountSat: minPayerAmountSat, maxPayerAmountSat: maxPayerAmountSat, swapperFeerate: swapperFeerate)
return PrepareReceiveResponse(paymentMethod: paymentMethod, feesSat: feesSat, amount: amount, minPayerAmountSat: minPayerAmountSat, maxPayerAmountSat: maxPayerAmountSat, swapperFeerate: swapperFeerate)
}
static func dictionaryOf(prepareReceiveResponse: PrepareReceiveResponse) -> [String: Any?] {
return [
"paymentMethod": valueOf(paymentMethod: prepareReceiveResponse.paymentMethod),
"feesSat": prepareReceiveResponse.feesSat,
"payerAmountSat": prepareReceiveResponse.payerAmountSat == nil ? nil : prepareReceiveResponse.payerAmountSat,
"amount": prepareReceiveResponse.amount == nil ? nil : dictionaryOf(receiveAmount: prepareReceiveResponse.amount!),
"minPayerAmountSat": prepareReceiveResponse.minPayerAmountSat == nil ? nil : prepareReceiveResponse.minPayerAmountSat,
"maxPayerAmountSat": prepareReceiveResponse.maxPayerAmountSat == nil ? nil : prepareReceiveResponse.maxPayerAmountSat,
"swapperFeerate": prepareReceiveResponse.swapperFeerate == nil ? nil : prepareReceiveResponse.swapperFeerate,
@@ -3157,8 +3187,12 @@ enum BreezSDKLiquidMapper {
guard let pubkey = walletInfo["pubkey"] as? String else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "pubkey", typeName: "WalletInfo"))
}
guard let assetBalancesTmp = walletInfo["assetBalances"] as? [[String: Any?]] else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "assetBalances", typeName: "WalletInfo"))
}
let assetBalances = try asAssetBalanceList(arr: assetBalancesTmp)
return WalletInfo(balanceSat: balanceSat, pendingSendSat: pendingSendSat, pendingReceiveSat: pendingReceiveSat, fingerprint: fingerprint, pubkey: pubkey)
return WalletInfo(balanceSat: balanceSat, pendingSendSat: pendingSendSat, pendingReceiveSat: pendingReceiveSat, fingerprint: fingerprint, pubkey: pubkey, assetBalances: assetBalances)
}
static func dictionaryOf(walletInfo: WalletInfo) -> [String: Any?] {
@@ -3168,6 +3202,7 @@ enum BreezSDKLiquidMapper {
"pendingReceiveSat": walletInfo.pendingReceiveSat,
"fingerprint": walletInfo.fingerprint,
"pubkey": walletInfo.pubkey,
"assetBalances": arrayOf(assetBalanceList: walletInfo.assetBalances),
]
}
@@ -3603,15 +3638,15 @@ enum BreezSDKLiquidMapper {
static func asListPaymentDetails(listPaymentDetails: [String: Any?]) throws -> ListPaymentDetails {
let type = listPaymentDetails["type"] as! String
if type == "liquid" {
guard let _destination = listPaymentDetails["destination"] as? String else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "destination", typeName: "ListPaymentDetails"))
}
return ListPaymentDetails.liquid(destination: _destination)
let _assetId = listPaymentDetails["assetId"] as? String
let _destination = listPaymentDetails["destination"] as? String
return ListPaymentDetails.liquid(assetId: _assetId, destination: _destination)
}
if type == "bitcoin" {
guard let _address = listPaymentDetails["address"] as? String else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "address", typeName: "ListPaymentDetails"))
}
let _address = listPaymentDetails["address"] as? String
return ListPaymentDetails.bitcoin(address: _address)
}
@@ -3621,11 +3656,12 @@ enum BreezSDKLiquidMapper {
static func dictionaryOf(listPaymentDetails: ListPaymentDetails) -> [String: Any?] {
switch listPaymentDetails {
case let .liquid(
destination
assetId, destination
):
return [
"type": "liquid",
"destination": destination,
"assetId": assetId == nil ? nil : assetId,
"destination": destination == nil ? nil : destination,
]
case let .bitcoin(
@@ -3633,7 +3669,7 @@ enum BreezSDKLiquidMapper {
):
return [
"type": "bitcoin",
"address": address,
"address": address == nil ? nil : address,
]
}
}
@@ -3909,11 +3945,20 @@ enum BreezSDKLiquidMapper {
static func asPayAmount(payAmount: [String: Any?]) throws -> PayAmount {
let type = payAmount["type"] as! String
if type == "receiver" {
guard let _amountSat = payAmount["amountSat"] as? UInt64 else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "amountSat", typeName: "PayAmount"))
if type == "bitcoin" {
guard let _receiverAmountSat = payAmount["receiverAmountSat"] as? UInt64 else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "receiverAmountSat", typeName: "PayAmount"))
}
return PayAmount.receiver(amountSat: _amountSat)
return PayAmount.bitcoin(receiverAmountSat: _receiverAmountSat)
}
if type == "asset" {
guard let _assetId = payAmount["assetId"] as? String else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "assetId", typeName: "PayAmount"))
}
guard let _receiverAmount = payAmount["receiverAmount"] as? UInt64 else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "receiverAmount", typeName: "PayAmount"))
}
return PayAmount.asset(assetId: _assetId, receiverAmount: _receiverAmount)
}
if type == "drain" {
return PayAmount.drain
@@ -3924,12 +3969,21 @@ enum BreezSDKLiquidMapper {
static func dictionaryOf(payAmount: PayAmount) -> [String: Any?] {
switch payAmount {
case let .receiver(
amountSat
case let .bitcoin(
receiverAmountSat
):
return [
"type": "receiver",
"amountSat": amountSat,
"type": "bitcoin",
"receiverAmountSat": receiverAmountSat,
]
case let .asset(
assetId, receiverAmount
):
return [
"type": "asset",
"assetId": assetId,
"receiverAmount": receiverAmount,
]
case .drain:
@@ -3990,13 +4044,16 @@ enum BreezSDKLiquidMapper {
return PaymentDetails.lightning(swapId: _swapId, description: _description, liquidExpirationBlockheight: _liquidExpirationBlockheight, preimage: _preimage, invoice: _invoice, bolt12Offer: _bolt12Offer, paymentHash: _paymentHash, destinationPubkey: _destinationPubkey, lnurlInfo: _lnurlInfo, refundTxId: _refundTxId, refundTxAmountSat: _refundTxAmountSat)
}
if type == "liquid" {
guard let _assetId = paymentDetails["assetId"] as? String else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "assetId", typeName: "PaymentDetails"))
}
guard let _destination = paymentDetails["destination"] as? String else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "destination", typeName: "PaymentDetails"))
}
guard let _description = paymentDetails["description"] as? String else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "description", typeName: "PaymentDetails"))
}
return PaymentDetails.liquid(destination: _destination, description: _description)
return PaymentDetails.liquid(assetId: _assetId, destination: _destination, description: _description)
}
if type == "bitcoin" {
guard let _swapId = paymentDetails["swapId"] as? String else {
@@ -4043,10 +4100,11 @@ enum BreezSDKLiquidMapper {
]
case let .liquid(
destination, description
assetId, destination, description
):
return [
"type": "liquid",
"assetId": assetId,
"destination": destination,
"description": description,
]
@@ -4243,6 +4301,64 @@ enum BreezSDKLiquidMapper {
return list
}
static func asReceiveAmount(receiveAmount: [String: Any?]) throws -> ReceiveAmount {
let type = receiveAmount["type"] as! String
if type == "bitcoin" {
guard let _payerAmountSat = receiveAmount["payerAmountSat"] as? UInt64 else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "payerAmountSat", typeName: "ReceiveAmount"))
}
return ReceiveAmount.bitcoin(payerAmountSat: _payerAmountSat)
}
if type == "asset" {
guard let _assetId = receiveAmount["assetId"] as? String else {
throw SdkError.Generic(message: errMissingMandatoryField(fieldName: "assetId", typeName: "ReceiveAmount"))
}
let _payerAmount = receiveAmount["payerAmount"] as? UInt64
return ReceiveAmount.asset(assetId: _assetId, payerAmount: _payerAmount)
}
throw SdkError.Generic(message: "Unexpected type \(type) for enum ReceiveAmount")
}
static func dictionaryOf(receiveAmount: ReceiveAmount) -> [String: Any?] {
switch receiveAmount {
case let .bitcoin(
payerAmountSat
):
return [
"type": "bitcoin",
"payerAmountSat": payerAmountSat,
]
case let .asset(
assetId, payerAmount
):
return [
"type": "asset",
"assetId": assetId,
"payerAmount": payerAmount == nil ? nil : payerAmount,
]
}
}
static func arrayOf(receiveAmountList: [ReceiveAmount]) -> [Any] {
return receiveAmountList.map { v -> [String: Any?] in return dictionaryOf(receiveAmount: v) }
}
static func asReceiveAmountList(arr: [Any]) throws -> [ReceiveAmount] {
var list = [ReceiveAmount]()
for value in arr {
if let val = value as? [String: Any?] {
var receiveAmount = try asReceiveAmount(receiveAmount: val)
list.append(receiveAmount)
} else {
throw SdkError.Generic(message: errUnexpectedType(typeName: "ReceiveAmount"))
}
}
return list
}
static func asSdkEvent(sdkEvent: [String: Any?]) throws -> SdkEvent {
let type = sdkEvent["type"] as! String
if type == "paymentFailed" {

View File

@@ -34,6 +34,11 @@ export interface AesSuccessActionDataDecrypted {
plaintext: string
}
export interface AssetBalance {
assetId: string
balance: number
}
export interface BackupRequest {
backupPath?: string
}
@@ -337,13 +342,13 @@ export interface PreparePayOnchainResponse {
export interface PrepareReceiveRequest {
paymentMethod: PaymentMethod
payerAmountSat?: number
amount?: ReceiveAmount
}
export interface PrepareReceiveResponse {
paymentMethod: PaymentMethod
feesSat: number
payerAmountSat?: number
amount?: ReceiveAmount
minPayerAmountSat?: number
maxPayerAmountSat?: number
swapperFeerate?: number
@@ -464,6 +469,7 @@ export interface WalletInfo {
pendingReceiveSat: number
fingerprint: string
pubkey: string
assetBalances: AssetBalance[]
}
export enum AesSuccessActionDataResultVariant {
@@ -563,10 +569,11 @@ export enum ListPaymentDetailsVariant {
export type ListPaymentDetails = {
type: ListPaymentDetailsVariant.LIQUID,
destination: string
assetId?: string
destination?: string
} | {
type: ListPaymentDetailsVariant.BITCOIN,
address: string
address?: string
}
export enum LnUrlCallbackStatusVariant {
@@ -623,13 +630,18 @@ export enum Network {
}
export enum PayAmountVariant {
RECEIVER = "receiver",
BITCOIN = "bitcoin",
ASSET = "asset",
DRAIN = "drain"
}
export type PayAmount = {
type: PayAmountVariant.RECEIVER,
amountSat: number
type: PayAmountVariant.BITCOIN,
receiverAmountSat: number
} | {
type: PayAmountVariant.ASSET,
assetId: string
receiverAmount: number
} | {
type: PayAmountVariant.DRAIN
}
@@ -655,6 +667,7 @@ export type PaymentDetails = {
refundTxAmountSat?: number
} | {
type: PaymentDetailsVariant.LIQUID,
assetId: string
destination: string
description: string
} | {
@@ -690,6 +703,20 @@ export enum PaymentType {
SEND = "send"
}
export enum ReceiveAmountVariant {
BITCOIN = "bitcoin",
ASSET = "asset"
}
export type ReceiveAmount = {
type: ReceiveAmountVariant.BITCOIN,
payerAmountSat: number
} | {
type: ReceiveAmountVariant.ASSET,
assetId: string
payerAmount?: number
}
export enum SdkEventVariant {
PAYMENT_FAILED = "paymentFailed",
PAYMENT_PENDING = "paymentPending",