This implementation allows users to post natively to Farcaster from Dragverse without using Neynar's paid service.
- Encrypted Storage: Signer private keys are encrypted using AES-256-GCM before storage
- Environment Key: Master encryption key stored in
FARCASTER_SIGNER_ENCRYPTION_KEY - Row-Level Security: Database policies prevent unauthorized access
- No Third-Party: Direct integration with Farcaster protocol (no Neynar required)
Run this command to generate a secure 256-bit encryption key:
openssl rand -hex 32Add to .env.local:
# Farcaster Native Posting
FARCASTER_SIGNER_ENCRYPTION_KEY=<your-generated-key>
# Optional: Custom Farcaster hub (default: nemes.farcaster.xyz:2283)
# FARCASTER_HUB_URL=your-hub-url:portRun the SQL migration to create the farcaster_signers table:
-- Located in: supabase-migrations/farcaster_signers.sqlExecute in Supabase SQL Editor or via migration tool.
- User connects Farcaster account (via Privy) → Gets FID
- User clicks "Enable Native Posting" in settings
- System generates Ed25519 signer key pair
- Private key encrypted and stored in database
- User shown QR code / deeplink to approve signer in Warpcast
- User opens Warpcast and approves the signer
- System polls for approval status
- Once approved, user can post natively to Farcaster
When user creates a post with Farcaster enabled:
- System retrieves encrypted signer from database
- Decrypts private key in-memory
- Signs cast message with Ed25519 signature
- Broadcasts to Farcaster hub
- Returns cast hash on success
POST /api/farcaster/signer/create
Authorization: Bearer <privy-jwt>
Response:
{
"success": true,
"publicKey": "0x...",
"approvalUrl": "https://client.warpcast.com/...",
"fid": 12345
}GET /api/farcaster/signer/status
Authorization: Bearer <privy-jwt>
Response:
{
"approved": true,
"fid": 12345,
"publicKey": "0x...",
"message": "Signer is approved and ready for posting"
}✅ Safe Practices:
- Private keys never exposed in API responses
- Encryption key stored in environment (not in code)
- Database uses RLS policies
- Keys encrypted at rest
- Decryption only happens in server-side code
- Never commit
FARCASTER_SIGNER_ENCRYPTION_KEYto version control - Rotate encryption key if compromised (requires re-generating all signers)
- Backup encryption key securely (users can't recover signers without it)
- Check
FARCASTER_SIGNER_ENCRYPTION_KEYis set correctly - Verify key is 64 hex characters (32 bytes)
- Ensure same key used for encryption/decryption
- User must approve signer in Warpcast app first
- Check signer registration via
/api/farcaster/signer/status - Try re-creating signer if approval fails
- Check Farcaster hub connectivity (
nemes.farcaster.xyz:2283) - Verify user's FID is valid
- Ensure signer is properly registered
| Method | Cost | Native Posting | Setup Complexity |
|---|---|---|---|
| Warpcast Redirect (old) | FREE | ❌ No | ⭐ Easy |
| Custom Signers (current) | FREE | ✅ Yes | ⭐⭐⭐ Medium |
| Neynar | $20-50/mo | ✅ Yes | ⭐⭐ Easy |
src/lib/farcaster/encryption.ts- AES-256-GCM encryption utilitiessrc/lib/farcaster/signer.ts- Signer generation, storage, and castingsrc/lib/crosspost/farcaster.ts- Native posting implementationsrc/app/api/farcaster/signer/create/route.ts- Signer creation endpointsrc/app/api/farcaster/signer/status/route.ts- Status check endpointsupabase-migrations/farcaster_signers.sql- Database schema
- Add UI for signer setup in settings page
- Implement QR code display for Warpcast approval
- Add signer status polling on frontend
- Handle signer expiration/rotation
- Add analytics for native posting success rate