Handling multiple assets

The Liquid sidechain can also be used to send and receive other assets registered on the Liquid Network. Using the SDK you can send and receive these assets by using a Liquid payment with an additional asset ID. By default the SDK includes the metadata for L-BTC and Tether USD. To include addition asset metadata, see Adding asset metadata.

Adding asset metadata API docs

You can add addition asset metadata to the SDK when you configure it on connect. In the example below we will add the PEGx EUR asset. Once the asset metadata is added, it can be used as an asset to send and receive. You can find the asset metadata for other assets in the Mainnet Liquid Asset Registry (Testnet).

Rust
// Create the default config
let mut config = LiquidSdk::default_config(
    LiquidNetwork::Mainnet,
    Some("<your-Breez-API-key>".to_string()),
)?;

// Configure asset metadata. Setting the optional fiat ID will enable
// paying fees using the asset (if available).
config.asset_metadata = Some(vec![
    AssetMetadata {
        asset_id: "18729918ab4bca843656f08d4dd877bed6641fbd596a0a963abbf199cfeb3cec".to_string(),
        name: "PEGx EUR".to_string(),
        ticker: "EURx".to_string(),
        precision: 8,
        fiat_id: Some("EUR".to_string()),
    },
]);
Swift
// Create the default config
var config = try defaultConfig(network: LiquidNetwork.mainnet, breezApiKey: "<your-Breez-API-key>")

// Configure asset metadata. Setting the optional fiat ID will enable
// paying fees using the asset (if available).
config.assetMetadata = [
    AssetMetadata(
        assetId: "18729918ab4bca843656f08d4dd877bed6641fbd596a0a963abbf199cfeb3cec",
        name: "PEGx EUR",
        ticker: "EURx",
        precision: 8,
        fiatId: "EUR"
    )
]
Kotlin
// Create the default config
val config : Config = defaultConfig(LiquidNetwork.MAINNET, "<your Breez API key>")

// Configure asset metadata. Setting the optional fiat ID will enable
// paying fees using the asset (if available).
config.assetMetadata = listOf(
    AssetMetadata(
        assetId = "18729918ab4bca843656f08d4dd877bed6641fbd596a0a963abbf199cfeb3cec",
        name = "PEGx EUR",
        ticker = "EURx",
        precision = 8.toUByte(),
        fiatId = "EUR"
    )
)
Javascript
// Create the default config
const config = defaultConfig('mainnet', '<your-Breez-API-key>')

// Configure asset metadata
config.assetMetadata = [
  {
    assetId: '18729918ab4bca843656f08d4dd877bed6641fbd596a0a963abbf199cfeb3cec',
    name: 'PEGx EUR',
    ticker: 'EURx',
    precision: 8
  }
]
React Native
// Create the default config
const config = await defaultConfig(
  LiquidNetwork.MAINNET,
  '<your-Breez-API-key>'
)

// Configure asset metadata. Setting the optional fiat ID will enable
// paying fees using the asset (if available).
config.assetMetadata = [
  {
    assetId: '18729918ab4bca843656f08d4dd877bed6641fbd596a0a963abbf199cfeb3cec',
    name: 'PEGx EUR',
    ticker: 'EURx',
    precision: 8,
    fiatId: 'EUR'
  }
]
Dart
// Create the default config
Config config = defaultConfig(network: LiquidNetwork.mainnet, breezApiKey: "<your-Breez-API-key>");

// Configure asset metadata. Setting the optional fiat ID will enable
// paying fees using the asset (if available).
config = config.copyWith(
  assetMetadata: [
    AssetMetadata(
      assetId: "18729918ab4bca843656f08d4dd877bed6641fbd596a0a963abbf199cfeb3cec",
      name: "PEGx EUR",
      ticker: "EURx",
      precision: 8,
      fiatId: "EUR",
    ),
  ],
);
Python
# Create the default config
config = default_config(
    network=LiquidNetwork.MAINNET,
    breez_api_key="<your-Breez-API-key>"
)

