Sending an on-chain transaction (Swap-Out)
You can send funds from the Breez SDK wallet to an on-chain address as follows.
Developer note
Consider implementing the Notification Plugin when using the Breez SDK in a mobile application. By registering a webhook the application can receive notifications to process the payment in the background.Preparing Payments
When sending an onchain payment, the swap limits for sending onchain need to be first checked.
let current_limits = sdk.fetch_onchain_limits().await?;
info!("Minimum amount: {} sats", current_limits.send.min_sat);
info!("Maximum amount: {} sats", current_limits.send.max_sat);
let currentLimits = try? sdk.fetchOnchainLimits()
if let limits = currentLimits {
print("Minimum amount, in sats: \(limits.send.minSat)")
print("Maximum amount, in sats: \(limits.send.maxSat)")
}
try {
val currentLimits = sdk.fetchOnchainLimits()
// Log.v("Breez", "Minimum amount, in sats: ${currentLimits.send.minSat}")
// Log.v("Breez", "Maximum amount, in sats: ${currentLimits.send.maxSat}")
} catch (e: Exception) {
// handle error
}
try {
const currentLimits = await fetchOnchainLimits()
console.log(`Minimum amount, in sats: ${currentLimits.send.minSat}`)
console.log(`Maximum amount, in sats: ${currentLimits.send.maxSat}`)
} catch (err) {
console.error(err)
}
OnchainPaymentLimitsResponse currentLimits = await breezSDKLiquid.instance!.fetchOnchainLimits();
print("Minimum amount: ${currentLimits.send.minSat} sats");
print("Maximum amount: ${currentLimits.send.maxSat} sats");
try:
current_limits = sdk.fetch_onchain_limits()
logging.debug("Minimum amount, in sats ", current_limits.send.min_sat)
logging.debug("Maximum amount, in sats ", current_limits.send.max_sat)
return current_limits
except Exception as error:
logging.error(error)
raise
if currentLimits, err := sdk.FetchOnchainLimits(); err == nil {
log.Printf("Minimum amount, in sats: %v", currentLimits.Send.MinSat)
log.Printf("Maximum amount, in sats: %v", currentLimits.Send.MaxSat)
}
try
{
var currentLimits = sdk.FetchOnchainLimits();
Console.WriteLine($"Minimum amount, in sats: {currentLimits.send.minSat}");
Console.WriteLine($"Maximum amount, in sats: {currentLimits.send.maxSat}");
}
catch (Exception)
{
// Handle error
}
This represents the range of valid amounts that can be sent at this point in time. The range may change depending on the swap service parameters or mempool feerate fluctuations.
Developer note
It is best to fetch these limits just before your app shows the Pay Onchain (reverse swap) UI. You can then use these limits to validate the user input.
Setting the receiver amount
When you want the payment receipient to receive a specific amount.
let prepare_res = sdk
.prepare_pay_onchain(&PreparePayOnchainRequest {
amount: PayOnchainAmount.Receiver {
amount_sat: 5_000,
},
fee_rate_sat_per_vbyte: None,
})
.await?;
// Check if the fees are acceptable before proceeding
let total_fees_sat = prepare_res.total_fees_sat;
let amount = PayOnchainAmount.receiver(amountSat: 5_000)
let prepareRequest = PreparePayOnchainRequest(amount: amount)
let prepareResponse = try? sdk.preparePayOnchain(req: prepareRequest)
if let response = prepareResponse {
// Check if the fees are acceptable before proceeding
print("Payer fees, in sats: \(response.totalFeesSat)")
}
try {
val amount = PayOnchainAmount.Receiver(5_000.toULong())
val prepareRequest = PreparePayOnchainRequest(amount)
val prepareResponse = sdk.preparePayOnchain(prepareRequest)
// Check if the fees are acceptable before proceeding
val totalFeesSat = prepareResponse.totalFeesSat;
} catch (e: Exception) {
// handle error
}
try {
const prepareResponse = await preparePayOnchain({
amount: {
type: PayOnchainAmountVariant.RECEIVER,
amountSat: 5_000
}
})
// Check if the fees are acceptable before proceeding
const totalFeesSat = prepareResponse.totalFeesSat
} catch (err) {
console.error(err)
}
PreparePayOnchainRequest preparePayOnchainRequest = PreparePayOnchainRequest(
amount: PayOnchainAmount_Receiver(amountSat: 5000 as BigInt),
);
PreparePayOnchainResponse prepareRes = await breezSDKLiquid.instance!.preparePayOnchain(
req: preparePayOnchainRequest,
);
// Check if the fees are acceptable before proceeding
BigInt totalFeesSat = prepareRes.totalFeesSat;
try:
amount = PayOnchainAmount.RECEIVER(5_000)
prepare_request = PreparePayOnchainRequest(amount)
prepare_response = sdk.prepare_pay_onchain(prepare_request)
# Check if the fees are acceptable before proceeding
total_fees_sat = prepare_response.total_fees_sat
except Exception as error:
logging.error(error)
raise
amount := breez_sdk_liquid.PayOnchainAmountReceiver{AmountSat: 5_000}
prepareRequest := breez_sdk_liquid.PreparePayOnchainRequest{
Amount: amount,
}
if prepareResponse, err := sdk.PreparePayOnchain(prepareRequest); err == nil {
// Check if the fees are acceptable before proceeding
totalFeesSat := prepareResponse.TotalFeesSat
log.Printf("Fees: %v sats", totalFeesSat)
}
try
{
var amount = new PayOnchainAmount.Receiver(5000);
var prepareRequest = new PreparePayOnchainRequest(amount);
var prepareResponse = sdk.PreparePayOnchain(prepareRequest);
// Check if the fees are acceptable before proceeding
var totalFeesSat = prepareResponse.totalFeesSat;
}
catch (Exception)
{
// Handle error
}
If you want to set a custom fee rate when the Bitcoin transaction is claimed:
let optional_sat_per_vbyte = Some(21);
let prepare_res = sdk
.prepare_pay_onchain(&PreparePayOnchainRequest {
amount: PayOnchainAmount.Receiver {
amount_sat: 5_000,
},
fee_rate_sat_per_vbyte: optional_sat_per_vbyte,
})
.await?;
// Check if the fees are acceptable before proceeding
let claim_fees_sat = prepare_res.claim_fees_sat;
let total_fees_sat = prepare_res.total_fees_sat;
let amount = PayOnchainAmount.receiver(amountSat: 5_000)
let optionalSatPerVbyte = UInt32(21)
let prepareRequest = PreparePayOnchainRequest(amount: amount, feeRateSatPerVbyte: optionalSatPerVbyte)
let prepareResponse = try? sdk.preparePayOnchain(req: prepareRequest)
if let response = prepareResponse {
// Check if the fees are acceptable before proceeding
print("Payer claim fees, in sats: \(response.claimFeesSat)")
print("Payer total fees, in sats: \(response.totalFeesSat)")
}
try {
val amount = PayOnchainAmount.Receiver(5_000.toULong())
val optionalSatPerVbyte = 21
val prepareRequest = PreparePayOnchainRequest(amount, optionalSatPerVbyte.toUInt())
val prepareResponse = sdk.preparePayOnchain(prepareRequest)
// Check if the fees are acceptable before proceeding
val claimFeesSat = prepareResponse.claimFeesSat;
val totalFeesSat = prepareResponse.totalFeesSat;
} catch (e: Exception) {
// handle error
}
try {
const optionalSatPerVbyte = 21
const prepareResponse = await preparePayOnchain({
amount: {
type: PayOnchainAmountVariant.RECEIVER,
amountSat: 5_000
},
feeRateSatPerVbyte: optionalSatPerVbyte
})
// Check if the fees are acceptable before proceeding
const claimFeesSat = prepareResponse.claimFeesSat
const totalFeesSat = prepareResponse.totalFeesSat
} catch (err) {
console.error(err)
}
int optionalSatPerVbyte = 21;
PreparePayOnchainRequest preparePayOnchainRequest = PreparePayOnchainRequest(
amount: PayOnchainAmount_Receiver(amountSat: 5000 as BigInt),
feeRateSatPerVbyte: optionalSatPerVbyte,
);
PreparePayOnchainResponse prepareRes = await breezSDKLiquid.instance!.preparePayOnchain(
req: preparePayOnchainRequest,
);
// Check if the fees are acceptable before proceeding
BigInt claimFeesSat = prepareRes.claimFeesSat;
BigInt totalFeesSat = prepareRes.totalFeesSat;
try:
amount = PayOnchainAmount.RECEIVER(5_000)
optional_sat_per_vbyte = 21
prepare_request = PreparePayOnchainRequest(amount, optional_sat_per_vbyte)
prepare_response = sdk.prepare_pay_onchain(prepare_request)
# Check if the fees are acceptable before proceeding
claim_fees_sat = prepare_response.claim_fees_sat
total_fees_sat = prepare_response.total_fees_sat
except Exception as error:
logging.error(error)
raise
amount := breez_sdk_liquid.PayOnchainAmountReceiver{AmountSat: 5_000}
optionalSatPerVbyte := uint32(21)
prepareRequest := breez_sdk_liquid.PreparePayOnchainRequest{
Amount: amount,
FeeRateSatPerVbyte: &optionalSatPerVbyte,
}
if prepareResponse, err := sdk.PreparePayOnchain(prepareRequest); err == nil {
// Check if the fees are acceptable before proceeding
claimFeesSat := prepareResponse.ClaimFeesSat
totalFeesSat := prepareResponse.TotalFeesSat
log.Printf("Claim fees: %v sats, total fees: %v sats", claimFeesSat, totalFeesSat)
}
try
{
var amount = new PayOnchainAmount.Receiver(5000);
uint optionalSatPerVbyte = 21;
var prepareRequest = new PreparePayOnchainRequest(amount, optionalSatPerVbyte);
var prepareResponse = sdk.PreparePayOnchain(prepareRequest);
// Check if the fees are acceptable before proceeding
var claimFeesSat = prepareResponse.claimFeesSat;
var totalFeesSat = prepareResponse.totalFeesSat;
}
catch (Exception)
{
// Handle error
}
Draining all funds
When you want send all funds from your wallet to another address.
let prepare_res = sdk
.prepare_pay_onchain(&PreparePayOnchainRequest {
amount: PayOnchainAmount.Drain,
fee_rate_sat_per_vbyte: None,
})
.await?;
// Check if the fees are acceptable before proceeding
let total_fees_sat = prepare_res.total_fees_sat;
let amount = PayOnchainAmount.drain
let prepareRequest = PreparePayOnchainRequest(amount: amount)
let prepareResponse = try? sdk.preparePayOnchain(req: prepareRequest)
if let response = prepareResponse {
// Check if the fees are acceptable before proceeding
print("Payer fees, in sats: \(response.totalFeesSat)")
}
try {
val amount = PayOnchainAmount.Drain
val prepareRequest = PreparePayOnchainRequest(amount)
val prepareResponse = sdk.preparePayOnchain(prepareRequest)
// Check if the fees are acceptable before proceeding
val totalFeesSat = prepareResponse.totalFeesSat;
} catch (e: Exception) {
// handle error
}
try {
const prepareResponse = await preparePayOnchain({
amount: {
type: PayOnchainAmountVariant.DRAIN
}
})
// Check if the fees are acceptable before proceeding
const totalFeesSat = prepareResponse.totalFeesSat
} catch (err) {
console.error(err)
}
PreparePayOnchainRequest preparePayOnchainRequest = PreparePayOnchainRequest(
amount: PayOnchainAmount_Drain(),
);
PreparePayOnchainResponse prepareRes = await breezSDKLiquid.instance!.preparePayOnchain(
req: preparePayOnchainRequest,
);
// Check if the fees are acceptable before proceeding
BigInt totalFeesSat = prepareRes.totalFeesSat;
try:
amount = PayOnchainAmount.DRAIN
prepare_request = PreparePayOnchainRequest(amount)
prepare_response = sdk.prepare_pay_onchain(prepare_request)
# Check if the fees are acceptable before proceeding
total_fees_sat = prepare_response.total_fees_sat
except Exception as error:
logging.error(error)
raise
amount := breez_sdk_liquid.PayOnchainAmountDrain{}
prepareRequest := breez_sdk_liquid.PreparePayOnchainRequest{
Amount: amount,
}
if prepareResponse, err := sdk.PreparePayOnchain(prepareRequest); err == nil {
// Check if the fees are acceptable before proceeding
totalFeesSat := prepareResponse.TotalFeesSat
log.Printf("Fees: %v sats", totalFeesSat)
}
try
{
var amount = new PayOnchainAmount.Drain();
var prepareRequest = new PreparePayOnchainRequest(amount);
var prepareResponse = sdk.PreparePayOnchain(prepareRequest);
// Check if the fees are acceptable before proceeding
var totalFeesSat = prepareResponse.totalFeesSat;
}
catch (Exception)
{
// Handle error
}
Sending Payments
Once you checked the amounts and the fees are acceptable, you can continue with sending the payment.
Note that one of the arguments will be the result from the prepare
call above.
let destination_address = String::from("bc1..");
sdk.pay_onchain(&PayOnchainRequest {
address: destination_address,
prepare_response,
})
.await?;
let destinationAddress = "bc1.."
let response = try? sdk.payOnchain(req: PayOnchainRequest(
address: destinationAddress,
prepareResponse: prepareResponse))
val address = "bc1.."
try {
sdk.payOnchain(PayOnchainRequest(address, prepareResponse))
} catch (e: Exception) {
// handle error
}
try {
const destinationAddress = 'bc1..'
const payOnchainRes = await payOnchain({
address: destinationAddress,
prepareResponse
})
} catch (err) {
console.error(err)
}
String destinationAddress = "bc1..";
PayOnchainRequest req = PayOnchainRequest(
address: destinationAddress,
prepareResponse: prepareRes,
);
SendPaymentResponse res = await breezSDKLiquid.instance!.payOnchain(req: req);
address = "bc1.."
try:
sdk.pay_onchain(PayOnchainRequest(address, prepare_response))
except Exception as error:
logging.error(error)
raise
address := "bc1.."
payOnchainRequest := breez_sdk_liquid.PayOnchainRequest{
Address: address,
PrepareResponse: prepareResponse,
}
if reverseSwapInfo, err := sdk.PayOnchain(payOnchainRequest); err == nil {
log.Printf("%#v", reverseSwapInfo)
}
var address = "bc1..";
try
{
var reverseSwapInfo = sdk.PayOnchain(
new PayOnchainRequest(address, prepareResponse));
}
catch (Exception)
{
// Handle error
}