From fe7630280e45cce884bbddac2c0a725796fe6c0b Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Fri, 24 Apr 2026 13:06:29 +0900 Subject: [PATCH 1/2] [Hotfix] Create OWS wallet DB row on agent linking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a human links their OWS wallet via /api/user/link-agent, also create/update a user row for the OWS wallet with agent metadata. Tries ERC-8004 RPC lookup for agent_id (best effort — may fail due to rate limiting). Without this, the OWS wallet profile page showed as "Human" with no agent identity. Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/api/user/link-agent/route.ts | 45 ++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/src/app/api/user/link-agent/route.ts b/src/app/api/user/link-agent/route.ts index 62a5d6fa..65cf5cdf 100644 --- a/src/app/api/user/link-agent/route.ts +++ b/src/app/api/user/link-agent/route.ts @@ -1,6 +1,8 @@ import { NextRequest, NextResponse } from "next/server"; import { verifyMessage } from "viem"; import { createServiceRoleClient } from "../../../../../lib/supabase"; +import { getAgentMetadata } from "../../../../../lib/contracts/erc8004"; +import type { Address } from "viem"; /** * POST /api/user/link-agent @@ -118,6 +120,49 @@ export async function POST(request: NextRequest) { } } + // Ensure the OWS wallet has a user row so its profile page works. + // If it already registered via ERC-8004, this will find it; otherwise create a minimal row. + const { data: owsUser } = await supabase + .from("users") + .select("id") + .or(`primary_address.eq.${normalizedOws},agent_wallet.eq.${normalizedOws}`) + .limit(1) + .single(); + + // Try to fetch ERC-8004 agent metadata for the OWS wallet (best effort) + let agentFields: Record = {}; + try { + const meta = await getAgentMetadata(normalizedOws as Address); + if (meta?.agentId) { + agentFields = { + agent_id: Number(meta.agentId), + agent_name: meta.name || null, + agent_description: meta.description || null, + agent_genre: meta.genre || null, + agent_registered_at: meta.registeredAt || new Date().toISOString(), + }; + } + } catch { /* RPC may fail — proceed without agent metadata */ } + + if (owsUser) { + // Update existing row with agent fields if found + if (Object.keys(agentFields).length > 0) { + await supabase.from("users").update({ + agent_owner: normalizedHuman, + agent_type: "ows-writer", + ...agentFields, + }).eq("id", owsUser.id).catch(() => {}); + } + } else { + await supabase.from("users").insert({ + primary_address: normalizedOws, + agent_wallet: normalizedOws, + agent_owner: normalizedHuman, + agent_type: "ows-writer", + ...agentFields, + }).catch(() => { /* best effort — may conflict if row was created concurrently */ }); + } + return NextResponse.json({ ok: true, linkedWallet: normalizedOws }); } catch (err) { return NextResponse.json( From a1d5a7a44d4c6d97288dfa22ebb1421d10c51072 Mon Sep 17 00:00:00 2001 From: Cho Young-Hwi Date: Fri, 24 Apr 2026 13:11:39 +0900 Subject: [PATCH 2/2] =?UTF-8?q?Fix:=20remove=20.catch()=20on=20Supabase=20?= =?UTF-8?q?queries=20=E2=80=94=20not=20supported=20by=20typed=20builder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 (1M context) --- src/app/api/user/link-agent/route.ts | 29 ++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/app/api/user/link-agent/route.ts b/src/app/api/user/link-agent/route.ts index 65cf5cdf..6a967bc9 100644 --- a/src/app/api/user/link-agent/route.ts +++ b/src/app/api/user/link-agent/route.ts @@ -144,24 +144,25 @@ export async function POST(request: NextRequest) { } } catch { /* RPC may fail — proceed without agent metadata */ } - if (owsUser) { - // Update existing row with agent fields if found - if (Object.keys(agentFields).length > 0) { - await supabase.from("users").update({ + try { + if (owsUser) { + if (Object.keys(agentFields).length > 0) { + await supabase.from("users").update({ + agent_owner: normalizedHuman, + agent_type: "ows-writer", + ...agentFields, + }).eq("id", owsUser.id); + } + } else { + await supabase.from("users").insert({ + primary_address: normalizedOws, + agent_wallet: normalizedOws, agent_owner: normalizedHuman, agent_type: "ows-writer", ...agentFields, - }).eq("id", owsUser.id).catch(() => {}); + }); } - } else { - await supabase.from("users").insert({ - primary_address: normalizedOws, - agent_wallet: normalizedOws, - agent_owner: normalizedHuman, - agent_type: "ows-writer", - ...agentFields, - }).catch(() => { /* best effort — may conflict if row was created concurrently */ }); - } + } catch { /* best effort — row creation may conflict */ } return NextResponse.json({ ok: true, linkedWallet: normalizedOws }); } catch (err) {