# Configure asset metadata. Setting the optional fiat ID will enable
# paying fees using the asset (if available).
config.asset_metadata = [
    AssetMetadata(
        asset_id="18729918ab4bca843656f08d4dd877bed6641fbd596a0a963abbf199cfeb3cec",
        name="PEGx EUR",
        ticker="EURx",
        precision=8,
        fiat_id="EUR"
    )
]
Go
// Create the default config
breezApiKey := "<your-Breez-API-key>"
config, err := breez_sdk_liquid.DefaultConfig(breez_sdk_liquid.LiquidNetworkMainnet, &breezApiKey)
if err != nil {
    return err
}

// Configure asset metadata. Setting the optional fiat ID will enable
// paying fees using the asset (if available).
fiatId := "EUR"
assetMetadata := []breez_sdk_liquid.AssetMetadata{
    {
        AssetId:   "18729918ab4bca843656f08d4dd877bed6641fbd596a0a963abbf199cfeb3cec",
        Name:      "PEGx EUR",
        Ticker:    "EURx",
        Precision: 8,
        FiatId:    &fiatId,
    },
}
config.AssetMetadata = &assetMetadata
C#
// Create the default config
var config = BreezSdkLiquidMethods.DefaultConfig(
    LiquidNetwork.Mainnet,
    "<your-Breez-API-key>"
) with
{
    // Configure asset metadata. Setting the optional fiat ID will enable
    // paying fees using the asset (if available).
    assetMetadata = new List<AssetMetadata>
    {
        new(
            assetId: "18729918ab4bca843656f08d4dd877bed6641fbd596a0a963abbf199cfeb3cec",
            name: "PEGx EUR",
            ticker: "EURx",
            precision: 8,
            fiatId: "EUR"
        )
    }
};

Default asset metadata

Mainnet

NameTickerAsset IDPrecision
BitcoinBTC6f0279e9ed041c3d710a9f57d0c02928416460c4b722ae3457a11eec381c526d8
Tether USDUSDtce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd28

Testnet

NameTickerAsset IDPrecision
Testnet BitcoinBTC144c654344aa716d6f3abcc1ca90e5641e4e2a7f633bc09fe3baf64585819a498
Testnet Tether USDUSDtb612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d738

Fetching the asset balances API docs

Once connected, the asset balances can be retreived.

Rust
let info = sdk.get_info().await?;
let asset_balances = info.wallet_info.asset_balances;
Swift
if let info = try? sdk.getInfo() {
    let assetBalances = info.walletInfo.assetBalances
    
    print(assetBalances)
}
Kotlin
try {
    val info = sdk.getInfo()
    val assetBalances = info?.walletInfo?.assetBalances
} catch (e: Exception) {
    // handle error
}
Javascript
const info = await sdk.getInfo()
const assetBalances = info.walletInfo.assetBalances
React Native
const info = await getInfo()
const assetBalances = info.walletInfo.assetBalances
Dart
GetInfoResponse? info = await breezSDKLiquid.instance!.getInfo();
List<AssetBalance> assetBalances = info.walletInfo.assetBalances;
Python
try:
    info = sdk.get_info()
    asset_balances = info.wallet_info.asset_balances
except Exception as error:
    logging.error(error)
    raise
Go
if info, err := sdk.GetInfo(); err == nil {
    assetBalances := info.WalletInfo.AssetBalances
    log.Printf("Asset balances: %#v", assetBalances)
}
C#
try
{
    var info = sdk.GetInfo();
    var assetBalances = info?.walletInfo?.assetBalances;
}
catch (Exception)
{
    // Handle error
}

Receiving a non-Bitcoin asset API docs

When receiving an asset via Liquid, we can generate a BIP21 URI with information regarding the payment of a specific asset. The amount to receive is optional and omitting it will result in an amountless BIP21 URI.

In the example below we are using the Mainnet Tether USD asset.

