From 4ca5dd0afa7848d100f0b99be7b53f5dcb2fd061 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Sat, 1 Aug 2026 17:49:50 -0700 Subject: Never let a losing device's error shout over a paid zap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Loose leader election for pay_invoice across a user's open tabs: before handling, defer a beat and stay silent if any reply for the request already exists on the relays; and before sending an ERROR reply, re-check — a device that lost the race (mid-init, stale state) was replying 'superseded' after another device's success, and clients trusted the later error, marking paid zaps as failed. Co-Authored-By: Claude Fable 5 --- src/nostr.js | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/nostr.js') diff --git a/src/nostr.js b/src/nostr.js index 2c458af..37bd62d 100644 --- a/src/nostr.js +++ b/src/nostr.js @@ -40,6 +40,9 @@ export function subscribeOn(relays, filter, onEvent, extra = {}) { return () => { try { sub.close(); } catch {} }; } catch { return () => {}; } } +export async function queryOn(relays, filter, maxWait = 1500) { + try { return await pool.querySync(relays, filter, { maxWait }); } catch { return []; } +} export async function publishOn(relays, evt) { try { const results = await Promise.allSettled(pool.publish(relays, evt)); -- cgit v1.2.3