From 60f9c91b61ce069fb472369eb6c16bf1a984a3d6 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Thu, 30 Jul 2026 21:07:48 -0700 Subject: zaps: stop spurious "failed to handle zap" warnings on non-zap invoices MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The zap dispatch parsed the invoice description and, when it wasn't JSON, suppressed the error only if the message contained "Unexpected" — V8's parse- error wording. On Bun the message is "Unable to parse JSON string", so every paid invoice with a non-JSON memo logged a warning. Parse-then-check instead: a non-JSON description is simply not a zap and is skipped silently; warn only when an actual kind-9734 zap request fails to process. Co-Authored-By: Claude Opus 4.8 --- lib/lightning.ts | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/lightning.ts b/lib/lightning.ts index cf099b23..b07db055 100644 --- a/lib/lightning.ts +++ b/lib/lightning.ts @@ -94,14 +94,20 @@ export async function listenForLightning() { if (p) return warn("already processed", bolt11 || bolt12); if (invoice?.memo) { - try { - if (JSON.parse(description).kind === 9734) { + // A non-JSON description just means this isn't a zap (the common case) — + // skip silently. Only a real kind-9734 zap request that fails to process + // is worth a warning. (The old `!includes("Unexpected")` guard was V8's + // parse-error wording; Bun's is "Unable to parse JSON string", so every + // non-zap memo'd invoice slipped through and spammed this warning.) + let zapreq; + try { zapreq = JSON.parse(description); } catch { zapreq = null; } + if (zapreq?.kind === 9734) { + try { const { pubkey } = await getUser(invoice.uid); handleZap(inv, pubkey); - } - } catch (e) { - if (!e.message.includes("Unexpected")) + } catch (e) { warn("failed to handle zap", e.message); + } } } @@ -237,14 +243,19 @@ export async function replay(index) { if (p) return warn("already processed", bolt11 || bolt12); if (invoice?.memo) { - try { - if (JSON.parse(description).kind === 9734) { + // Non-JSON description = not a zap (common case); skip silently. Only a + // real kind-9734 zap request that fails processing warrants a warning. + // (The old `!includes("Unexpected")` guard was V8 wording; Bun's parse + // error is "Unable to parse JSON string", so non-zaps spammed the warning.) + let zapreq; + try { zapreq = JSON.parse(description); } catch { zapreq = null; } + if (zapreq?.kind === 9734) { + try { const { pubkey } = await getUser(invoice.uid); handleZap(inv, pubkey); - } - } catch (e) { - if (!e.message.includes("Unexpected")) + } catch (e) { warn("failed to handle zap", e.message); + } } } -- cgit v1.2.3