Rust
// Create a Liquid BIP21 URI/address to receive an asset payment to.
// Note: Not setting the amount will generate an amountless BIP21 URI.
let usdt_asset_id = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2".to_string();
let optional_amount = Some(ReceiveAmount::Asset {
    asset_id: usdt_asset_id,
    payer_amount: Some(1.50),
});
let prepare_response = sdk
    .prepare_receive_payment(&PrepareReceiveRequest {
        payment_method: PaymentMethod::LiquidAddress,
        amount: optional_amount,
    })
    .await?;

// If the fees are acceptable, continue to create the Receive Payment
let receive_fees_sat = prepare_response.fees_sat;
info!("Fees: {} sats", receive_fees_sat);
Swift
// Create a Liquid BIP21 URI/address to receive an asset payment to.
// Note: Not setting the amount will generate an amountless BIP21 URI.
let usdtAssetId = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"
let optionalAmount = ReceiveAmount.asset(assetId: usdtAssetId, payerAmount: 1.50)
let prepareResponse = try? sdk
    .prepareReceivePayment(req: PrepareReceiveRequest(
        paymentMethod: PaymentMethod.liquidAddress,
        amount: optionalAmount
    ))

// If the fees are acceptable, continue to create the Receive Payment
let receiveFeesSat = prepareResponse!.feesSat;
print("Fees: {} sats", receiveFeesSat);
Kotlin
try {
    // Create a Liquid BIP21 URI/address to receive an asset payment to.
    // Note: Not setting the amount will generate an amountless BIP21 URI.
    val usdtAssetId = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"
    val optionalAmount = ReceiveAmount.Asset(usdtAssetId, 1.50)
    val prepareRequest = PrepareReceiveRequest(PaymentMethod.LIQUID_ADDRESS, optionalAmount)
    val prepareResponse = sdk.prepareReceivePayment(prepareRequest)

    // If the fees are acceptable, continue to create the Receive Payment
    val receiveFeesSat = prepareResponse.feesSat;
    // Log.v("Breez", "Fees: ${receiveFeesSat} sats")
} catch (e: Exception) {
    // handle error
}
Javascript

// Create a Liquid BIP21 URI/address to receive an asset payment to.
// Note: Not setting the amount will generate an amountless BIP21 URI.
const usdtAssetId = 'ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2'
const optionalAmount: ReceiveAmount = {
  type: 'asset',
  assetId: usdtAssetId,
  payerAmount: 1.5
}

const prepareResponse = await sdk.prepareReceivePayment({
  paymentMethod: 'liquidAddress',
  amount: optionalAmount
})

// If the fees are acceptable, continue to create the Receive Payment
const receiveFeesSat = prepareResponse.feesSat
console.log(`Fees: ${receiveFeesSat} sats`)
React Native

// Create a Liquid BIP21 URI/address to receive an asset payment to.
// Note: Not setting the amount will generate an amountless BIP21 URI.
const usdtAssetId = 'ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2'
const optionalAmount: ReceiveAmount = {
  type: ReceiveAmountVariant.ASSET,
  assetId: usdtAssetId,
  payerAmount: 1.50
}

const prepareResponse = await prepareReceivePayment({
  paymentMethod: PaymentMethod.LIQUID_ADDRESS,
  amount: optionalAmount
})

// If the fees are acceptable, continue to create the Receive Payment
const receiveFeesSat = prepareResponse.feesSat
console.log(`Fees: ${receiveFeesSat} sats`)
Dart
// Create a Liquid BIP21 URI/address to receive an asset payment to.
// Note: Not setting the amount will generate an amountless BIP21 URI.
String usdtAssetId = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2";
ReceiveAmount_Asset optionalAmount = ReceiveAmount_Asset(assetId: usdtAssetId, payerAmount: 1.50);
PrepareReceiveResponse prepareResponse = await breezSDKLiquid.instance!.prepareReceivePayment(
  req: PrepareReceiveRequest(
    paymentMethod: PaymentMethod.liquidAddress,
    amount: optionalAmount,
  ),
);

