From 43217f327e5d7ca1a06e88d413eb8ef849e8f354 Mon Sep 17 00:00:00 2001 From: Danny Morabito Date: Wed, 9 Jul 2025 13:27:37 +0200 Subject: [PATCH] add refund functionality --- index.ts | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/index.ts b/index.ts index 20fd4f6..12dae2f 100644 --- a/index.ts +++ b/index.ts @@ -435,4 +435,64 @@ export default class PortalBtcWallet { listener(); } } + + /** + * Refunds a payment + * + * @param payment - The payment to refund + */ + async refundPayment(payment: Payment) { + if (!this.breezSDK) throw new Error("Breez SDK not initialized"); + const prepareAddr = await this.breezSDK.prepareReceivePayment({ + paymentMethod: "bitcoinAddress", + }); + const receiveRes = await this.breezSDK.receivePayment({ + prepareResponse: prepareAddr, + }); + const refundAddress = receiveRes.destination as string; + + try { + const refundables = await this.breezSDK.listRefundables(); + let swapAddress: string | undefined; + if (refundables.length === 1) { + swapAddress = refundables[0]?.swapAddress; + } else { + swapAddress = refundables.find( + (r) => + r.amountSat === payment.amountSat && + Math.abs(r.timestamp - payment.timestamp) < 300, + )?.swapAddress; + } + + if (!swapAddress) { + throw new Error("Could not identify refundable swap for this payment."); + } + + const fees = await this.breezSDK.recommendedFees(); + const feeRateSatPerVbyte = fees.economyFee; + + const refundRequest = { + swapAddress, + refundAddress, + feeRateSatPerVbyte, + } as const; + + try { + await this.breezSDK.prepareRefund(refundRequest); + } catch (err) { + console.warn( + "prepareRefund failed (may be expected for some swaps)", + err, + ); + return; + } + + await this.breezSDK.refund(refundRequest); + } catch (err) { + console.error("Refund failed", err); + throw new Error( + `Refund failed: ${err instanceof Error ? err.message : err}`, + ); + } + } }