Sending an on-chain transaction (Swap-Out)
You can send funds from the Breez SDK wallet to an on-chain address as follows.
Setting the fee
First, fetch the current reverse swap fees:
let current_fees = sdk
.fetch_reverse_swap_fees(ReverseSwapFeesRequest {
send_amount_sat: Some(50_000),
claim_tx_feerate: None,
})
.await?;
info!(
"Total estimated fees for reverse swap: {:?}",
current_fees.total_fees
);
let sendAmountSat: UInt64 = 50_000
let currentFees = try? sdk.fetchReverseSwapFees(req: ReverseSwapFeesRequest(sendAmountSat: sendAmountSat))
print("Total estimated fees for reverse swap: \(String(describing: currentFees?.totalFees))")
try {
val fees = sdk.fetchReverseSwapFees(ReverseSwapFeesRequest(50_000_u))
// Log.v("Breez", "Total estimated fees for reverse swap: ${fees.totalFees}")
} catch (e: Exception) {
// handle error
}
try {
const currentFees = await fetchReverseSwapFees({ sendAmountSat: 50000 })
console.log(
`Total estimated fees for reverse swap: ${currentFees.totalFees}`
)
} catch (err) {
console.error(err)
}
ReverseSwapFeesRequest req = const ReverseSwapFeesRequest(sendAmountSat: 50000);
ReverseSwapPairInfo currentFees = await BreezSDK().fetchReverseSwapFees(req: req);
print("Total estimated fees for reverse swap: ${currentFees.totalFees}");
req = breez_sdk.ReverseSwapFeesRequest(send_amount_sat=50000)
current_fees = sdk_services.fetch_reverse_swap_fees(req)
print("Total estimated fees for reverse swap: ", current_fees.total_fees)
sendAmountSat := uint64(50_000)
reverseSwapFeesRequest := breez_sdk.ReverseSwapFeesRequest{
SendAmountSat: &sendAmountSat,
}
if currentFees, err := sdk.FetchReverseSwapFees(reverseSwapFeesRequest); err == nil {
log.Printf("Total estimated fees for reverse swap: %v", currentFees.TotalFees)
}
try
{
var currentFees = sdk.FetchReverseSwapFees(
new ReverseSwapFeesRequest(50000));
Console.WriteLine(
$"Total estimated fees for reverse " +
$"swap: {currentFees.totalFees}");
}
catch (Exception)
{
// Handle error
}
Developer note
The reverse swap will involve two on-chain transactions, for which the mining fees can only be estimated. They will happen automatically once the process is started, but the last two values above are these estimates to help you get a picture of the total costs.
Fetching the fees also tells you what is the range of amounts the service allows:
info!("Minimum amount, in sats: {}", current_fees.min);
info!("Maximum amount, in sats: {}", current_fees.max);
print("Minimum amount, in sats: \(currentFees.min)")
print("Maximum amount, in sats: \(currentFees.max)")
// Log.v("Breez", "Minimum amount, in sats: ${fees.min}")
// Log.v("Breez", "Maximum amount, in sats: ${fees.max}")
console.log(`Minimum amount, in sats: ${currentFees.min}`)
console.log(`Maximum amount, in sats: ${currentFees.max}`)
print("Minimum amount, in sats: ${currentFees.min}");
print("Maximum amount, in sats: ${currentFees.max}");
print("Minimum amount, in sats: ", current_fees.min)
print("Maximum amount, in sats: ", current_fees.max)
log.Printf("Minimum amount, in sats: %v", currentFees.Min)
log.Printf("Maximum amount, in sats: %v", currentFees.Max)
Console.WriteLine($"Minimum amount, in sats: {currentFees.min}");
Console.WriteLine($"Maximum amount, in sats: {currentFees.max}");
Sending all funds
In case you want to drain your channels you need to know the maximum sendable amount to an on-chain address:
let max_amount = sdk.max_reverse_swap_amount().await?;
info!("Max reverse swap amount: {:?}", max_amount.total_sat);
let maxAmount = try? sdk.maxReverseSwapAmount()
print("Max reverse swap amount: \(String(describing: maxAmount?.totalSat))")
try {
val maxAmount = sdk.maxReverseSwapAmount()
// Log.v("Breez", "Max reverse swap amount: ${maxAmount.totalSat}")
} catch (e: Exception) {
// handle error
}
try {
const maxAmount = await maxReverseSwapAmount()
console.log(
`Max reverse swap amount: ${maxAmount.totalSat}`
)
} catch (err) {
console.error(err)
}
MaxReverseSwapAmountResponse maxAmount = await BreezSDK().maxReverseSwapAmount();
print("Max reverse swap amount: ${maxAmount.totalSat}");
max_amount = sdk_services.max_reverse_swap_amount()
print("Max reverse swap amount: ", max_amount.totalSat)
if maxAmount, err := sdk.MaxReverseSwapAmount(); err == nil {
log.Printf("Max reverse swap amount: %v", maxAmount.TotalSat)
}
try
{
var maxAmountResponse = sdk.MaxReverseSwapAmount();
Console.WriteLine(
$"Max reverse swap amount {maxAmountResponse.totalSat}");
}
catch (Exception)
{
// Handle error
}
Executing the Swap
Once you decided about the amount and checked the fees are acceptable, you can start the reverse swap:
let destination_address = String::from("bc1..");
let amount_sat = current_fees.min;
let sat_per_vbyte = fee_rate;
sdk.send_onchain(SendOnchainRequest {
pair_hash: current_fees.fees_hash,
amount_sat,
sat_per_vbyte,
onchain_recipient_address: destination_address,
})
.await?;
let destinationAddress = "bc1.."
let amountSat = currentFees.min
let satPerVbyte: UInt32 = 5
let response = try? sdk.sendOnchain(req: SendOnchainRequest(amountSat: amountSat, onchainRecipientAddress: destinationAddress, pairHash: currentFees.feesHash, satPerVbyte: satPerVbyte))
val address = "bc1.."
val amountSat = 123.toULong()
val satPerVbyte = 1.toUInt()
try {
sdk.sendOnchain(SendOnchainRequest(amountSat, address, fees.feesHash, satPerVbyte))
} catch (e: Exception) {
// handle error
}
try {
const onchainRecipientAddress = 'bc1..'
const amountSat = currentFees.min
const satPerVbyte = 5
const reverseSwapInfo = await sendOnchain({
amountSat,
onchainRecipientAddress,
pairHash: currentFees.feesHash,
satPerVbyte
})
} catch (err) {
console.error(err)
}
SendOnchainRequest req = SendOnchainRequest(
amountSat: amountSat,
onchainRecipientAddress: onchainRecipientAddress,
pairHash: pairHash,
satPerVbyte: satPerVbyte,
);
SendOnchainResponse resp = await BreezSDK().sendOnchain(req: req);
destination_address = "bc1.."
amount_sat = 50000
sat_per_vbyte = fee_rate
try:
req = breez_sdk.SendOnchainRequest(amount_sat, destination_address, current_fees.fees_hash, sat_per_vbyte)
sdk_services.send_onchain(req)
destinationAddress := "bc1.."
sendAmountSat := uint64(50_000)
satPerVbyte := uint32(5)
if currentFees, err := sdk.FetchReverseSwapFees(breez_sdk.ReverseSwapFeesRequest{SendAmountSat: &sendAmountSat}); err == nil {
sendOnchainRequest := breez_sdk.SendOnchainRequest{
AmountSat: sendAmountSat,
OnchainRecipientAddress: destinationAddress,
PairHash: currentFees.FeesHash,
SatPerVbyte: satPerVbyte,
}
if reverseSwapInfo, err := sdk.SendOnchain(sendOnchainRequest); err == nil {
log.Printf("%#v", reverseSwapInfo)
}
}
var destinationAddress = "bc1..";
var amountSat = currentFees.min;
var satPerVbyte = feeRate;
try
{
var reverseSwapInfo = sdk.SendOnchain(
new SendOnchainRequest(
amountSat,
destinationAddress,
currentFees.feesHash,
satPerVbyte));
}
catch (Exception)
{
// Handle error
}
Starting the reverse swap will trigger a HODL invoice payment, which will only be settled if the entire swap completes. This means you will see an outgoing pending payment in your list of payments, which locks those funds until the invoice is either settled or cancelled. This will happen automatically at the end of the reverse swap.
List in-progress Swaps
You can check its status with:
for rs in sdk.in_progress_reverse_swaps().await? {
info!(
"Reverse swap {} in progress, status is {:?}",
rs.id, rs.status
);
}
if let inProgressReverseSwaps = try? sdk.inProgressReverseSwaps() {
for rs in inProgressReverseSwaps {
print("Reverse swap \(rs.id) in progress, status is \(rs.status)")
}
}
for (rs in sdk.inProgressReverseSwaps()) {
// Log.v("Breez", "Reverse swap ${rs.id} in progress, status is ${rs.status}")
}
try {
const swaps = await inProgressReverseSwaps()
for (const swap of swaps) {
console.log(
`Reverse swap ${swap.id} in progress, status is ${swap.status}`
)
}
} catch (err) {
console.error(err)
}
List<ReverseSwapInfo> inProgRevSwapList = await BreezSDK().inProgressReverseSwaps();
for (var inProgRevSwap in inProgRevSwapList) {
print("Reverse swap ${inProgRevSwap.id} in progress, status is ${inProgRevSwap.status.name}");
}
reverse_swaps = sdk_services.in_progress_reverse_swaps()
for rs in reverse_swaps:
print("Reverse swap ",rs.id , " in progress, status is ", rs.status)
if swaps, err := sdk.InProgressReverseSwaps(); err == nil {
for _, swap := range swaps {
log.Printf("Reverse swap %v in progress, status is %v", swap.Id, swap.Status)
}
}
try
{
var swaps = sdk.InProgressReverseSwaps();
foreach (var swap in swaps)
{
Console.WriteLine(
$"Reverse swap {swap.id} in progress, " +
$"status is {swap.status}`");
}
}
catch (Exception)
{
// Handle error
}
If the reverse swap is successful, you'll get the on-chain payment on your destination address and the HODL invoice will change from pending to settled.
If however something goes wrong at any point in the process, the initial HODL payment will be cancelled and the funds in your Breez SDK wallet will be unlocked.