// If the fees are acceptable, continue to create the Receive Payment
BigInt receiveFeesSat = prepareResponse.feesSat;
print("Fees: $receiveFeesSat sats");
Python
try:
    # Create a Liquid BIP21 URI/address to receive an asset payment to.
    # Note: Not setting the amount will generate an amountless BIP21 URI.
    usdt_asset_id = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"
    optional_amount = ReceiveAmount.ASSET(usdt_asset_id, 1.50)
    prepare_request = PrepareReceiveRequest(
        payment_method=PaymentMethod.LIQUID_ADDRESS,
        amount=optional_amount
    )
    prepare_response = sdk.prepare_receive_payment(prepare_request)

    # If the fees are acceptable, continue to create the Receive Payment
    receive_fees_sat = prepare_response.fees_sat
    logging.debug(f"Fees: {receive_fees_sat} sats")
    return prepare_response
except Exception as error:
    logging.error(error)
    raise
Go
// Create a Liquid BIP21 URI/address to receive an asset payment to.
// Note: Not setting the amount will generate an amountless BIP21 URI.
usdtAssetId := "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"
payerAmount := float64(1.50)
var optionalAmount breez_sdk_liquid.ReceiveAmount = breez_sdk_liquid.ReceiveAmountAsset{
    AssetId:     usdtAssetId,
    PayerAmount: &payerAmount,
}
prepareRequest := breez_sdk_liquid.PrepareReceiveRequest{
    PaymentMethod: breez_sdk_liquid.PaymentMethodLiquidAddress,
    Amount:        &optionalAmount,
}
if prepareResponse, err := sdk.PrepareReceivePayment(prepareRequest); err == nil {
    // If the fees are acceptable, continue to create the Receive Payment
    receiveFeesSat := prepareResponse.FeesSat
    log.Printf("Fees: %v sats", receiveFeesSat)
}
C#
try
{
    // Create a Liquid BIP21 URI/address to receive an asset payment to.
    // Note: Not setting the amount will generate an amountless BIP21 URI.
    var usdtAssetId = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2";
    var optionalAmount = new ReceiveAmount.Asset(usdtAssetId, 1.50);
    var prepareRequest = new PrepareReceiveRequest(PaymentMethod.LiquidAddress, optionalAmount);
    var prepareResponse = sdk.PrepareReceivePayment(prepareRequest);

    // If the fees are acceptable, continue to create the Receive Payment
    var receiveFeesSat = prepareResponse.feesSat;
    Console.WriteLine($"Fees: {receiveFeesSat} sats");
}
catch (Exception)
{
    // Handle error
}

Sending a non-Bitcoin asset API docs

When sending an asset via Liquid, a BIP21 URI or Liquid address can be used as the destination. If a Liquid address is used, the optional prepare request amount must be set. If a BIP21 URI is used, either the BIP21 URI amount or optional prepare request amount must be set. When both amounts are set, the SDK will prioritize the request amount over the BIP21 amount.

In the example below we are using the Mainnet Tether USD asset.

Rust
// Set the Liquid BIP21 or Liquid address you wish to pay
let destination = "<Liquid BIP21 or address>".to_string();
// If the destination is an address or an amountless BIP21 URI,
// you must specify an asset amount
let usdt_asset_id = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2".to_string();
let optional_amount = Some(PayAmount::Asset {
    asset_id: usdt_asset_id,
    receiver_amount: Some(1.50),
    estimate_asset_fees: Some(false),
});
let prepare_response = sdk
    .prepare_send_payment(&PrepareSendRequest {
        destination,
        amount: optional_amount,
    })
    .await?;

// If the fees are acceptable, continue to create the Send Payment
let send_fees_sat = prepare_response.fees_sat;
info!("Fees: {:?} sats", send_fees_sat);
Swift
// Set the Liquid BIP21 or Liquid address you wish to pay
let destination = "<Liquid BIP21 or address>"
// If the destination is an address or an amountless BIP21 URI,
// you must specify an asset amount
let usdtAssetId = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"
let optionalAmount = PayAmount.asset(
    assetId: usdtAssetId,
    receiverAmount: 1.50,
    estimateAssetFees: false
)
let prepareResponse = try? sdk
    .prepareSendPayment(req: PrepareSendRequest (
        destination: destination,
        amount: optionalAmount
    ))

