User dashboard for Smirk wallet users. Requires the Smirk browser extension to access.
This website serves as a hub for Smirk wallet users to:
- View their account UUID and balances
- See tipping history (sent and received)
- Register & verify social platform usernames (Telegram, Discord)
- Manage social tips - view sent/received, clawback unclaimed
- Public stats - platform growth metrics at /stats
Important: This site is ONLY accessible to users with the Smirk extension installed. Authentication happens via cryptographic signatures from the user's wallet keys.
The website is designed to be deployable either:
- Alongside the backend - Served from the same server as smirk-backend (current plan)
- Separately - As a standalone deployment (e.g., Vercel, separate server)
Keep this flexibility in mind when developing - avoid tight coupling to backend internals.
The Smirk extension injects a window.smirk API object into web pages. The website uses this to:
- Detect extension - Check if
window.smirkexists - Connect - Request user's public keys (with user approval)
- Sign - Request signatures for authentication challenges (BTC/LTC: ECDSA, XMR/WOW/Grin: Ed25519)
┌─────────────┐ window.smirk ┌─────────────────┐
│ Website │ ◄──────────────────► │ Smirk Extension │
└──────┬──────┘ └────────┬────────┘
│ │
│ POST /auth/verify │ User approves
│ { publicKeys, signatures } │ in popup
▼ ▼
┌─────────────┐ ┌─────────────────┐
│ Backend │ │ Extension UI │
└─────────────┘ └─────────────────┘
- User clicks "Connect with Smirk"
- Website calls
window.smirk.connect() - Extension shows approval popup
- User approves → Extension returns public keys for all 5 assets
- Website calls
POST /api/v1/auth/website/challengewith origin - Backend returns challenge message (with nonce + timestamp + origin)
- Website calls
window.smirk.signMessage(challenge) - Extension shows asset picker - user chooses favorite coin
- User signs → Extension returns signature from chosen asset
- Website sends
{ challenge_id, signature }toPOST /api/v1/auth/website/verify - Backend verifies signature, looks up user by pubkey_hash, issues JWT session
- Website stores JWT, user is now authenticated
- Framework: Next.js 14+ (App Router)
- Styling: Tailwind CSS
- State: React Context / Zustand (TBD)
- Auth: JWT sessions verified against backend
# Install dependencies
npm install
# Run development server
npm run dev
# Build for production
npm run build
# Start production server
npm start# Backend API URL
NEXT_PUBLIC_API_URL=http://localhost:3000
# For production
NEXT_PUBLIC_API_URL=https://api.smirk.cashsrc/
├── app/ # Next.js App Router pages
│ ├── page.tsx # Landing / Connect page
│ ├── dashboard/ # Protected dashboard routes
│ │ ├── page.tsx # Main dashboard (balances, UUID)
│ │ ├── history/ # Tip history
│ │ └── settings/ # Account settings
│ └── layout.tsx # Root layout
├── components/ # React components
│ ├── ConnectButton.tsx # "Connect with Smirk" button
│ ├── Dashboard/ # Dashboard components
│ └── ui/ # Shared UI components
├── lib/
│ ├── smirk.ts # window.smirk API wrapper
│ ├── auth.ts # Authentication utilities
│ └── api.ts # Backend API client
└── types/
└── smirk.d.ts # TypeScript types for window.smirk
- Challenge messages include timestamps to prevent replay attacks
- Signatures are verified server-side against registered public keys
- JWT tokens have reasonable expiration
- HTTPS required in production
- CSP headers to prevent XSS
- smirk-extension - Browser extension (injects
window.smirk) - smirk-backend - Rust backend API