diff --git a/prisma/migrations/20250912152754_add_walletaddress_to_user_model/migration.sql b/prisma/migrations/20250912152754_add_walletaddress_to_user_model/migration.sql new file mode 100644 index 0000000..0c2ddb7 --- /dev/null +++ b/prisma/migrations/20250912152754_add_walletaddress_to_user_model/migration.sql @@ -0,0 +1,11 @@ +/* + Warnings: + + - A unique constraint covering the columns `[walletAddress]` on the table `User` will be added. If there are existing duplicate values, this will fail. + +*/ +-- AlterTable +ALTER TABLE "public"."User" ADD COLUMN "walletAddress" TEXT; + +-- CreateIndex +CREATE UNIQUE INDEX "User_walletAddress_key" ON "public"."User"("walletAddress"); diff --git a/prisma/migrations/20250912153358_update_user_model_email/migration.sql b/prisma/migrations/20250912153358_update_user_model_email/migration.sql new file mode 100644 index 0000000..9c40c31 --- /dev/null +++ b/prisma/migrations/20250912153358_update_user_model_email/migration.sql @@ -0,0 +1,2 @@ +-- AlterTable +ALTER TABLE "public"."User" ALTER COLUMN "email" DROP NOT NULL; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 24d14a3..87539ef 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -15,7 +15,8 @@ datasource db { model User { id String @id @default(uuid()) - email String @unique + walletAddress String? @unique + email String? @unique name String? password String? role Role @default(USER) diff --git a/src/components/LoginForm.tsx b/src/components/LoginForm.tsx index 74f863c..dea1baa 100644 --- a/src/components/LoginForm.tsx +++ b/src/components/LoginForm.tsx @@ -13,6 +13,7 @@ import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import GoogleSignInButton from "@/components/GoogleSignInButton"; import { ConnectButton } from "@rainbow-me/rainbowkit"; +import WalletConnectButton from "./walletconnectbutton"; export default function LoginForm() { const [email, setEmail] = useState(""); @@ -42,7 +43,7 @@ export default function LoginForm() {
- +
diff --git a/src/components/walletconnectbutton.tsx b/src/components/walletconnectbutton.tsx new file mode 100644 index 0000000..1b9e476 --- /dev/null +++ b/src/components/walletconnectbutton.tsx @@ -0,0 +1,24 @@ +"use client"; +import { addUser } from "@/lib/action"; +import { ConnectButton } from "@rainbow-me/rainbowkit"; +import { useEffect } from "react"; +import { useAccount } from "wagmi"; + +export default function WalletConnectButton() { + + const {address, isConnected} = useAccount(); + + useEffect(()=>{ + if(isConnected && address){ + addUser(address) + .then((user)=> + console.log("User added/login",user)) + .catch((err)=>{ + console.error("Error adding user", err); + }) + } + }, + [address, isConnected]); + + return ; +} diff --git a/src/lib/action.ts b/src/lib/action.ts new file mode 100644 index 0000000..6266a12 --- /dev/null +++ b/src/lib/action.ts @@ -0,0 +1,66 @@ +"use server"; +import { prisma } from "./prisma"; + + +export async function addUser(address: string, email?: string) { + + const normalizedAddress = address ? address.trim().toLowerCase() : undefined; + if (!normalizedAddress && !email) { + throw new Error("Must provide wallet address or email"); + } + + const selectSafe = { + id: true, + email: true, + walletAddress: true, + role: true, + name: true, + image: true, + subscriptionType: true, + createdAt: true, + updatedAt: true, + lastLoginAt: true, + isActive: true, + } as const; + + // Prefer wallet path when available (idempotent via upsert) + if (normalizedAddress) { + try { + const user = await prisma.user.upsert({ + where: { walletAddress: normalizedAddress }, + update: { lastLoginAt: new Date() }, + create: { + walletAddress: normalizedAddress, + email: email ?? null, + lastLoginAt: new Date(), + }, + select: selectSafe, + }); + // Optionally link email if provided and not set yet + if (email && !user.email) { + return await prisma.user.update({ + where: { id: user.id }, + data: { email }, + select: selectSafe, + }); + } + return user; + } catch (e) { + // Handle race: if unique constraint hit, re-fetch + const existing = await prisma.user.findUnique({ + where: { walletAddress: normalizedAddress }, + select: selectSafe, + }); + if (existing) return existing; + throw e; + } + } + + // Email-only path (idempotent) + return prisma.user.upsert({ + where: { email: email as string }, + update: { lastLoginAt: new Date() }, + create: { email: email as string }, + select: selectSafe, + }); +} \ No newline at end of file