// If the fees are acceptable, continue to create the Send Payment
let sendFeesSat = prepareResponse!.feesSat
print("Fees: {} sats", sendFeesSat);
Kotlin
// Set the Liquid BIP21 or Liquid address you wish to pay
val destination = "<Liquid BIP21 or address>"
try {
    // Create a Liquid BIP21 URI/address to receive an asset payment to.
    // Note: Not setting the amount will generate an amountless BIP21 URI.
    val usdtAssetId = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"
    val optionalAmount = PayAmount.Asset(usdtAssetId, 1.50, false)
    val prepareResponse = sdk.prepareSendPayment(PrepareSendRequest(destination, optionalAmount))

    // If the fees are acceptable, continue to create the Send Payment
    val sendFeesSat = prepareResponse.feesSat;
    // Log.v("Breez", "Fees: ${sendFeesSat} sats")
} catch (e: Exception) {
    // handle error
}
Javascript
// Set the Liquid BIP21 or Liquid address you wish to pay
const destination = '<Liquid BIP21 or address>'
// If the destination is an address or an amountless BIP21 URI,
// you must specify an asset amount

const usdtAssetId = 'ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2'
const optionalAmount: PayAmount = {
  type: 'asset',
  assetId: usdtAssetId,
  receiverAmount: 1.5,
  estimateAssetFees: false
}

const prepareResponse = await sdk.prepareSendPayment({
  destination,
  amount: optionalAmount
})

// If the fees are acceptable, continue to create the Send Payment
const sendFeesSat = prepareResponse.feesSat
console.log(`Fees: ${sendFeesSat} sats`)
React Native
// Set the Liquid BIP21 or Liquid address you wish to pay
const destination = '<Liquid BIP21 or address>'
// If the destination is an address or an amountless BIP21 URI,
// you must specify an asset amount

const usdtAssetId = 'ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2'
const optionalAmount: PayAmount = {
  type: PayAmountVariant.ASSET,
  assetId: usdtAssetId,
  receiverAmount: 1.50,
  estimateAssetFees: false
}

const prepareResponse = await prepareSendPayment({
  destination,
  amount: optionalAmount
})

// If the fees are acceptable, continue to create the Send Payment
const sendFeesSat = prepareResponse.feesSat
console.log(`Fees: ${sendFeesSat} sats`)
Dart
// Set the Liquid BIP21 or Liquid address you wish to pay
String destination = "<Liquid BIP21 or address>";
// If the destination is an address or an amountless BIP21 URI,
// you must specify an asset amount
String usdtAssetId = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2";
PayAmount_Asset optionalAmount = PayAmount_Asset(
  assetId: usdtAssetId,
  receiverAmount: 1.50,
  estimateAssetFees: false,
);
PrepareSendRequest prepareSendRequest = PrepareSendRequest(
  destination: destination,
  amount: optionalAmount,
);

PrepareSendResponse prepareSendResponse = await breezSDKLiquid.instance!.prepareSendPayment(
  req: prepareSendRequest,
);

// If the fees are acceptable, continue to create the Send Payment
BigInt? sendFeesSat = prepareSendResponse.feesSat;
print("Fees: $sendFeesSat sats");
Python
# Set the Liquid BIP21 or Liquid address you wish to pay
destination = "<Liquid BIP21 or address>"
try:
    # If the destination is an address or an amountless BIP21 URI,
    # you must specify an asset amount
    usdt_asset_id = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"
    optional_amount = PayAmount.ASSET(usdt_asset_id, 1.50, False)
    prepare_response = sdk.prepare_send_payment(PrepareSendRequest(destination, optional_amount))

    # If the fees are acceptable, continue to create the Send Payment
    send_fees_sat = prepare_response.fees_sat
    logging.debug(f"Fees: {send_fees_sat} sats")
    return prepare_response
except Exception as error:
    logging.error(error)
    raise
