From 849e00a2ffac505d0573ab0d51288a4817d30574 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 6 Feb 2026 02:00:56 +0000 Subject: [PATCH] fix: resolve decryption timeouts and listener warnings Increases NIP-07 concurrency to 3 and lowers priority for non-critical decryption tasks to prevent blocklist timeouts. Increases relay max listeners to 200 to mitigate warnings. Co-authored-by: PR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> --- js/nostr/client.js | 10 +++++++--- js/nostr/nip07Permissions.js | 2 +- js/services/hashtagPreferencesService.js | 4 ++-- js/subscriptions.js | 4 ++-- tests/nip07-concurrency.test.mjs | 18 ++++++++++-------- 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/js/nostr/client.js b/js/nostr/client.js index 6d869794..6dc72632 100644 --- a/js/nostr/client.js +++ b/js/nostr/client.js @@ -4654,13 +4654,17 @@ export class NostrClient { const relay = await originalEnsureRelay(url); if (relay && typeof relay.setMaxListeners === "function") { try { - relay.setMaxListeners(100); + relay.setMaxListeners(200); } catch (error) { // ignore } } return relay; }; + } else { + devLogger.warn( + "[nostr] SimplePool.ensureRelay missing; max listeners patch skipped." + ); } shimLegacySimplePoolMethods(instance); @@ -5170,7 +5174,7 @@ export class NostrClient { (pubkey, ciphertext, options) => activeSigner.nip44Decrypt(pubkey, ciphertext, { ...options, - priority: NIP07_PRIORITY.HIGH, + priority: NIP07_PRIORITY.NORMAL, }), { priority: -20, @@ -5188,7 +5192,7 @@ export class NostrClient { (pubkey, ciphertext, options) => activeSigner.nip04Decrypt(pubkey, ciphertext, { ...options, - priority: NIP07_PRIORITY.HIGH, + priority: NIP07_PRIORITY.NORMAL, }), { priority: -10, diff --git a/js/nostr/nip07Permissions.js b/js/nostr/nip07Permissions.js index 5f39ce8c..2efa0055 100644 --- a/js/nostr/nip07Permissions.js +++ b/js/nostr/nip07Permissions.js @@ -99,7 +99,7 @@ class Nip07RequestQueue { // This prevents "message channel closed" errors caused by race conditions // when multiple components (blocks, DMs, auth) query the extension simultaneously, // while allowing critical tasks (e.g. blocklist decryption) to jump the line. -const requestQueue = new Nip07RequestQueue(2); +const requestQueue = new Nip07RequestQueue(3); export function getEnableVariantTimeoutMs() { const overrideValue = diff --git a/js/services/hashtagPreferencesService.js b/js/services/hashtagPreferencesService.js index 2ba1c0cb..8c8709b5 100644 --- a/js/services/hashtagPreferencesService.js +++ b/js/services/hashtagPreferencesService.js @@ -951,7 +951,7 @@ class HashtagPreferencesService { // get more time because the user may be approving a popup. const nip07DecryptTimeoutMs = allowPermissionPrompt ? 15000 : 5000; const signerDecryptOptions = { - priority: NIP07_PRIORITY.HIGH, + priority: NIP07_PRIORITY.NORMAL, timeoutMs: nip07DecryptTimeoutMs, retryMultiplier: 1, }; @@ -981,7 +981,7 @@ class HashtagPreferencesService { } const extensionDecryptOptions = { - priority: NIP07_PRIORITY.HIGH, + priority: NIP07_PRIORITY.NORMAL, timeoutMs: nip07DecryptTimeoutMs, retryMultiplier: 1, }; diff --git a/js/subscriptions.js b/js/subscriptions.js index d7f14af1..b5f3a441 100644 --- a/js/subscriptions.js +++ b/js/subscriptions.js @@ -970,7 +970,7 @@ class SubscriptionsManager { // loads get more time because the user may be approving a popup. const nip07DecryptTimeoutMs = allowPermissionPrompt ? 15000 : 5000; const signerDecryptOptions = { - priority: NIP07_PRIORITY.HIGH, + priority: NIP07_PRIORITY.NORMAL, timeoutMs: nip07DecryptTimeoutMs, retryMultiplier: 1, }; @@ -992,7 +992,7 @@ class SubscriptionsManager { if (nostrApi) { const decrypterOptions = { - priority: NIP07_PRIORITY.HIGH, + priority: NIP07_PRIORITY.NORMAL, timeoutMs: nip07DecryptTimeoutMs, retryMultiplier: 1, }; diff --git a/tests/nip07-concurrency.test.mjs b/tests/nip07-concurrency.test.mjs index 6647f89d..1b86d38a 100644 --- a/tests/nip07-concurrency.test.mjs +++ b/tests/nip07-concurrency.test.mjs @@ -21,9 +21,9 @@ describe("NIP-07 Concurrency Queue", () => { global.window = originalWindow; }); - test("runs up to 2 tasks concurrently", async () => { + test("runs up to 3 tasks concurrently", async () => { const start = Date.now(); - const delays = [200, 200, 100]; + const delays = [200, 200, 200, 100]; const log = []; const task = (id, delay) => async () => { @@ -36,17 +36,18 @@ describe("NIP-07 Concurrency Queue", () => { const p1 = runNip07WithRetry(task(1, delays[0]), { priority: NIP07_PRIORITY.NORMAL }); const p2 = runNip07WithRetry(task(2, delays[1]), { priority: NIP07_PRIORITY.NORMAL }); const p3 = runNip07WithRetry(task(3, delays[2]), { priority: NIP07_PRIORITY.NORMAL }); + const p4 = runNip07WithRetry(task(4, delays[3]), { priority: NIP07_PRIORITY.NORMAL }); - await Promise.all([p1, p2, p3]); + await Promise.all([p1, p2, p3, p4]); const starts = log.filter(e => e.status === 'start'); - // Task 1 and 2 should start almost immediately (concurrency 2) - assert.ok(Math.abs(starts[0].time - starts[1].time) < 50, "Task 1 and 2 should start concurrently"); + // Task 1, 2, 3 should start almost immediately (concurrency 3) + assert.ok(Math.abs(starts[0].time - starts[2].time) < 50, "Task 1, 2, 3 should start concurrently"); - // Task 3 should start after roughly 200ms (when slot opens) + // Task 4 should start after roughly 200ms (when slot opens) // Note: Node's setTimeout is not precise, so we use loose bounds - assert.ok(starts[2].time >= 150, "Task 3 should wait for a slot"); + assert.ok(starts[3].time >= 150, "Task 4 should wait for a slot"); }); test("respects priority", async () => { @@ -59,9 +60,10 @@ describe("NIP-07 Concurrency Queue", () => { return id; }; - // Fill the queue (size 2) + // Fill the queue (size 3) runNip07WithRetry(task('blocker1', 100)); runNip07WithRetry(task('blocker2', 100)); + runNip07WithRetry(task('blocker3', 100)); // Enqueue low priority const pLow = runNip07WithRetry(task('low', 50), { priority: NIP07_PRIORITY.LOW });