From ee9c2700e700b71f0ae5bb7742eeb0ed94cd5fae Mon Sep 17 00:00:00 2001 From: thePR0M3TH3AN <53631862+PR0M3TH3AN@users.noreply.github.com> Date: Sun, 14 Jun 2026 16:01:29 -0400 Subject: [PATCH] refactor(watch-history): route relay fetches through SubscriptionManager (P4) watchHistory.fetch now reads via the L1 SubscriptionManager (deduped + health-gated) instead of pool.list directly: a new getSubscriptionManager dep is threaded from the client, and both fetches (index + chunks) go through a listEvents() helper. Raw pool.list is retained only as a fallback for environments without a manager (tests/mocks), so the file stays grandfathered. Verified: watch-history unit test passes; wh-repro cold resolve returns 10 items with 2 decrypts (routing intact end-to-end). Co-Authored-By: Claude Opus 4.8 --- js/nostr/client.js | 1 + js/nostr/watchHistory.js | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/js/nostr/client.js b/js/nostr/client.js index 46909f7c..02c2f3cd 100644 --- a/js/nostr/client.js +++ b/js/nostr/client.js @@ -500,6 +500,7 @@ export class NostrClient { this.nip71Cache = new Map(); this.watchHistory = createWatchHistoryManager({ getPool: () => this.pool, + getSubscriptionManager: () => this.getSubscriptionManager(), getActivePubkey: () => this.pubkey, getSessionActor: () => this.sessionActor, ensureSessionActor: () => this.ensureSessionActor(), diff --git a/js/nostr/watchHistory.js b/js/nostr/watchHistory.js index b1680326..158bc890 100644 --- a/js/nostr/watchHistory.js +++ b/js/nostr/watchHistory.js @@ -1925,6 +1925,16 @@ class WatchHistoryManager { }; } const pool = typeof this.deps.getPool === "function" ? this.deps.getPool() : null; + // Route relay reads through the L1 SubscriptionManager when available + // (deduped + health-gated); fall back to the raw pool otherwise. + const subscriptionManager = + typeof this.deps.getSubscriptionManager === "function" + ? this.deps.getSubscriptionManager() + : null; + const listEvents = (relays, filters) => + subscriptionManager + ? subscriptionManager.list({ filters, relays }) + : pool.list(relays, filters); if (!pool) { devLogger.warn( "[nostr] Cannot fetch watch history because relay pool is unavailable. Returning cached values.", @@ -1966,7 +1976,7 @@ class WatchHistoryManager { limit, }, ]; - const results = await pool.list(readRelays, filters); + const results = await listEvents(readRelays, filters); pointerEvents = Array.isArray(results) ? results .flat() @@ -2029,7 +2039,7 @@ class WatchHistoryManager { let decryptedItems = []; if (chunkIdentifiers.length && canAttemptDecrypt) { try { - const results = await pool.list(readRelays, [ + const results = await listEvents(readRelays, [ { kinds: [WATCH_HISTORY_KIND], authors: [actorKey],