Go
// Set the Liquid BIP21 or Liquid address you wish to pay
destination := "<Liquid BIP21 or address>"
// If the destination is an address or an amountless BIP21 URI,
// you must specify an asset amount
usdtAssetId := "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"
receiverAmount := float64(1.50)
estimateAssetFees := false
var optionalAmount breez_sdk_liquid.PayAmount = breez_sdk_liquid.PayAmountAsset{
    AssetId:           usdtAssetId,
    ReceiverAmount:    receiverAmount,
    EstimateAssetFees: &estimateAssetFees,
}

prepareRequest := breez_sdk_liquid.PrepareSendRequest{
    Destination: destination,
    Amount:      &optionalAmount,
}
prepareResponse, err := sdk.PrepareSendPayment(prepareRequest)
if err != nil {
    log.Printf("Error: %#v", err)
    return
}

sendFeesSat := prepareResponse.FeesSat
log.Printf("Fees: %v sats", sendFeesSat)
C#
// Set the Liquid BIP21 or address you wish to pay
var destination = "<Liquid BIP21 or address>";
try
{
    // If the destination is an address or an amountless BIP21 URI,
    // you must specify an asset amount
    var usdtAssetId = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2";
    var optionalAmount = new PayAmount.Asset(usdtAssetId, 1.50, false);
    var prepareResponse = sdk.PrepareSendPayment(new PrepareSendRequest(destination, optionalAmount));

    // If the fees are acceptable, continue to create the Send Payment
    var sendFeesSat = prepareResponse.feesSat;
    Console.WriteLine($"Fees: {sendFeesSat} sats");
}
catch (Exception)
{
    // Handle error
}

Paying fees with a non-Bitcoin asset API docs

For some assets, like Tether USD, you can pay the sending transaction fees with the asset.

Developer note

When adding additional asset metadata, the optional fiat ID has to be set and the Payjoin provider has to support paying fees for this asset. When the asset is not supported, the asset fees in the prepare send payment response will be not set.

In the prepare send payment step, set the estimate asset fees param to true to validate and calculate the asset fees.

Rust
let destination = "<Liquid BIP21 or address>".to_string();
let usdt_asset_id = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2".to_string();
// Set the optional estimate asset fees param to true
let optional_amount = Some(PayAmount::Asset {
    asset_id: usdt_asset_id,
    receiver_amount: Some(1.50),
    estimate_asset_fees: Some(true),
});
let prepare_response = sdk
    .prepare_send_payment(&PrepareSendRequest {
        destination,
        amount: optional_amount,
    })
    .await?;

// If the asset fees are set, you can use these fees to pay to send the asset
let send_asset_fees = prepare_response.estimated_asset_fees;
info!("Estimated Fees: ~{:?}", send_asset_fees);

// If the asset fess are not set, you can use the sats fees to pay to send the asset
let send_fees_sat = prepare_response.fees_sat;
info!("Fees: {:?} sats", send_fees_sat);
Swift
let destination = "<Liquid BIP21 or address>"
let usdtAssetId = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"
// Set the optional estimate asset fees param to true
let optionalAmount = PayAmount.asset(
    assetId: usdtAssetId,
    receiverAmount: 1.50,
    estimateAssetFees: true
)
let prepareResponse = try? sdk
    .prepareSendPayment(req: PrepareSendRequest (
        destination: destination,
        amount: optionalAmount
    ))

// If the asset fees are set, you can use these fees to pay to send the asset
let sendAssetFees = prepareResponse!.estimatedAssetFees
print("Estimated Fees: ~{}", sendAssetFees);

