diff options
Diffstat (limited to 'src/features')
| -rw-r--r-- | src/features/ark.js | 13 | ||||
| -rw-r--r-- | src/features/nwc.js | 13 |
2 files changed, 22 insertions, 4 deletions
diff --git a/src/features/ark.js b/src/features/ark.js index 67759c9..87bb5c9 100644 --- a/src/features/ark.js +++ b/src/features/ark.js @@ -3629,7 +3629,18 @@ export function arkFeature(ctx) { async arkMakeInvoice(amountSat, description) { const mgr = await connectArk(); const a = await mgr.createLnInvoice(amountSat, description); - return { invoice: a.invoice, paymentHash: a.paymentHash, amountSat }; + return { invoice: a.invoice, paymentHash: a.paymentHash, amountSat, expiresAt: a.expiresAt }; + }, + // NIP-47 lookup_invoice: a payment of ours by hash or bolt11. One that + // is still pending gets a push first (a receive whose HTLCs have + // arrived is claimed right here), so a merchant polling sees it settle. + async arkLnLookup(q) { + const mgr = await connectArk(); + const found = mgr.lnLookup(q); + if (!found || found.state !== 'pending') return found; + const a = (mgr.state.actions || []).find((x) => x.paymentHash === found.payment_hash && x.type.startsWith('ln-')); + if (a) await Promise.race([mgr.driveLn(a.id).catch(() => {}), new Promise((r) => setTimeout(r, 8000))]); + return mgr.lnLookup(q); }, arkMovements() { const s = arkStateNow(); return s ? (s.movements || []) : []; }, // The wallet's reusable ark receive address (BIP-353 names publish it). diff --git a/src/features/nwc.js b/src/features/nwc.js index 4259207..9cf8d0b 100644 --- a/src/features/nwc.js +++ b/src/features/nwc.js @@ -40,7 +40,7 @@ const RES_KIND = 23195; const INFO_KIND = 13194; // What we can actually honour. No pay_keysend (Ark can't), no multi_pay. -const METHODS = ['get_info', 'get_balance', 'pay_invoice', 'make_invoice', 'list_transactions']; +const METHODS = ['get_info', 'get_balance', 'pay_invoice', 'make_invoice', 'lookup_invoice', 'list_transactions']; // Requests older than this are ignored — a relay replaying history must not // re-trigger payments. @@ -461,12 +461,19 @@ export function nwcFeature(ctx) { const inv = await hook('arkMakeInvoice', sat, params.description || ''); return { result: { - type: 'incoming', invoice: inv.invoice, payment_hash: inv.paymentHash, + type: 'incoming', state: 'pending', invoice: inv.invoice, payment_hash: inv.paymentHash, amount: sat * 1000, created_at: nowSec(), description: params.description || '', + expires_at: inv.expiresAt ? Math.floor(inv.expiresAt / 1000) : undefined, }, }; } + if (method === 'lookup_invoice') { + if (!params.payment_hash && !params.invoice) return errRes('OTHER', 'payment_hash or invoice required'); + const tx = await hook('arkLnLookup', { paymentHash: params.payment_hash, invoice: params.invoice }); + return tx ? { result: tx } : errRes('NOT_FOUND', 'invoice not found'); + } + if (method === 'list_transactions') { const movements = hook('arkMovements') || []; const txs = movements @@ -474,7 +481,7 @@ export function nwcFeature(ctx) { .slice(-(params.limit || 20)) .map((m) => ({ type: m.type === 'ln-receive' ? 'incoming' : 'outgoing', - invoice: m.invoice || '', preimage: m.preimage || '', + state: 'settled', invoice: m.invoice || '', preimage: m.preimage || '', amount: (m.amountSat || 0) * 1000, fees_paid: 0, created_at: Math.floor((m.ts || Date.now()) / 1000), settled_at: Math.floor((m.ts || Date.now()) / 1000), |
