diff --git a/lib/utils/neynar-client.js b/lib/utils/neynar-client.js --- a/lib/utils/neynar-client.js +++ b/lib/utils/neynar-client.js @@ -63,9 +63,16 @@ class NeynarClient { apiKey: string; + ledChannelsCache: Map< + string, + { channels: NeynarChannel[], timestamp: number }, + >; + cacheTTL: number; - constructor(apiKey: string) { + constructor(apiKey: string, cacheTTL: number = 60000) { this.apiKey = apiKey; + this.ledChannelsCache = new Map(); + this.cacheTTL = cacheTTL; // Default TTL of 60 seconds } // We're using the term "friend" for a bidirectional follow @@ -153,11 +160,31 @@ return this.fetchFollowedFarcasterChannelsWithFilter(fid, () => true); } - fetchLedFarcasterChannels(fid: string): Promise { - return this.fetchFollowedFarcasterChannelsWithFilter( + cleanExpiredCacheEntries() { + const now = Date.now(); + for (const [fid, { timestamp }] of this.ledChannelsCache.entries()) { + if (now - timestamp >= this.cacheTTL) { + this.ledChannelsCache.delete(fid); + } + } + } + + async fetchLedFarcasterChannels(fid: string): Promise { + this.cleanExpiredCacheEntries(); + + const cachedEntry = this.ledChannelsCache.get(fid); + if (cachedEntry && Date.now() - cachedEntry.timestamp < this.cacheTTL) { + return cachedEntry.channels; + } + + const channels = await this.fetchFollowedFarcasterChannelsWithFilter( fid, channel => channel.lead.fid === parseInt(fid), ); + + this.ledChannelsCache.set(fid, { channels, timestamp: Date.now() }); + + return channels; } async fetchFarcasterChannelByName(