// If the asset fess are not set, you can use the sats fees to pay to send the asset
let sendFeesSat = prepareResponse!.feesSat
print("Fees: {} sats", sendFeesSat);
Kotlin
val destination = "<Liquid BIP21 or address>"
try {
    val usdtAssetId = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"
    // Set the optional estimate asset fees param to true
    val optionalAmount = PayAmount.Asset(usdtAssetId, 1.50, true)
    val prepareResponse = sdk.prepareSendPayment(PrepareSendRequest(destination, optionalAmount))

    // If the asset fees are set, you can use these fees to pay to send the asset
    val sendAssetFees = prepareResponse.estimatedAssetFees;
    // Log.v("Breez", "Estimated Fees: ~${sendAssetFees}")
    
    // If the asset fess are not set, you can use the sats fees to pay to send the asset
    val sendFeesSat = prepareResponse.feesSat;
    // Log.v("Breez", "Fees: ${sendFeesSat} sats")
} catch (e: Exception) {
    // handle error
}
Javascript
const destination = '<Liquid BIP21 or address>'
const usdtAssetId = 'ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2'
// Set the optional estimate asset fees param to true
const optionalAmount: PayAmount = {
  type: 'asset',
  assetId: usdtAssetId,
  receiverAmount: 1.50,
  estimateAssetFees: true
}

const prepareResponse = await sdk.prepareSendPayment({
  destination,
  amount: optionalAmount
})

// If the asset fees are set, you can use these fees to pay to send the asset
const sendAssetFees = prepareResponse.estimatedAssetFees
console.log(`Estimated Fees: ~${sendAssetFees}`)

// If the asset fess are not set, you can use the sats fees to pay to send the asset
const sendFeesSat = prepareResponse.feesSat
console.log(`Fees: ${sendFeesSat} sats`)
React Native
const destination = '<Liquid BIP21 or address>'
const usdtAssetId = 'ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2'
// Set the optional estimate asset fees param to true
const optionalAmount: PayAmount = {
  type: PayAmountVariant.ASSET,
  assetId: usdtAssetId,
  receiverAmount: 1.50,
  estimateAssetFees: true
}

const prepareResponse = await prepareSendPayment({
  destination,
  amount: optionalAmount
})

// If the asset fees are set, you can use these fees to pay to send the asset
const sendAssetFees = prepareResponse.estimatedAssetFees
console.log(`Estimated Fees: ~${sendAssetFees}`)

// If the asset fess are not set, you can use the sats fees to pay to send the asset
const sendFeesSat = prepareResponse.feesSat
console.log(`Fees: ${sendFeesSat} sats`)
Dart
String destination = "<Liquid BIP21 or address>";
String usdtAssetId = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2";
// Set the optional estimate asset fees param to true
PayAmount_Asset optionalAmount = PayAmount_Asset(
  assetId: usdtAssetId,
  receiverAmount: 1.50,
  estimateAssetFees: true,
);
PrepareSendRequest prepareSendRequest = PrepareSendRequest(
  destination: destination,
  amount: optionalAmount,
);

PrepareSendResponse prepareSendResponse = await breezSDKLiquid.instance!.prepareSendPayment(
  req: prepareSendRequest,
);

// If the asset fees are set, you can use these fees to pay to send the asset
double? sendAssetFees = prepareSendResponse.estimatedAssetFees;
print("Estimated Fees: ~$sendAssetFees");

// If the asset fess are not set, you can use the sats fees to pay to send the asset
BigInt? sendFeesSat = prepareSendResponse.feesSat;
print("Fees: $sendFeesSat sats");
Python
destination = "<Liquid BIP21 or address>"
try:
    usdt_asset_id = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"
    # Set the optional estimate asset fees param to true
    optional_amount = PayAmount.ASSET(usdt_asset_id, 1.50, True)
    prepare_response = sdk.prepare_send_payment(PrepareSendRequest(destination, optional_amount))

    # If the asset fees are set, you can use these fees to pay to send the asset
    send_asset_fees = prepare_response.estimated_asset_fees
    logging.debug(f"Estimated Fees: ~{send_asset_fees}")

    # If the asset fess are not set, you can use the sats fees to pay to send the asset
    send_fees_sat = prepare_response.fees_sat
    logging.debug(f"Fees: {send_fees_sat} sats")
    return prepare_response
except Exception as error:
    logging.error(error)
    raise
Go
destination := "<Liquid BIP21 or address>"
usdtAssetId := "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2"
receiverAmount := float64(1.50)
// Set the optional estimate asset fees param to true
estimateAssetFees := true
var optionalAmount breez_sdk_liquid.PayAmount = breez_sdk_liquid.PayAmountAsset{
    AssetId:           usdtAssetId,
    ReceiverAmount:    receiverAmount,
    EstimateAssetFees: &estimateAssetFees,
}

