From 2b7cd02ad584963f7f7b8f94653b2fc0db6a751e Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sat, 22 Aug 2026 09:29:53 -0700 Subject: The open tab learns the same manners as the worker: a wallet on the wrong network holds its tongue for three seconds before erring on a pay request, giving the right device's answer the floor Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_017Fc8SHJRvBBXgMCntjNCri --- src/features/nwc.js | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'src') diff --git a/src/features/nwc.js b/src/features/nwc.js index ef34373..45bbbf5 100644 --- a/src/features/nwc.js +++ b/src/features/nwc.js @@ -365,6 +365,15 @@ export function nwcFeature(ctx) { const dec = maybeBolt11(invoice); if (!dec) return errRes('OTHER', 'not a bolt11 invoice'); if (!dec.amountSat) return errRes('OTHER', 'zero-amount invoices are not supported'); + // The invoice names its network. A wallet on another network (a + // mutinynet tab, say) must not race the user's real payer with an + // instant mismatch error — hold back long enough for the right device + // to answer; sendChecked then suppresses this if anyone did. + const netOf = (n) => (n === 'mutinynet' ? 'signet' : n); + if (dec.network && netOf(getNetwork()) !== dec.network) { + await new Promise((r) => setTimeout(r, 3000)); + return errRes('INTERNAL', `invoice is for ${dec.network}, wallet is on ${netOf(getNetwork())}`); + } const { left } = spendRoom(c); if (dec.amountSat > c.maxSat) { return errRes('QUOTA_EXCEEDED', `over the ${c.maxSat} sat per-payment limit`); -- cgit v1.2.3