Fix Farcaster identity: Steemhunt API + Neynar fallback#253
Fix Farcaster identity: Steemhunt API + Neynar fallback#253realproject7 merged 2 commits intomainfrom
Conversation
Rewrite lib/farcaster.ts to use Steemhunt's free Farcaster Indexer API as the primary lookup, falling back to Neynar only when NEYNAR_API_KEY is configured. Simple in-memory cache (1h TTL) with in-flight dedup. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
project7-interns
left a comment
There was a problem hiding this comment.
APPROVE — with one non-blocking observation.
Observation (non-blocking): null results are now cached for 1h.
The old code explicitly avoided caching transient failures ("Only caches successful lookups with TTL; transient errors are never cached"). The new code caches null from the Neynar fallback path unconditionally — meaning if Steemhunt times out and NEYNAR_API_KEY isn't set, a null gets cached for 1h. A user who does have an FC account won't resolve until the cache entry expires.
For a v1 this is acceptable — the 1h window is bounded and the scenario (Steemhunt down + no Neynar key) should be rare. If it becomes an issue, a simple fix would be to skip caching when both lookups failed due to errors (vs. a genuine "no profile" result).
What looks good:
- In-flight dedup prevents thundering herd on popular addresses
AbortSignal.timeout(3000)prevents hanging requests- Same
lookupByAddress()signature — zero consumer changes needed .catch(() => null)on both paths ensures no unhandled rejections- Clean separation of
steemhuntLookup/neynarLookup
project7-interns
left a comment
There was a problem hiding this comment.
Verdict: REQUEST CHANGES
Summary
The Steemhunt-first / Neynar-fallback flow matches the ticket, but the new cache semantics introduce a regression: transient lookup failures are now cached as null for one hour.
Findings
- [medium]
lookupByAddress()now caches negative results for the full TTL, including transient network timeouts and 5xxs from Steemhunt/Neynar. Because both lookups are wrapped in.catch(() => null)and the final branch always doescache.set(key, { profile: fallback, expiresAt: ... }), a single temporary outage can suppress Farcaster identity for that address for an hour after the upstream has recovered.- File:
lib/farcaster.ts:82 - Suggestion: Preserve the previous behavior of caching only successful lookups, or distinguish true "not linked" responses from transient failures before negative-caching
null.
- File:
Decision
Request changes. The API swap is correct, but the null-cache regression should be fixed before merge.
Distinguish between "API confirmed wallet not linked" (cache null for 1h) and "transient error" (don't cache, retry next request). Addresses T2a review feedback on PR #253. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
project7-interns
left a comment
There was a problem hiding this comment.
Verdict: APPROVE
Summary
The follow-up patch fixes the cache regression from the earlier review. Transient Steemhunt/Neynar failures are no longer negative-cached, while confirmed not-linked responses can still be cached.
Findings
- [info] No blocking issues found in the updated patch.
Decision
Approve. The Steemhunt-first / Neynar-fallback flow now preserves the intended retry behavior after upstream recovery. CI was still pending when reviewed.
Summary
lib/farcaster.tsto use Steemhunt's free Farcaster Indexer API (fc.hunt.town) as primary lookupNEYNAR_API_KEYis configuredMapcache (1h TTL), 3s request timeout, in-flight dedupnode-cacheneeded)WriterIdentity.tsx,WriterIdentityClient.tsx) require no changes — samelookupByAddress()signature andFarcasterProfiletypeFixes #250
Test plan
npm run typecheckpasses🤖 Generated with Claude Code