Files
bitvid/js/nostr/decryptionSchemeCache.js
T
Claude 71c153f68d perf: speed up post-login list sync with shared decryption cache
Three performance bottlenecks were causing slow list loading after NIP-07 login:

1. Each list service (blocks, subscriptions, hashtag preferences) maintained
   its own isolated decryptionSuccessCache. When blocks decrypted with nip44_v2,
   subscriptions and hashtag preferences had no way to know — they each had to
   independently probe all schemes through the NIP-07 extension queue, tripling
   the number of extension calls during the critical login path.

2. List loading was gated on both relaysReadyPromise AND permissionPromise in
   the coordinator. Since the NIP-07 extension already grants decrypt permissions
   during loginWithExtension(), the redundant pre-grant was adding 2-5 seconds
   of unnecessary latency before any list fetching could begin.

3. The DECRYPT_RETRY_DELAY_MS was 10 seconds across all services. When a decrypt
   attempt failed transiently (extension still initializing), the retry waited
   far too long before trying again.

Changes:
- Create shared decryptionSchemeCache module used by all three list services
- Add fast-path: when shared cache knows the correct scheme, try ONLY that
  scheme before falling back to parallel Promise.any() probe
- Remove permissionPromise from the list-loading gate in authSessionCoordinator
- Reduce DECRYPT_RETRY_DELAY_MS from 10s to 3s in all three services
- Clear shared cache on logout

https://claude.ai/code/session_013QrGMnxtMTsGTPqaP35jMj
2026-02-07 13:43:15 +00:00

67 lines
1.8 KiB
JavaScript

// js/nostr/decryptionSchemeCache.js
/**
* Shared decryption scheme cache across all list services (blocks,
* subscriptions, hashtag preferences). When one service discovers the
* correct decryption scheme for a pubkey, the others can reuse it
* immediately instead of independently probing the NIP-07 extension.
*
* This eliminates redundant extension decrypt calls during the critical
* login path where all three services decrypt simultaneously.
*/
const DECRYPTION_CACHE_TTL_MS = 10 * 60 * 1000; // 10 minutes
/** @type {Map<string, { scheme: string, timestamp: number }>} */
const cache = new Map();
/**
* Retrieve the last successfully-used decryption scheme for a pubkey.
* Returns null if the entry is missing or expired.
*
* @param {string} pubkey - Hex pubkey to look up.
* @returns {string|null} The scheme identifier (e.g. "nip44_v2") or null.
*/
export function getLastSuccessfulScheme(pubkey) {
if (typeof pubkey !== "string" || !pubkey) {
return null;
}
const entry = cache.get(pubkey);
if (!entry) {
return null;
}
if (Date.now() - entry.timestamp > DECRYPTION_CACHE_TTL_MS) {
cache.delete(pubkey);
return null;
}
return entry.scheme;
}
/**
* Record a successful decryption scheme for a pubkey so other services
* can skip scheme discovery.
*
* @param {string} pubkey - Hex pubkey.
* @param {string} scheme - The scheme that succeeded (e.g. "nip44_v2").
*/
export function setLastSuccessfulScheme(pubkey, scheme) {
if (typeof pubkey !== "string" || !pubkey) {
return;
}
if (typeof scheme !== "string" || !scheme) {
return;
}
cache.set(pubkey, { scheme, timestamp: Date.now() });
}
/**
* Clear all cached entries. Useful on logout.
*/
export function clearDecryptionSchemeCache() {
cache.clear();
}