From f385ae87f7b65ef2e2cc7caaedc78170c6c99392 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Mon, 17 Aug 2026 22:32:03 -0700 Subject: nwc: reply UNAUTHORIZED on unknown connection instead of returning silently A NIP-47 request whose pubkey/user no longer exists (deleted app or migrated user) was silently dropped, leaving the client spinning. Send an UNAUTHORIZED error reply so the client can surface it. Still not logged (not a server fault). Co-Authored-By: Claude Opus 4.8 --- lib/nwc.ts | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/nwc.ts b/lib/nwc.ts index 6f36293a..d830e8cd 100644 --- a/lib/nwc.ts +++ b/lib/nwc.ts @@ -309,8 +309,19 @@ export default () => { await reply({ result_type: method, ...result }); } } catch (e) { - // Stale client state (deleted app or migrated user) is not a server fault — don't log. - if (e.message === "pubkey not found" || e.message === "user not found") return; + // Stale client state (deleted app or migrated user) is not a server + // fault — don't log it, but DO answer: a NIP-47 UNAUTHORIZED reply + // lets the client surface an error instead of spinning forever on a + // connection this server no longer knows. + if (e.message === "pubkey not found" || e.message === "user not found") { + try { + await reply({ + result_type: method, + error: { code: "UNAUTHORIZED", message: "unknown connection" }, + }); + } catch (_) {} + return; + } err("problem with nwc", pubkey, method, e.message); // Still reply so the client isn't left hanging on the failure. try { -- cgit v1.2.3