diff --git a/TODO.md b/TODO.md index 63fbcb0..a468ce7 100644 --- a/TODO.md +++ b/TODO.md @@ -1,84 +1,99 @@ # Smirk Website TODO -## Phase 1: Foundation (Critical Path) +See [smirk-backend/docs/SOCIAL_TIPPING.md](../smirk-backend/docs/SOCIAL_TIPPING.md) for full architecture. + +## Completed ### Extension API (DONE - 2026-01-22) -- [x] **Inject `window.smirk` API** - Content script injects API object into pages -- [x] **`window.smirk.connect()`** - Returns public keys for all 5 assets -- [x] **`window.smirk.signMessage(message)`** - Signs message with all 5 asset keys -- [x] **`window.smirk.isConnected()`** - Check if site is connected -- [x] **`window.smirk.disconnect()`** - Revoke site access -- [x] **`window.smirk.getPublicKeys()`** - Get public keys if already connected -- [x] **Approval popup UI** - Show user what site is requesting, allow approve/deny -- [x] **Origin allowlist** - Track which origins user has approved (persisted to storage) +- [x] Inject `window.smirk` API - Content script injects API object into pages +- [x] `window.smirk.connect()` - Returns public keys for all 5 assets +- [x] `window.smirk.signMessage(message)` - Signs message with user's chosen asset +- [x] `window.smirk.isConnected()` - Check if site is connected +- [x] `window.smirk.disconnect()` - Revoke site access +- [x] `window.smirk.getPublicKeys()` - Get public keys if already connected +- [x] Approval popup UI - Show user what site is requesting, allow approve/deny +- [x] Origin allowlist - Track which origins user has approved ### Backend Auth Endpoints (DONE - 2026-01-24) - [x] `POST /api/v1/auth/website/challenge` - Generate challenge with nonce + origin -- [x] `POST /api/v1/auth/website/verify` - Verify signatures, issue JWT session token +- [x] `POST /api/v1/auth/website/verify` - Verify signature, issue JWT session token - [x] `GET /api/v1/auth/me` - Get current user info from JWT -- [ ] JWT middleware for protected routes (frontend side) +- [x] Single-asset authentication - User picks favorite coin to sign with -### Website Basics -- [ ] Initialize Next.js project with App Router -- [ ] Tailwind CSS setup -- [ ] Basic layout (header, footer) -- [ ] Landing page with "Connect with Smirk" button -- [ ] Extension detection (`window.smirk` check) -- [ ] "Install Smirk" fallback if extension not detected +### Website Foundation (DONE - 2026-01-25) +- [x] Next.js 16 project with App Router +- [x] Tailwind CSS setup +- [x] Landing page with connect button +- [x] Extension detection (`window.smirk` check) +- [x] Authentication flow (connect → choose coin → sign → logged in) +- [x] JWT storage in localStorage +- [x] Logout functionality + +### Linked Accounts (DONE - 2026-01-26) +- [x] Settings page at `/settings` +- [x] List currently linked platforms +- [x] "Link Telegram" button → verification flow +- [x] Verification UI: enter username → get code → send to bot → confirm +- [x] Unlink platform button + +--- ## Phase 2: Core Dashboard -### Authentication Flow -- [ ] Connect button triggers `window.smirk.connect()` -- [ ] Challenge generation and signing -- [ ] Backend verification and JWT storage -- [ ] Protected route middleware -- [ ] Logout functionality - -### Dashboard - Basic +### Dashboard Home - [ ] Display user UUID -- [ ] Display balances for all 5 assets -- [ ] Auto-refresh balances -- [ ] Loading states and error handling +- [ ] Display balances for all 5 assets (fetched via backend) +- [ ] Auto-refresh balances (polling or WebSocket) +- [ ] Loading skeletons and error states -### Dashboard - Tip History -- [ ] List of tips sent +### Tip History (Basic) +- [ ] List of tips sent (existing tip_links) - [ ] List of tips received - [ ] Pagination - [ ] Filter by asset type - [ ] Click to view tip details -## Phase 3: Account Management +## Phase 3: Social Tipping Dashboard -### Connected Accounts -- [ ] Link Telegram account -- [ ] Link Discord account -- [ ] Link other platforms (Twitter/X, etc.) -- [ ] Manage/unlink accounts -- [ ] Display linked accounts on dashboard +### Tips Sent (`/tips/sent`) +- [ ] List social tips with status (pending/claimed/clawed-back) +- [ ] Filter by platform (Telegram/Discord/direct) +- [ ] Clawback button (enabled anytime for unclaimed tips) +- [ ] Confirmation modal for clawback +- [ ] "Resend notification" option -### Settings -- [ ] Notification preferences -- [ ] Privacy settings -- [ ] Export account data +### Tips Received (`/tips/received`) +- [ ] List tips received (claimed and pending) +- [ ] Claim pending tips (verify platform ownership first) +- [ ] Link to transaction on blockchain explorer -## Phase 4: Social Features (Future) +### Public Tips (`/tips/public`) - Phase 2 +- [ ] View public tips sent by user +- [ ] Claim status tracking +- [ ] Share link/payload copy button + +## Phase 5: Additional Platforms + +- [ ] Discord linking flow +- [ ] Signal linking flow (future) +- [ ] Simplex linking flow (future) +- [ ] Matrix linking flow (future) + +## Phase 6: Social Features (Future) ### Direct Tipping - [ ] Send tip to another Smirk user by UUID -- [ ] Send tip via username/handle +- [ ] Send tip via username/handle (from website) - [ ] Tip confirmation flow -- [ ] Tip notifications ### Messaging (Future) - [ ] Direct messages between users -- [ ] Encrypted messaging (E2E?) -- [ ] Message notifications +- [ ] Encrypted messaging (E2E) ### Discovery (Future) - [ ] Public profiles (opt-in) - [ ] Search users -- [ ] Leaderboards? +- [ ] Tipping leaderboards (opt-in) ## Technical Debt / Polish @@ -104,41 +119,20 @@ ## Notes -### Extension Work Required (add to smirk-extension/TODO.md) +### Signing Algorithm Reference -The website cannot function without these extension features: - -1. **Content script injection** - Must inject `window.smirk` on all pages (or configurable origins) -2. **Message passing** - Content script ↔ Background script communication -3. **Approval UI** - Popup for connect/sign requests -4. **Security** - Origin tracking, user approval persistence - -### Signing Algorithm Notes - -For message signing (all implemented in extension): -- **BTC/LTC**: ECDSA signature (secp256k1) with Bitcoin message signing format -- **XMR/WOW**: Ed25519 signature using private spend key -- **Grin**: Ed25519 signature using slatepack key - -Backend must implement verification for all signature types. +For message signing (implemented in extension, verified by backend): +- **BTC/LTC**: ECDSA (secp256k1) with Bitcoin message signing format +- **XMR/WOW**: Ed25519 using private spend key +- **Grin**: Ed25519 using slatepack key ### Challenge Message Format ``` -Sign this message to authenticate with smirk.cash - -Timestamp: 2026-01-22T12:00:00Z +Smirk Authentication Challenge Nonce: abc123... -Origin: https://smirk.cash +Origin: https://smirk.to +Timestamp: 1706000000 ``` -Challenge should expire after ~5 minutes to prevent replay attacks. - -### Single-Asset Authentication (DONE - 2026-01-25) - -User picks their favorite coin to sign with: -- Simpler UX - choose one coin, sign once -- User data - "What's your favorite coin?" insight -- Any of the 5 coins proves wallet ownership - -This positions Smirk as infrastructure for wallet-based authentication across multiple cryptocurrencies. +Challenge expires after 5 minutes. diff --git a/src/app/page.tsx b/src/app/page.tsx index cc38d6e..5faf20a 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -2,6 +2,7 @@ import { useState, useEffect } from 'react'; import Image from 'next/image'; +import Link from 'next/link'; import { getChallenge, verifySignature, type AuthResponse } from '@/lib/api'; type Asset = 'btc' | 'ltc' | 'xmr' | 'wow' | 'grin'; @@ -220,13 +221,22 @@ export default function Home() { )} - +
Please sign in first
+ + Go to home + +{error}
+User ID
+{user.id}
+Telegram
+ {telegramSocial?.verified ? ( +@{telegramSocial.username}
+ ) : telegramSocial?.pending_verification ? ( +Pending: @{telegramSocial.username}
+ ) : ( +Not linked
+ )} +{linkError}
} +Your verification code:
+{verificationCode}
+/verify {verificationCode}{linkError}
} +{platform}
+Coming soon
+