diff --git a/src/app/api/access/route.ts b/src/app/api/access/route.ts index 4fef23d9..535e123b 100644 --- a/src/app/api/access/route.ts +++ b/src/app/api/access/route.ts @@ -23,8 +23,13 @@ export async function POST(request: Request) { try { const supabase = getSupabaseAdminClient(); await supabase.from("users").upsert( - { privy_id: userId, email: body.email || null, x_handle: body.xHandle || null, last_seen_at: new Date().toISOString() }, - { onConflict: "privy_id", ignoreDuplicates: false }, + { + id: `privy:${userId}`, + email: body.email || null, + x_handle: body.xHandle || null, + last_seen_at: new Date().toISOString(), + }, + { onConflict: "id", ignoreDuplicates: false }, ); } catch { /* non-fatal */ } diff --git a/src/app/api/user/wallet/route.ts b/src/app/api/user/wallet/route.ts index e7b122df..4cba59df 100644 --- a/src/app/api/user/wallet/route.ts +++ b/src/app/api/user/wallet/route.ts @@ -9,17 +9,30 @@ async function getCodeId(): Promise { return verifyAccessToken(token); } +function isPrivyUser(codeId: string) { + return codeId.startsWith("privy:"); +} + export async function GET() { const codeId = await getCodeId(); if (!codeId) return NextResponse.json({ wallet: null }); const supabase = getSupabaseAdminClient(); + + if (isPrivyUser(codeId)) { + const { data } = await supabase + .from("users") + .select("wallet") + .eq("id", codeId) + .maybeSingle(); + return NextResponse.json({ wallet: data?.wallet ?? null }); + } + const { data } = await supabase .from("access_codes") .select("wallet") .eq("id", codeId) .maybeSingle(); - return NextResponse.json({ wallet: data?.wallet ?? null }); } @@ -35,10 +48,27 @@ export async function POST(request: Request) { } const supabase = getSupabaseAdminClient(); - await supabase - .from("access_codes") - .update({ wallet }) - .eq("id", codeId); + + if (isPrivyUser(codeId)) { + await supabase.from("users").update({ wallet }).eq("id", codeId); + } else { + await supabase.from("access_codes").update({ wallet }).eq("id", codeId); + } + + return NextResponse.json({ ok: true }); +} + +export async function DELETE() { + const codeId = await getCodeId(); + if (!codeId) return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + + const supabase = getSupabaseAdminClient(); + + if (isPrivyUser(codeId)) { + await supabase.from("users").update({ wallet: null }).eq("id", codeId); + } else { + await supabase.from("access_codes").update({ wallet: null }).eq("id", codeId); + } return NextResponse.json({ ok: true }); } diff --git a/src/app/dashboard/luca/page.tsx b/src/app/dashboard/luca/page.tsx index ecc7a113..ffe5dd82 100644 --- a/src/app/dashboard/luca/page.tsx +++ b/src/app/dashboard/luca/page.tsx @@ -165,7 +165,7 @@ function LucaChat() { } const showEmpty = messages.length === 0; - const isReady = Boolean(selectedSlug || wallet); + const isReady = true; const greeting = (() => { const h = new Date().getHours(); return h < 12 ? "Good morning" : h < 18 ? "Good afternoon" : "Good evening"; @@ -280,8 +280,7 @@ function LucaChat() { What should I read for you today?

- Luca answers from your agent's attributed books only — every figure carries its period and confidence, and missing data is called missing. - {!isReady && " Link your wallet or select an agent to get started."} + Luca answers from attributed books only — every figure carries its period and confidence, and missing data is called missing.

{/* Capability grid — 3-col, 6px radius (no pills) */} @@ -434,8 +433,8 @@ function LucaChat() {