feat: add comment support for Lightning payments in BTCPay and Strike services

- Enhanced the sendPaymentWithAddress method in BTCPayService and StrikeService to accept an optional comment parameter.
- Updated resolveLightningAddress to include the comment in the callback URL if supported by the LNURL-pay endpoint.
- Modified PaymentService to construct a descriptive comment for Lightning invoices, improving clarity for users.

These changes enhance the payment experience by allowing users to include contextual information with their transactions.
This commit is contained in:
Dorian
2026-02-14 13:02:42 +00:00
parent e774d20821
commit 11d289d793
8 changed files with 135 additions and 35 deletions

View File

@@ -345,12 +345,13 @@ export class BTCPayService implements LightningService {
async sendPaymentWithAddress(
address: string,
payment: Payment,
comment?: string,
): Promise<LightningPaymentDTO> {
try {
const sats = Math.floor(payment.milisatsAmount / 1000);
// Resolve the Lightning address to a BOLT11 invoice
const bolt11 = await this.resolveLightningAddress(address, sats);
const bolt11 = await this.resolveLightningAddress(address, sats, comment);
// Pay the BOLT11 via BTCPay's internal Lightning node
const payUrl = this.storeUrl('/lightning/BTC/invoices/pay');
@@ -578,6 +579,7 @@ export class BTCPayService implements LightningService {
private async resolveLightningAddress(
address: string,
amountSats: number,
comment?: string,
): Promise<string> {
const [username, domain] = address.split('@');
if (!username || !domain) {
@@ -606,6 +608,16 @@ export class BTCPayService implements LightningService {
const callbackUrl = new URL(lnurlData.callback);
callbackUrl.searchParams.set('amount', amountMillisats.toString());
// Include a descriptive comment if the endpoint supports it.
// LNURL-pay endpoints advertise commentAllowed (max char length).
const commentAllowed = lnurlData.commentAllowed || 0;
if (comment && commentAllowed > 0) {
callbackUrl.searchParams.set(
'comment',
comment.slice(0, commentAllowed),
);
}
const { data: invoiceData } = await axios.get(callbackUrl.toString(), { timeout: 10_000 });
if (invoiceData.status === 'ERROR') {