| title | Frames Setup & Configuration | |||
|---|---|---|---|---|
| section | frames | |||
| slug | setup | |||
| tags |
|
|||
| weight | 1 | |||
| navOrder | 1 |
CASTQUEST V3 — Farcaster Frames Integration Guide
Frames are interactive Farcaster integrations that allow users to interact with CASTQUEST directly from their Farcaster feed. The frames feature is built into the web application.
Code Path: apps/web/app/frames/ (part of web application)
Frames are server-rendered HTML with specific meta tags that Farcaster clients render as interactive cards. CASTQUEST frames support:
- Quest Frames: Create and complete quests
- Mint Frames: Mint NFTs and tokens
- Marketplace Frames: Browse and purchase items
- Profile Frames: Display user profiles and stats
- Framework: Next.js API routes
- Rendering: Server-side rendering (SSR)
- Validation: Farcaster signature verification
- Storage: PostgreSQL for frame state
- Integration: Farcaster Hub API
- Web application setup (see Web App Setup)
- Farcaster account with developer access
- Farcaster Hub access (self-hosted or Neynar)
-
FARCASTER_APP_FID: Farcaster application FID (Farcaster ID)- Example:
12345 - Obtain from: https://www.farcaster.xyz/
- Used for: Frame authentication
- Example:
-
FARCASTER_APP_MNEMONIC: App mnemonic for signing- Format: 24-word BIP39 mnemonic
- CRITICAL: Keep secret, never commit
- Used for: Signing frame responses
-
FARCASTER_HUB_URL: Farcaster Hub URL- Default:
https://hub.farcaster.xyz - Alternative: Self-hosted hub or Neynar
- Default:
-
FARCASTER_API_KEY: API key for Farcaster services- Required if using hosted services
- Obtain from service provider
# In .env.local or .env.production
# Farcaster Configuration
FARCASTER_APP_FID=12345
FARCASTER_APP_MNEMONIC="word1 word2 word3 ... word24"
FARCASTER_HUB_URL=https://hub.farcaster.xyz
FARCASTER_API_KEY=fc_api_key_here- Go to https://www.farcaster.xyz/
- Create new application
- Note your FID (Farcaster ID)
- Generate app mnemonic
- Save credentials securely
Add Farcaster credentials to environment:
# Development
cp .env.local.example .env.local
# Edit .env.local and add Farcaster variables
# Production
# Add variables to hosting platform (Vercel, K8s secrets)Frame routes are in apps/web/app/frames/[type]/route.ts:
// Example: apps/web/app/frames/quest/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function GET(req: NextRequest) {
// Render frame HTML with meta tags
return new NextResponse(frameHtml, {
headers: { 'Content-Type': 'text/html' }
});
}
export async function POST(req: NextRequest) {
// Handle frame button click
const body = await req.json();
// Verify Farcaster signature
// Process action
// Return updated frame
}Test using Farcaster Frame Validator:
Frames are part of the web application:
# Development with hot reload
pnpm --filter @castquest/web dev
# Production build
pnpm --filter @castquest/web build
# Start production server
pnpm --filter @castquest/web startFrames are deployed as part of the web application:
- Development:
http://localhost:3000/frames/* - Production:
https://castquest.io/frames/*
-
Deploy Web App: Frames deploy with main web application
# Build and deploy pnpm --filter @castquest/web build vercel --prod -
Verify Frame URLs: Ensure frame routes are accessible
curl https://castquest.io/frames/quest/1
-
Test in Farcaster: Post frame URL to verify rendering
- Use Warpcast or other Farcaster client
- Verify interactive elements work
- Test all button actions
-
Monitor Performance: Track frame metrics
- View counts
- Interaction rates
- Error rates
- Load times
Optimize frame delivery:
- Enable CDN caching for static assets
- Set appropriate cache headers
- Use image optimization
- Compress responses
Register frames in Farcaster:
- Submit frame URL to Farcaster registry
- Verify ownership
- Monitor indexing status
Always verify Farcaster signatures on frame actions:
import { verifyFrameSignature } from '@/lib/farcaster';
export async function POST(req: NextRequest) {
const body = await req.json();
const isValid = await verifyFrameSignature(body);
if (!isValid) {
return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
}
// Process valid request
}- Store mnemonic in secrets manager (AWS Secrets Manager, Vault)
- Never log or expose mnemonic
- Use environment variables, not hardcoded values
- Rotate if compromised
Sanitize all user inputs in frames:
import { sanitize } from '@/lib/sanitize';
export async function POST(req: NextRequest) {
const body = await req.json();
// Sanitize inputs
const sanitizedInput = sanitize(body.inputText);
// Validate
if (!isValid(sanitizedInput)) {
return NextResponse.json({ error: 'Invalid input' }, { status: 400 });
}
}Configure CORS for frame endpoints:
export async function GET(req: NextRequest) {
return new NextResponse(html, {
headers: {
'Content-Type': 'text/html',
'Access-Control-Allow-Origin': 'https://warpcast.com',
'Access-Control-Allow-Methods': 'GET, POST',
}
});
}- Always verify signatures: Never trust unsigned frame actions
- Validate all inputs: Sanitize and validate user inputs
- Rate limit endpoints: Prevent abuse and spam
- Log security events: Monitor for suspicious activity
- Use HTTPS: Always use secure connections
- Keep secrets secure: Never expose mnemonics or keys
- Monitor frame abuse: Track and block malicious frames
Track frame interactions:
- View counts
- Button clicks
- Conversion rates
- Error rates
Monitor frame errors:
- Invalid signatures
- API failures
- Rendering errors
- Timeout issues
Optimize frame performance:
- Cache rendered frames (Redis)
- Optimize images (Next.js Image)
- Minimize response size
- Use CDN for assets
Create and complete quests via frames:
- Path:
/frames/quest/[id] - Actions: View, start, complete quest
- Data: Quest details, progress, rewards
Mint NFTs and tokens:
- Path:
/frames/mint/[id] - Actions: View, mint, verify
- Data: Mint details, pricing, eligibility
Browse marketplace items:
- Path:
/frames/marketplace/[id] - Actions: View, buy, offer
- Data: Item details, price, seller
Display user profiles:
- Path:
/frames/profile/[address] - Actions: View, follow, tip
- Data: Profile info, stats, tokens
"Frame not rendering"
- Check meta tags format
- Verify frame URL is accessible
- Test with Frame Validator
- Check Content-Type header
"Invalid signature"
- Verify FARCASTER_APP_MNEMONIC is correct
- Check signature verification logic
- Ensure Hub URL is accessible
"Hub connection failed"
- Verify FARCASTER_HUB_URL is correct
- Check network connectivity
- Try alternative Hub (Neynar)
- Frame Types - Supported frame types
- Frame Templates - Frame templates
- Farcaster Integration - Deep dive
- GitHub: https://github.com/CastQuest/cast/issues
- Docs: https://docs.castquest.io/frames
- Discord: https://discord.gg/castquest