From fdc194ac277755246122ac70f5095f127a80d5cb Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Mon, 30 Mar 2026 19:41:09 +0100 Subject: [PATCH] [#632] Fix first-connect race: await register before profile fetch useConnectedIdentity fired register-by-wallet (fire-and-forget) and getFarcasterProfile in parallel, causing double SteemHunt/Neynar API calls on first connect since DB was empty when profile fetch ran. Now awaits register completion before fetching profile, so the DB is populated first and getFarcasterProfile reads from cache. Fixes realproject7/plotlink#632 Co-Authored-By: Claude Opus 4.6 (1M context) --- src/hooks/useConnectedIdentity.ts | 39 +++++++++++++++++++------------ 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/src/hooks/useConnectedIdentity.ts b/src/hooks/useConnectedIdentity.ts index 163f10cc..b1f1a006 100644 --- a/src/hooks/useConnectedIdentity.ts +++ b/src/hooks/useConnectedIdentity.ts @@ -25,24 +25,33 @@ export function useConnectedIdentity() { let cancelled = false; fetchingRef.current = true; - // Register user in DB (fire-and-forget) - if (registeredRef.current !== address) { - registeredRef.current = address; - fetch("/api/user/register-by-wallet", { - method: "POST", - headers: { "Content-Type": "application/json" }, - body: JSON.stringify({ walletAddress: address }), - }).catch(() => { - // Non-fatal — profile will still work from live API - }); - } + const addr = address; // capture for closure type narrowing + async function init() { + // Step 1: Register (populates DB with SteemHunt/Neynar data) + if (registeredRef.current !== addr) { + registeredRef.current = addr; + try { + await fetch("/api/user/register-by-wallet", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ walletAddress: addr }), + }); + } catch { + // Non-fatal — profile will still work from live API + } + } - getFarcasterProfile(address).then((p) => { + // Step 2: Now fetch profile (DB is populated, no external API needed) if (!cancelled) { - setResult({ profile: p, resolvedFor: address }); - fetchingRef.current = false; + const p = await getFarcasterProfile(addr); + if (!cancelled) { + setResult({ profile: p, resolvedFor: addr }); + fetchingRef.current = false; + } } - }); + } + + init(); return () => { cancelled = true; };