diff --git a/.gitignore b/.gitignore index 5ef6a52..b721bff 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ yarn-error.log* # env files (can opt-in for committing if needed) .env* +!.env.local.example # vercel .vercel diff --git a/README.md b/README.md index 78f2171..38c590c 100644 --- a/README.md +++ b/README.md @@ -52,14 +52,12 @@ The Smirk extension injects a `window.smirk` API object into web pages. The webs 5. Website calls `POST /api/v1/auth/website/challenge` with origin 6. Backend returns challenge message (with nonce + timestamp + origin) 7. Website calls `window.smirk.signMessage(challenge)` -8. Extension shows signing popup with the message -9. User approves → Extension returns signatures from all 5 keys -10. Website sends `{ challenge_id, signatures }` to `POST /api/v1/auth/website/verify` -11. Backend verifies signatures, looks up user by BTC pubkey_hash, issues JWT session +8. Extension shows asset picker - user chooses favorite coin +9. User signs → Extension returns signature from chosen asset +10. Website sends `{ challenge_id, signature }` to `POST /api/v1/auth/website/verify` +11. Backend verifies signature, looks up user by pubkey_hash, issues JWT session 12. Website stores JWT, user is now authenticated -**Future**: Allow single-asset auth (user picks their favorite coin to sign with). - ### Tech Stack - **Framework**: Next.js 14+ (App Router) diff --git a/TODO.md b/TODO.md index d3cc609..63fbcb0 100644 --- a/TODO.md +++ b/TODO.md @@ -134,14 +134,11 @@ Origin: https://smirk.cash Challenge should expire after ~5 minutes to prevent replay attacks. -### Single-Asset Authentication (Future Enhancement) +### Single-Asset Authentication (DONE - 2026-01-25) -**Current implementation**: Backend requires signatures from all 5 asset keys. +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 -**Better approach**: Let users pick their favorite coin to sign with. Benefits: -1. **Simpler UX** - User chooses one coin, signs once -2. **User data** - "What's your favorite coin?" gives us insight into our user base -3. **Proof of concept** - Demonstrates wallet-based auth for ANY of these 5 coins -4. **Still secure** - We already know all 5 pubkeys; signing with ANY one proves wallet ownership - -This positions Smirk as infrastructure for wallet-based authentication across multiple cryptocurrencies. Other websites could use the same pattern - "Sign in with Bitcoin/Litecoin/Monero/Wownero/Grin". +This positions Smirk as infrastructure for wallet-based authentication across multiple cryptocurrencies. diff --git a/src/app/globals.css b/src/app/globals.css index a93bec2..0235929 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,5 +1,13 @@ @import "tailwindcss"; +@font-face { + font-family: 'Creepster'; + src: url('/fonts/Creepster-Regular.ttf') format('truetype'); + font-weight: normal; + font-style: normal; + font-display: swap; +} + :root { --background: #0a0a0a; --foreground: #ededed; @@ -73,3 +81,13 @@ body { font-weight: 500; text-transform: uppercase; } + +/* Creepster text styling */ +.creepster-text { + font-family: 'Creepster', cursive; + color: #fbeb0a; + text-shadow: + 0 0 10px rgba(251, 235, 10, 0.6), + 0 0 20px rgba(251, 235, 10, 0.4), + 0 0 30px rgba(251, 235, 10, 0.2); +} diff --git a/src/app/page.tsx b/src/app/page.tsx index f2b88b5..cc38d6e 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -60,14 +60,17 @@ export default function Home() { const challenge = await getChallenge(window.location.origin); // Sign with the selected coin - const signatures = await window.smirk.signMessage(challenge.challenge); - const sig = signatures[coin]; + const result = await window.smirk.signMessage(challenge.challenge); + const sig = result.signatures.find((s) => s.asset === coin); + if (!sig) { + throw new Error(`No signature found for ${coin}`); + } // Verify with backend const auth = await verifySignature(challenge.challenge_id, { asset: coin, signature: sig.signature, - public_key: sig.public_key, + public_key: sig.publicKey, }); // Store token and show logged in @@ -101,14 +104,18 @@ export default function Home() { return (
smirk.ca$h