This application implements a secure Bitcoin wallet-based authentication system using cryptographic signatures and address whitelisting.
- Message Signing: Users must sign a challenge message with their Bitcoin private key
- Address Verification: Only whitelisted Bitcoin addresses can access the application
- Session Management: Secure server-side sessions with automatic expiration
- Route Protection: Middleware automatically protects all sensitive routes
- Whitelist Database: Authorized addresses stored securely in Supabase
- Challenge-Response: Unique challenge messages prevent replay attacks
- Server-Side Verification: All authentication logic runs on the server
- Secure Cookies: HttpOnly cookies prevent client-side manipulation
- Row Level Security: Database policies prevent unauthorized access
```
- User visits protected page
- Middleware redirects to /login
- User connects Bitcoin wallet (UniSat, Xverse, etc.)
- System generates unique challenge message
- User signs challenge with wallet private key
- Server verifies signature and checks whitelist
- If valid, creates secure session and redirects to app ```
Authorized addresses are stored in the whitelist table:
```sql CREATE TABLE whitelist ( id UUID PRIMARY KEY, bitcoin_address TEXT UNIQUE NOT NULL, label TEXT, is_active BOOLEAN DEFAULT true, created_at TIMESTAMP DEFAULT NOW() ); ```
The middleware automatically protects these routes:
/- Main PSBT builder interface/api/psbt/*- PSBT creation APIs/api/analyze-psbt- Transaction analysis- All other sensitive endpoints
Public routes (no authentication required):
/login- Authentication page/api/auth/*- Authentication endpoints
The following environment variables are automatically configured:
NEXT_PUBLIC_SUPABASE_URL- Supabase project URLSUPABASE_SERVICE_ROLE_KEY- Server-side Supabase keyNEXT_PUBLIC_SUPABASE_ANON_KEY- Client-side Supabase key
To add new authorized Bitcoin addresses, run this SQL in your Supabase dashboard:
```sql INSERT INTO whitelist (bitcoin_address, label) VALUES ('bc1qyour_address_here', 'Description of user'); ```
Or use the provided script:
```bash
npm run dev
```
- Unauthorized Access: Only whitelisted addresses can authenticate
- Session Hijacking: HttpOnly cookies prevent client-side access
- Replay Attacks: Unique challenge messages with timestamps
- Client-Side Bypass: All verification happens server-side
- Database Tampering: Row Level Security policies protect data
- Private Key Security: Users must keep their Bitcoin private keys secure
- Wallet Compatibility: Requires compatible Bitcoin wallet (UniSat, Xverse, OKX)
- Network Security: Use HTTPS in production
- Session Expiration: Sessions expire after 24 hours
- Address Management: Remove addresses from whitelist to revoke access
GET /api/auth/challenge- Generate challenge messagePOST /api/auth/verify- Verify signature and create sessionGET /api/auth/session- Check current session statusPOST /api/auth/logout- Clear session and logout
All PSBT and transaction APIs require authentication:
POST /api/psbt/create- Create new PSBTPOST /api/analyze-psbt- Analyze transaction metrics
-
Add your Bitcoin address to the whitelist: ```sql INSERT INTO whitelist (bitcoin_address, label) VALUES ('your_bitcoin_address', 'Development Testing'); ```
-
Connect your wallet and sign the challenge message
-
Access should be granted to the main application
Enable debug logging by checking the browser console and server logs:
[v0]prefixed messages show authentication flow- Check Network tab for API request/response details
- Verify cookies are set correctly in Application tab
- Update Whitelist: Replace example addresses with real authorized addresses
- Environment Variables: Ensure all Supabase variables are configured
- HTTPS: Enable HTTPS for secure cookie transmission
- Database Security: Review and test Row Level Security policies
- Session Security: Consider shorter session timeouts for high-security environments
"Address not authorized"
- Check if address is in whitelist table
- Verify
is_active = truefor the address
"Invalid signature"
- Ensure wallet is properly connected
- Try signing the message again
- Check wallet compatibility
"Session expired"
- Sessions expire after 24 hours
- Re-authenticate by visiting /login
Middleware redirect loops
- Check middleware configuration
- Verify public routes are properly excluded
- Clear browser cookies and try again