Refunding payments

The SDK handles refunding of failed payments automatically except when receiving Bitcoin payments where the refund of a failed swap has to be managed manually.

Bitcoin

In order to manually execute a Bitcoin refund, you need to supply an on-chain Bitcoin address to which the refunded amount will be sent. The following code will retrieve the refundable swaps:

Rust
let refundables = sdk.list_refundables().await?;
Swift
let refundables = try? sdk.listRefundables()
Kotlin
try {
    val refundables = sdk.listRefundables()
} catch (e: Exception) {
    // handle error
}
React Native
try {
  const refundables = await listRefundables()
} catch (err) {
  console.error(err)
}
Dart
List<RefundableSwap> refundables = await breezSDKLiquid.instance!.listRefundables();
Python
try:
    refundables = sdk.list_refundables()
    return refundables
except Exception as error:
    logging.error(error)
    raise
Go
if refundables, err := sdk.ListRefundables(); err == nil {
    log.Printf("%#v", refundables)
}
C#
try
{
    var refundables = sdk.ListRefundables();
}
catch (Exception)
{
    // Handle error
}

To refund a swap, you need to set a fee rate for the Bitcoin transaction. You can get the Bitcoin mempool fee estimates from the SDK:

Rust
let fees = sdk.recommended_fees().await?;
Swift
let fees = try? sdk.recommendedFees()
Kotlin
try {
    val fees = sdk.recommendedFees()
} catch (e: Exception) {
    // handle error
}
React Native
try {
  const fees = await recommendedFees()
} catch (err) {
  console.error(err)
}
Dart
RecommendedFees fees = await breezSDKLiquid.instance!.recommendedFees();
Python
try:
    fees = sdk.recommended_fees()
except Exception as error:
    logging.error(error)
    raise
Go
if fees, err := sdk.RecommendedFees(); err == nil {
    log.Printf("%v", fees)
}
C#
try
{
    var fees = sdk.RecommendedFees();
}
catch (Exception)
{
    // Handle error
}

Once you have a refundable swap, use the following code to execute a refund:

Rust
let destination_address = "...".into();
let fee_rate_sat_per_vbyte = refund_tx_fee_rate;

sdk.refund(&RefundRequest {
    swap_address: refundable.swap_address,
    refund_address: destination_address,
    fee_rate_sat_per_vbyte,
})
.await?;
Swift
let destinationAddress = "..."
let feeRateSatPerVbyte = refundTxFeeRate
let response = try? sdk.refund(req: RefundRequest(
    swapAddress: refundable.swapAddress,
    refundAddress: destinationAddress,
    feeRateSatPerVbyte: feeRateSatPerVbyte))
Kotlin
val destinationAddress = "..."
val feeRateSatPerVbyte = refundTxFeeRate
try {
    sdk.refund(RefundRequest(refundable.swapAddress, destinationAddress, feeRateSatPerVbyte))
} catch (e: Exception) {
    // handle error
}
React Native
const destinationAddress = '...'
const feeRateSatPerVbyte = refundTxFeeRate

const refundResponse = await refund({
  swapAddress: refundable.swapAddress,
  refundAddress: destinationAddress,
  feeRateSatPerVbyte
})
Dart
String destinationAddress = "...";
int feeRateSatPerVbyte = refundTxFeeRate;

RefundRequest req = RefundRequest(
  swapAddress: refundable.swapAddress,
  refundAddress: destinationAddress,
  feeRateSatPerVbyte: feeRateSatPerVbyte,
);
RefundResponse resp = await breezSDKLiquid.instance!.refund(req: req);
print(resp.refundTxId);
Python
destination_address = "..."
fee_rate_sat_per_vbyte = refund_tx_fee_rate
try:
    sdk.refund(RefundRequest(refundable.swap_address, destination_address, fee_rate_sat_per_vbyte))
except Exception as error:
    logging.error(error)
    raise
Go
destinationAddress := "..."
feeRateSatPerVbyte := refundTxFeeRate
refundRequest := breez_sdk_liquid.RefundRequest{
    SwapAddress:        refundable.SwapAddress,
    RefundAddress:      destinationAddress,
    FeeRateSatPerVbyte: feeRateSatPerVbyte,
}

if result, err := sdk.Refund(refundRequest); err == nil {
    log.Printf("%v", result)
}
C#
var destinationAddress = "...";
var feeRateSatPerVbyte = refundTxFeeRate;
try
{
    sdk.Refund(
        new RefundRequest(
            refundable.swapAddress, 
            destinationAddress, 
            feeRateSatPerVbyte));
}
catch (Exception)
{
    // Handle error
}

Developer note

A refund can be attempted several times. A common scenario where this is useful is if the initial refund transaction takes too long to mine, your application's users can be offered the ability to re-trigger the refund with a higher feerate.