From 4c263e729a82b4c67437c84e4c7568dc97cd4e0a Mon Sep 17 00:00:00 2001 From: "shakespeare.diy" Date: Wed, 17 Jun 2026 11:43:51 +0700 Subject: [PATCH] fix: replace subscribeMany with querySync for nostr-tools v2 compatibility The server was using the nostr-tools v1 API (subscribeMany with onevent/oneose callbacks) but the installed version is v2.23.5 which changed the internal subscription handling. querySync() is the correct v2 API for one-shot queries and handles EOSE cleanly without needing manual timeout management. Co-authored-by: shakespeare.diy --- cvm-server/server.ts | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/cvm-server/server.ts b/cvm-server/server.ts index fc9651a..b3d81ff 100644 --- a/cvm-server/server.ts +++ b/cvm-server/server.ts @@ -45,23 +45,27 @@ const CVM_RELAY = process.env.CVM_RELAY || "wss://relay.contextvm.net"; const dataPool = new SimplePool(); -async function queryNostr(filters: Filter[], timeoutMs = 6000): Promise { - return new Promise((resolve) => { - const events: any[] = []; - const sub = dataPool.subscribeMany(NOSTR_RELAYS, filters, { - onevent(e: any) { - events.push(e); - }, - oneose() { - sub.close(); - resolve(events); - }, - }); - setTimeout(() => { - sub.close(); - resolve(events); - }, timeoutMs); - }); +async function queryNostr(filters: Filter[], timeoutMs = 8000): Promise { + // nostr-tools v2: use querySync which handles eose cleanly + // Run each filter separately and merge results (querySync takes a single filter) + const allEvents: any[] = []; + await Promise.all( + filters.map(async (filter) => { + try { + const abort = new AbortController(); + const timer = setTimeout(() => abort.abort(), timeoutMs); + const events = await dataPool.querySync(NOSTR_RELAYS, filter, { + maxWait: timeoutMs, + abort: abort.signal, + }); + clearTimeout(timer); + allEvents.push(...events); + } catch { + // ignore per-filter errors + } + }) + ); + return allEvents; } // ─── Helpers ─────────────────────────────────────────────────────────────────