prepareRequest := breez_sdk_liquid.PrepareSendRequest{
    Destination: destination,
    Amount:      &optionalAmount,
}
prepareResponse, err := sdk.PrepareSendPayment(prepareRequest)
if err != nil {
    log.Printf("Error: %#v", err)
    return
}

// If the asset fees are set, you can use these fees to pay to send the asset
sendAssetFees := prepareResponse.EstimatedAssetFees
log.Printf("Estimated Fees: ~%v", sendAssetFees)

// If the asset fess are not set, you can use the sats fees to pay to send the asset
sendFeesSat := prepareResponse.FeesSat
log.Printf("Fees: %v sats", sendFeesSat)
C#
var destination = "<Liquid BIP21 or address>";
try
{
    var usdtAssetId = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2";
    // Set the optional estimate asset fees param to true
    var optionalAmount = new PayAmount.Asset(usdtAssetId, 1.50, true);
    var prepareResponse = sdk.PrepareSendPayment(new PrepareSendRequest(destination, optionalAmount));

    // If the asset fees are set, you can use these fees to pay to send the asset
    var sendAssetFees = prepareResponse.estimatedAssetFees;
    Console.WriteLine($"Estimated Fees: ~{sendAssetFees}");

    // If the asset fess are not set, you can use the sats fees to pay to send the asset
    var sendFeesSat = prepareResponse.feesSat;
    Console.WriteLine($"Fees: {sendFeesSat} sats");
}
catch (Exception)
{
    // Handle error
}

If the asset fees are set in the response, then set the use asset fees to true to pay fees with the asset. You can still pay fees in satoshi if you set the use asset fees to false (default).

Rust
// Set the use asset fees param to true
let send_response = sdk
    .send_payment(&SendPaymentRequest {
        prepare_response,
        use_asset_fees: Some(true),
    })
    .await?;
let payment = send_response.payment;
Swift
// Set the use asset fees param to true
let sendResponse = try? sdk.sendPayment(req: SendPaymentRequest (
    prepareResponse: prepareResponse,
    useAssetFees: true
))
let payment = sendResponse!.payment
Kotlin
try {
    // Set the use asset fees param to true
    val sendResponse = sdk.sendPayment(SendPaymentRequest(prepareResponse, true))
    val payment = sendResponse.payment
} catch (e: Exception) {
    // handle error
}
Javascript
// Set the use asset fees param to true
const sendResponse = await sdk.sendPayment({
  prepareResponse,
  useAssetFees: true
})
const payment = sendResponse.payment
React Native
// Set the use asset fees param to true
const sendResponse = await sendPayment({
  prepareResponse,
  useAssetFees: true
})
const payment = sendResponse.payment
Dart
// Set the use asset fees param to true
SendPaymentResponse sendPaymentResponse = await breezSDKLiquid.instance!.sendPayment(
  req: SendPaymentRequest(prepareResponse: prepareResponse, useAssetFees: true),
);
Payment payment = sendPaymentResponse.payment;
Python
try:
    # Set the use asset fees param to true
    send_response = sdk.send_payment(SendPaymentRequest(prepare_response, True))
    payment = send_response.payment
except Exception as error:
    logging.error(error)
    raise
Go
// Set the use asset fees param to true
useAssetFees := true
req := breez_sdk_liquid.SendPaymentRequest{
    PrepareResponse: prepareResponse,
    UseAssetFees:    &useAssetFees,
}
if response, err := sdk.SendPayment(req); err == nil {
    payment := response.Payment
    log.Printf("Payment: %#v", payment)
}
C#
try
{
    // Set the use asset fees param to true
    var sendRequest = new SendPaymentRequest(prepareResponse, true);
    var sendResponse = sdk.SendPayment(sendRequest);
    var payment = sendResponse.payment;
}
catch (Exception)
{
    // Handle error
}