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,10 @@ import { getFCNames as baseGetFCNames, + getFCAvatarURLs as baseGetFCAvatarURLs, type BaseFCInfo, 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 +16,7 @@ +client: NeynarClient, +fcCache: FCCache, +getFCNames: GetFCNames, + +getFCAvatarURLs: GetFCAvatarURLs, }; const NeynarClientContext: React.Context = @@ -41,10 +44,14 @@ const getFCNames: GetFCNames = ( users: $ReadOnlyArray, ): Promise => baseGetFCNames(fcCache, users); + const getFCAvatarURLs: GetFCAvatarURLs = ( + users: $ReadOnlyArray, + ): Promise => baseGetFCAvatarURLs(fcCache, users); 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 @@ -5,11 +5,15 @@ export type BaseFCInfo = { +fid?: ?string, +farcasterUsername?: ?string, + +pfpURL?: ?string, ... }; export type GetFCNames = ( users: $ReadOnlyArray, ) => Promise; +export type GetFCAvatarURLs = ( + users: $ReadOnlyArray, +) => Promise; async function getFCNames( fcCache: FCCache, @@ -76,4 +80,69 @@ }); } -export { getFCNames }; +async function getFCAvatarURLs( + fcCache: FCCache, + users: $ReadOnlyArray, +): Promise { + const info = users.map(user => { + if (!user) { + return user; + } + const { fid, pfpURL } = user; + let cachedResult = null; + if (pfpURL) { + cachedResult = pfpURL; + } else if (fid) { + cachedResult = fcCache.getCachedFarcasterUserForFID(fid)?.pfpURL; + } + return { + input: user, + fid, + cachedResult, + }; + }); + + const needFetch = info + .map(user => { + if (!user) { + return null; + } + const { fid, cachedResult } = user; + if (cachedResult || !fid) { + 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 { input, fid, cachedResult } = user; + if (cachedResult) { + return { ...input, pfpURL: cachedResult }; + } else if (!fid) { + return input; + } + const pfpURL = pfpURLs.get(fid); + if (pfpURL) { + return { ...input, pfpURL }; + } + return input; + }); +} + +export { getFCNames, getFCAvatarURLs };