Skip to content

Commit

Permalink
Multi-asset send/receive
Browse files Browse the repository at this point in the history
  • Loading branch information
dangeross committed Jan 7, 2025
1 parent b9ef4e8 commit 8e447d0
Show file tree
Hide file tree
Showing 22 changed files with 1,050 additions and 230 deletions.
32 changes: 28 additions & 4 deletions cli/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ pub(crate) enum Command {
#[arg(short, long)]
amount_sat: 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)]
drain: Option<bool>,
Expand Down Expand Up @@ -72,11 +77,16 @@ pub(crate) enum Command {
#[arg(short = 'm', long = "method")]
payment_method: Option<PaymentMethod>,

/// Amount the payer will send, in satoshi
/// Amount the payer will send, in satoshi units. If receiving a non Liquid Bitcoin
/// asset, this is the units of the asset to receive.
/// If not specified, it will generate a BIP21 URI/Liquid address with no amount
#[arg(short, long)]
payer_amount_sat: 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")]
description: Option<String>,
Expand Down Expand Up @@ -118,6 +128,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>,
Expand Down Expand Up @@ -267,12 +281,14 @@ pub(crate) async fn handle_command(
Command::ReceivePayment {
payment_method,
payer_amount_sat,
asset_id,
description,
use_description_hash,
} => {
let prepare_response = sdk
.prepare_receive_payment(&PrepareReceiveRequest {
payer_amount_sat,
asset_id,
payment_method: payment_method.unwrap_or(PaymentMethod::Lightning),
})
.await?;
Expand Down Expand Up @@ -333,6 +349,7 @@ pub(crate) async fn handle_command(
offer,
address,
amount_sat,
asset_id,
drain,
delay,
} => {
Expand Down Expand Up @@ -364,6 +381,7 @@ pub(crate) async fn handle_command(
.prepare_send_payment(&PrepareSendRequest {
destination,
amount,
asset_id,
})
.await?;

Expand Down Expand Up @@ -488,12 +506,18 @@ pub(crate) async fn handle_command(
to_timestamp,
limit,
offset,
asset_id,
destination,
address,
} => {
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 }),
_ => None,
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,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;

Expand Down Expand Up @@ -373,8 +374,9 @@ typedef struct wire_cst_prepare_pay_onchain_request {
} wire_cst_prepare_pay_onchain_request;

typedef struct wire_cst_prepare_receive_request {
uint64_t *payer_amount_sat;
int32_t payment_method;
uint64_t *payer_amount_sat;
struct wire_cst_list_prim_u_8_strict *asset_id;
} wire_cst_prepare_receive_request;

typedef struct wire_cst_prepare_refund_request {
Expand All @@ -386,11 +388,13 @@ typedef struct wire_cst_prepare_refund_request {
typedef struct wire_cst_prepare_send_request {
struct wire_cst_list_prim_u_8_strict *destination;
struct wire_cst_pay_amount *amount;
struct wire_cst_list_prim_u_8_strict *asset_id;
} wire_cst_prepare_send_request;

typedef struct wire_cst_prepare_receive_response {
int32_t payment_method;
uint64_t *payer_amount_sat;
struct wire_cst_list_prim_u_8_strict *asset_id;
uint64_t fees_sat;
uint64_t *min_payer_amount_sat;
uint64_t *max_payer_amount_sat;
Expand Down Expand Up @@ -501,6 +505,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 {
Expand Down Expand Up @@ -643,6 +648,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;
Expand Down Expand Up @@ -720,6 +735,7 @@ typedef struct wire_cst_get_info_response {
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_get_info_response;

typedef struct wire_cst_InputType_BitcoinAddress {
Expand Down Expand Up @@ -1349,6 +1365,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);
Expand Down Expand Up @@ -1430,6 +1448,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);
Expand Down
13 changes: 11 additions & 2 deletions lib/bindings/src/breez_sdk_liquid.udl
Original file line number Diff line number Diff line change
Expand Up @@ -355,12 +355,18 @@ dictionary ConnectWithSignerRequest {
Config config;
};

dictionary AssetBalance {
string asset_id;
u64 balance;
};

dictionary GetInfoResponse {
u64 balance_sat;
u64 pending_send_sat;
u64 pending_receive_sat;
string fingerprint;
string pubkey;
sequence<AssetBalance> asset_balances;
};

dictionary SignMessageRequest {
Expand Down Expand Up @@ -403,6 +409,7 @@ dictionary LnUrlPayRequest {
dictionary PrepareSendRequest {
string destination;
PayAmount? amount = null;
string? asset_id = null;
};

[Enum]
Expand Down Expand Up @@ -434,12 +441,14 @@ enum PaymentMethod {
dictionary PrepareReceiveRequest {
PaymentMethod payment_method;
u64? payer_amount_sat = null;
string? asset_id = null;
};

dictionary PrepareReceiveResponse {
PaymentMethod payment_method;
u64 fees_sat;
u64? payer_amount_sat;
string? asset_id;
u64? min_payer_amount_sat;
u64? max_payer_amount_sat;
f64? swapper_feerate;
Expand Down Expand Up @@ -533,7 +542,7 @@ dictionary ListPaymentsRequest {

[Enum]
interface ListPaymentDetails {
Liquid(string destination);
Liquid(string? asset_id, string? destination);
Bitcoin(string address);
};

Expand Down Expand Up @@ -570,7 +579,7 @@ dictionary LnUrlInfo {
[Enum]
interface PaymentDetails {
Lightning(string swap_id, string description, string? preimage, string? bolt11, string? bolt12_offer, string? payment_hash, 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, string? refund_tx_id, u64? refund_tx_amount_sat);
};

Expand Down
8 changes: 7 additions & 1 deletion lib/core/src/chain_swap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ use lwk_wollet::{
};
use tokio::sync::{broadcast, Mutex};

use crate::model::{BlockListener, ChainSwapUpdate};
use crate::{
chain::{bitcoin::BitcoinChainService, liquid::LiquidChainService},
ensure_sdk,
Expand All @@ -31,6 +30,10 @@ use crate::{
utils,
wallet::OnchainWallet,
};
use crate::{
model::{BlockListener, ChainSwapUpdate},
wallet::LIQUID_BTC_ASSET_ID,
};

// Estimates based on https://github.com/BoltzExchange/boltz-backend/blob/ee4c77be1fcb9bb2b45703c542ad67f7efbf218d/lib/rates/FeeProvider.ts#L68
pub const ESTIMATED_BTC_CLAIM_TX_VSIZE: u64 = 111;
Expand Down Expand Up @@ -527,6 +530,7 @@ impl ChainSwapHandler {
self.persister.insert_or_update_payment(PaymentTxData {
tx_id: lockup_tx_id.clone(),
timestamp: Some(utils::now()),
asset_id: LIQUID_BTC_ASSET_ID.to_string(),
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,
Expand Down Expand Up @@ -737,6 +741,7 @@ impl ChainSwapHandler {
.build_tx_or_drain_tx(
self.config.lowball_fee_rate_msat_per_vbyte(),
&lockup_details.lockup_address,
LIQUID_BTC_ASSET_ID.as_str(),
lockup_details.amount,
)
.await?;
Expand Down Expand Up @@ -861,6 +866,7 @@ impl ChainSwapHandler {
PaymentTxData {
tx_id: claim_tx_id.clone(),
timestamp: Some(utils::now()),
asset_id: LIQUID_BTC_ASSET_ID.to_string(),
amount_sat: swap.receiver_amount_sat,
fees_sat: 0,
payment_type: PaymentType::Receive,
Expand Down
Loading

0 comments on commit 8e447d0

Please sign in to comment.