As your experienced web developer, I have implemented the complete Stellar wallet authentication system. Here's how to proceed.
✅ Backend Authentication System
- JWT token generation and validation
- Stellar signature verification
- Nonce-based replay protection
- Session management
- Authentication middleware
✅ Frontend Integration
- Wallet connection with signature signing
- JWT token storage and management
- Protected API integration
- Session persistence
✅ Database Schema
- Users table for wallet management
- Auth sessions table for token management
- Login nonces table for replay protection
✅ API Endpoints
POST /api/auth/nonce- Get nonce for signingPOST /api/auth/verify- Verify signature and get JWTPOST /api/auth/logout- Logout and invalidate sessionPOST /api/snippets- Create snippets (now requires auth)
1. Create .env.local file:
# In root directory, create or edit .env.local2. Add these environment variables:
# Database URL (from NeonDB)
DATABASE_URL="postgresql://user:password@host/database?sslmode=require"
# Generate secure JWT secret:
JWT_SECRET="<paste-output-of-command-below>"
# Stellar network
NEXT_PUBLIC_STELLAR_NETWORK="testnet"3. Generate JWT_SECRET in terminal:
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Copy the output and paste into .env.local as JWT_SECRET value4. Apply database migration:
-- Connect to your NeonDB database
-- Copy entire contents of: scripts/add-auth-tables.sql
-- Paste and execute in NeonDB SQL editor# Terminal 1: Start development server
npm run dev
# You should see:
# ▲ Next.js X.X.X (ready - started server on 0.0.0.0:3000)- Open http://localhost:3000 in browser
- Look for "Connect Wallet" button in navbar
- No console errors should appear
✅ If you see the button, you're ready to test!
📖 Open: TESTING_GUIDE.md in your project
Follow: 8 Step-by-Step Tests
- Each test takes 2-5 minutes
- Total time: 30-45 minutes
- All tests provided with expected results
✅ When all tests pass: Implementation is verified!
| File | Purpose | When to Use |
|---|---|---|
| TESTING_GUIDE.md | 8-step testing procedure | START HERE - Run all tests |
| IMPLEMENTATION_SUMMARY.md | Overview of what was built | Understand the implementation |
| AUTHENTICATION_GUIDE.md | Complete technical reference | Troubleshooting, deeper understanding |
| IMPLEMENTATION_CHECKLIST.md | Detailed acceptance criteria | Verify all requirements met |
| .env.example | Environment setup instructions | Setting up variables |
The 8 tests verify:
- ✅ Wallet Connection - Can connect and get public key
- ✅ Signature Verification - Server validates signature
- ✅ JWT Generation - Valid JWT token created
- ✅ Replay Protection - Nonce can't be used twice
- ✅ Protected Routes - API requires authentication
- ✅ Session Persistence - Stays logged in after refresh
- ✅ Logout - Clears all session data
- ✅ Error Handling - Invalid requests rejected properly
1. Install Freighter: https://www.freighter.app/
2. Refresh page
3. Try again
1. Check DATABASE_URL is correct in .env.local
2. Verify NeonDB credentials
3. Ensure ?sslmode=require is in URL
4. Test connection in NeonDB dashboard
1. Verify .env.local has JWT_SECRET
2. Generated value from: node -e "console.log(...)"
3. Restart dev server: npm run dev
1. Connect wallet first
2. Check browser console: localStorage.getItem('authToken')
3. Should return a JWT token
4. If empty, reconnect wallet
1. Click "Connect Wallet"
2. Select wallet (Freighter/Albedo)
3. Approve wallet connection
4. Sign nonce with wallet
5. Redirected with JWT token
6. Address shown in navbar
7. Can now create snippets
8. Address persists after refresh
9. Click address to disconnect
Frontend Backend Database
| | |
|--Get Nonce---------->| |
|<--Nonce returned-----| |
| |--Create nonce--------->|
| |<--Stored in DB---------|
| | |
|--Send Signature----->| |
| |--Verify signature |
| |--Check nonce--------->|
| |<--Nonce exists--------|
| |--Create JWT token |
| |--Store session------->|
|<--JWT Token---------| |
| |--Mark nonce used----->|
| | |
[Stores JWT in localStorage]
| | |
|--Create Snippet----->| |
| [Auth: Bearer JWT] |--Verify JWT |
| |--Check session------->|
| |<--Session valid--------|
| |--Create snippet------->|
| |<--Snippet created-----|
|<--Snippet Created----| |
- ✅ Wallets sign messages (never share private keys)
- ✅ Only public keys stored on server
- ✅ JWT tokens cryptographically signed
- ✅ Replay protection with single-use nonces
- ✅ Sessions expire after 7 days
- ✅ Tokens hashed before storage
Complete these in order:
- 1. Set up
.env.localwith 3 variables - 2. Run database migration script
- 3. Start dev server:
npm run dev - 4. Open http://localhost:3000
- 5. See "Connect Wallet" button
- 6. Open
TESTING_GUIDE.md - 7. Run Test 1: Basic Wallet Connection
- 8. Run Test 2: Signature Verification
- 9. Run Test 3: JWT Token Validation
- 10. Run Test 4: Replay Protection
- 11. Run Test 5: Protected Routes
- 12. Run Test 6: Session Persistence
- 13. Run Test 7: Logout
- 14. Run Test 8: Error Handling
When all ✅ checked: Implementation verified!
- Cryptographically signed token
- Contains wallet address
- Expires after 7 days
- Sent with every API request in
Authorizationheader
- One-time random string
- Prevents replay attacks
- Valid for 15 minutes
- Can only be used once
- Wallet signs nonce with private key
- Server verifies signature with public key
- Proves user owns the wallet
- Private key never leaves wallet
- JWT token + user info stored in database
- Can be invalidated on logout
- Linked to wallet address
- Expires automatically
- For testing issues: See
TESTING_GUIDE.md→ Troubleshooting section - For technical details: See
AUTHENTICATION_GUIDE.md - For requirements: See
IMPLEMENTATION_CHECKLIST.md - For setup help: See
.env.example
Next Step: Open TESTING_GUIDE.md and begin testing!
You've got this! 💪