Bug
When a known PlotLink user (who is NOT an agent) visits /agents, the page fires 3+ RPC calls to base-rpc.publicnode.com (agentIdByWallet, balanceOf, tokenOfOwnerByIndex) even though the DB already knows this user has no agent registration. This defeats the purpose of PR #597 (agent DB cache).
Visible in network tab: multiple base-rpc.publicnode.com fetches on every page load.
Root Cause
In src/app/agents/page.tsx, the detection flow is:
- Call
getAgentUserFromDB(address) — this function (lib/actions.ts lines 186-231) queries the users table with agent_id IS NOT NULL filter on ALL queries
- For a user who exists in DB but has
agent_id = NULL → all queries exclude them → returns null
dbUser = null, dbDetected = false
needsRpcFallback = !dbLoading && !dbDetected && !!address → true
- Three RPC calls fire unnecessarily
The function cannot distinguish between:
- "User exists in DB but is not an agent" (
agent_id IS NULL) → should NOT make RPC calls
- "User has no DB record at all" (completely unknown wallet) → SHOULD make RPC calls (might be externally registered agent)
Fix
Change the detection to also check if the user exists in DB at all (regardless of agent status):
Option A: Two-step DB check in agents/page.tsx
// Step 1: Check if user has cached agent data
const { data: agentUser, isLoading: agentLoading } = useQuery({
queryKey: ["db-agent", address],
queryFn: () => getAgentUserFromDB(address!),
enabled: !!address,
});
// Step 2: Check if user exists in DB at all (regardless of agent status)
const { data: regularUser, isLoading: userLoading } = useQuery({
queryKey: ["db-user-exists", address],
queryFn: () => getUserFromDB(address!),
enabled: !!address && !agentLoading && agentUser === null,
});
const dbLoading = agentLoading || (agentUser === null && userLoading);
const dbDetected = agentUser?.agent_id != null;
const userExistsInDB = agentUser != null || regularUser != null;
// Only RPC if user has NO DB record at all (completely unknown wallet)
const needsRpcFallback = !dbLoading && !dbDetected && !userExistsInDB && !!address;
Option B: Single function that returns discriminated result
Create a new checkAgentStatus(address) server action that returns:
type AgentStatus =
| { status: "agent"; user: User } // known agent
| { status: "not-agent" } // known user, no agent_id
| { status: "unknown" } // no DB record at all
This is cleaner and avoids two separate DB round-trips.
Expected behavior after fix
| Scenario |
DB check |
RPC calls |
Result |
| Known user, no agent_id |
getUserFromDB → user found, agent_id = NULL |
None |
Show registration form |
| Known agent |
getAgentUserFromDB → agent found |
None |
Show management UI |
| Unknown wallet (no DB record) |
Both return null |
Yes (3 calls) |
Check if externally registered |
| Unknown wallet, externally registered agent |
Both return null, RPC finds agent |
Yes, then auto-cache |
Show management UI |
Files to modify
src/app/agents/page.tsx — fix needsRpcFallback logic
lib/actions.ts — possibly add checkAgentStatus() helper
Branch
task/600-fix-agent-rpc-fallback
Acceptance criteria
Bug
When a known PlotLink user (who is NOT an agent) visits
/agents, the page fires 3+ RPC calls tobase-rpc.publicnode.com(agentIdByWallet,balanceOf,tokenOfOwnerByIndex) even though the DB already knows this user has no agent registration. This defeats the purpose of PR #597 (agent DB cache).Visible in network tab: multiple
base-rpc.publicnode.comfetches on every page load.Root Cause
In
src/app/agents/page.tsx, the detection flow is:getAgentUserFromDB(address)— this function (lib/actions.ts lines 186-231) queries the users table withagent_id IS NOT NULLfilter on ALL queriesagent_id = NULL→ all queries exclude them → returnsnulldbUser = null,dbDetected = falseneedsRpcFallback = !dbLoading && !dbDetected && !!address→ trueThe function cannot distinguish between:
agent_id IS NULL) → should NOT make RPC callsFix
Change the detection to also check if the user exists in DB at all (regardless of agent status):
Option A: Two-step DB check in agents/page.tsx
Option B: Single function that returns discriminated result
Create a new
checkAgentStatus(address)server action that returns:This is cleaner and avoids two separate DB round-trips.
Expected behavior after fix
getUserFromDB→ user found,agent_id = NULLgetAgentUserFromDB→ agent foundFiles to modify
src/app/agents/page.tsx— fixneedsRpcFallbacklogiclib/actions.ts— possibly addcheckAgentStatus()helperBranch
task/600-fix-agent-rpc-fallbackAcceptance criteria