A Next.js mini app demonstrating Base Verify integration for X (Twitter) verification and airdrop claiming. Users connect their wallet, verify their X account through Base Verify, and claim an airdrop.
- 🔐 Wallet Integration: Connect via Coinbase Wallet or other Web3 wallets using OnchainKit
- ✅ X (Twitter) Verification: Verify X accounts using Base Verify API
- Wallet Connection: User connects wallet via OnchainKit
- Signature Generation: App generates SIWE message with verification traits
- Base Verify Redirect: User redirects to Base Verify mini app with PKCE challenge
- X Verification: User verifies X account on Base Verify
- Callback: Base Verify redirects back with authorization code
- Token Exchange: App exchanges code for verification token
- Database Storage: Store wallet address + verification token (prevents reuse)
- Airdrop Claimed: Success confirmation
model VerifiedUser {
id String @id @default(cuid())
address String @unique // Wallet address
baseVerifyToken String? @unique // Verification token from Base Verify
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("verified_users")
}Key Constraints:
addressis unique (one claim per wallet)baseVerifyTokenis unique (prevents verification token reuse)
- POST
/api/verify-token: Verifies signature with Base Verify API and stores user - GET
/api/users: Fetches all verified users - POST
/api/delete-airdrop: Allows users to delete their claim (requires signature)
- Node.js 20+ and npm
- PostgreSQL database
- Coinbase Developer Platform account
- Base Verify API access (secret key)
npm installCreate a .env.local file in the root directory (see .env.example)
# Generate Prisma client
npm run db:generate
# Push schema to database (for development)
npm run db:push
# Or run migrations (for production)
npx prisma migrate deploynpm run devThe app will start on http://localhost:3003
To view/edit database records:
npm run db:studioThe app uses Sign-In with Ethereum (SIWE) messages with custom resources to communicate verification requirements:
// Example SIWE message structure
{
domain: "your-app.vercel.app",
address: "0x123...",
statement: "Sign in with X verification",
uri: "cbwallet://miniapp?url=https://your-app.vercel.app",
chainId: 8453, // Base mainnet
resources: [
"urn:verify:action:base_verify_token",
"urn:verify:provider:x",
"urn:verify:provider:x:verified:true"
]
}To improve UX, signatures are cached in localStorage for 5 minutes:
- Prevents repeated signature requests during verification flow
- Automatically cleared on address change or error
- Validates address and action match before reuse
The app implements PKCE (Proof Key for Code Exchange) for secure OAuth-like flow:
- Generate code verifier and challenge
- Store verifier in sessionStorage
- Redirect to Base Verify with challenge
- Exchange authorization code + verifier for token
Users can delete their own airdrop claim:
- Signs message:
"Delete airdrop for {address}" - Backend verifies signature using Viem (supports EOA & EIP-1271)
- Removes user from database