diff --git a/keyserver/src/utils/fc-cache.js b/keyserver/src/utils/fc-cache.js --- a/keyserver/src/utils/fc-cache.js +++ b/keyserver/src/utils/fc-cache.js @@ -4,7 +4,7 @@ import { getFCNames as baseGetFCNames, type GetFCNames, - type BaseFCInfo, + type BaseFCNamesInfo, } from 'lib/utils/farcaster-helpers.js'; import { FCCache } from 'lib/utils/fc-cache.js'; import { NeynarClient } from 'lib/utils/neynar-client.js'; @@ -24,7 +24,7 @@ } neynarClient = new NeynarClient(neynarKey); const fcCache = new FCCache(neynarClient); - getFCNames = (users: $ReadOnlyArray): Promise => + getFCNames = (users: $ReadOnlyArray): Promise => baseGetFCNames(fcCache, users); } diff --git a/lib/components/neynar-client-provider.react.js b/lib/components/neynar-client-provider.react.js --- a/lib/components/neynar-client-provider.react.js +++ b/lib/components/neynar-client-provider.react.js @@ -4,8 +4,11 @@ import { getFCNames as baseGetFCNames, - type BaseFCInfo, + getFCAvatarURLs as baseGetFCAvatarURLs, + type BaseFCNamesInfo, + type BaseFCAvatarInfo, type GetFCNames, + type GetFCAvatarURLs, } from '../utils/farcaster-helpers.js'; import { FCCache } from '../utils/fc-cache.js'; import { NeynarClient } from '../utils/neynar-client.js'; @@ -14,6 +17,7 @@ +client: NeynarClient, +fcCache: FCCache, +getFCNames: GetFCNames, + +getFCAvatarURLs: GetFCAvatarURLs, }; const NeynarClientContext: React.Context = @@ -38,13 +42,17 @@ return null; } const fcCache = new FCCache(neynarClient); - const getFCNames: GetFCNames = ( + const getFCNames: GetFCNames = ( users: $ReadOnlyArray, ): Promise => baseGetFCNames(fcCache, users); + const getFCAvatarURLs: GetFCAvatarURLs = ( + fids: $ReadOnlyArray, + ): Promise => baseGetFCAvatarURLs(fcCache, fids); return { client: neynarClient, fcCache, getFCNames, + getFCAvatarURLs, }; }, [neynarClient]); diff --git a/lib/utils/farcaster-helpers.js b/lib/utils/farcaster-helpers.js --- a/lib/utils/farcaster-helpers.js +++ b/lib/utils/farcaster-helpers.js @@ -2,16 +2,24 @@ import { FCCache } from './fc-cache.js'; -export type BaseFCInfo = { +export type BaseFCNamesInfo = { +fid?: ?string, +farcasterUsername?: ?string, ... }; -export type GetFCNames = ( +export type BaseFCAvatarInfo = { + +fid: string, + +pfpURL: ?string, +}; + +export type GetFCNames = ( users: $ReadOnlyArray, ) => Promise; +export type GetFCAvatarURLs = ( + fids: $ReadOnlyArray, +) => Promise; -async function getFCNames( +async function getFCNames( fcCache: FCCache, users: $ReadOnlyArray, ): Promise { @@ -76,4 +84,57 @@ }); } -export { getFCNames }; +async function getFCAvatarURLs( + fcCache: FCCache, + fids: $ReadOnlyArray, +): Promise { + const info = fids.map(fid => { + const cachedResult = fcCache.getCachedFarcasterUserForFID(fid)?.pfpURL; + return { + fid, + cachedResult, + }; + }); + + const needFetch = info + .map(user => { + if (!user) { + return null; + } + const { fid, cachedResult } = user; + if (cachedResult) { + return null; + } + return fid; + }) + .filter(Boolean); + + const pfpURLs = new Map(); + if (needFetch.length > 0) { + const results = await fcCache.getFarcasterUsersForFIDs(needFetch); + for (let i = 0; i < needFetch.length; i++) { + const fid = needFetch[i]; + const result = results[i]; + if (result) { + pfpURLs.set(fid, result.pfpURL); + } + } + } + + return info.map(user => { + if (!user) { + return user; + } + const { fid, cachedResult } = user; + if (cachedResult) { + return { fid, pfpURL: cachedResult }; + } + const pfpURL = pfpURLs.get(fid); + if (pfpURL) { + return { fid, pfpURL }; + } + return { fid, pfpURL: null }; + }); +} + +export { getFCNames, getFCAvatarURLs };