BlockMafia
Multiplayer Mafia game with ETH prizes.
Created on 10th January 2026
โข
BlockMafia
Multiplayer Mafia game with ETH prizes.
The problem BlockMafia solves
๐ญ PrizeMafia - Farcaster Frame
Multiplayer Mafia game with ETH prizes, built as a Farcaster Frame on Base L2.
๐ฎ Game Overview
- 9 Players: Exactly 9 players per game
- Entry Fee: 0.001 ETH (testnet)
- Roles: 2 Mafia, 1 Doctor, 1 God, 5 Villagers
- Duration: 3 rounds max, ~15 minutes
- Platform: Farcaster Frames (no app needed!)
๐๏ธ Architecture
- Frontend: Next.js + Farcaster Frames
- Backend: Next.js API routes + Redis state
- Blockchain: Base Sepolia testnet
- Wallet: Privy embedded wallets
- Images: @vercel/og dynamic generation
๐ Quick Start
1. Clone and Install
git clone <your-repo>
cd prizemafia-frame
npm install
2. Environment Setup
cp .env.example .env.local
# Fill in your API keys:
# - NEYNAR_API_KEY (Farcaster)
# - UPSTASH_REDIS_URL & TOKEN (Redis)
# - ALCHEMY_BASE_KEY (Base network)
# - PRIVY_APP_ID & SECRET (Wallets)
# - PRIVATE_KEY (Deployer wallet)
3. Deploy Smart Contract
# Compile contract
npm run hardhat:compile
# Deploy to Base Sepolia
npm run hardhat:deploy
# Update .env.local with contract address
4. Run Development Server
npm run dev
5. Test Your Frame
- Use Frame Ground to test locally
- Share frame URL in Warpcast to test live
๐ Project Structure
src/
โโโ app/api/
โ โโโ frame/ # Frame endpoints
โ โโโ og/ # Image generation
โ โโโ cron/ # Timer jobs
โโโ lib/
โ โโโ game-engine.ts # Game logic
โ โโโ redis.ts # State management
โ โโโ frame-utils.ts # Frame helpers
โ โโโ types.ts # TypeScript types
โโโ contracts/
โ โโโ SimpleMafiaEscrow.sol
โโโ scripts/
โโโ deploy.ts
๐ฏ Game Flow
- Create/Join: Host creates game, players join via frame
- Payment: Players pay 0.001 ETH entry fee (embedded wallet)
- Start: Game starts when 9 players joined
- Roles: Secret roles assigned via private DMs
- Day Phase: 5min discussion, vote to eliminate
- Night Phase: Mafia kills, Doctor saves
- Win: Mafia wins if they equal villagers, else villagers win
๐ง API Endpoints
Frame Routes
GET/POST /api/frame- Main landingPOST /api/frame/create- Create gamePOST /api/frame/join- Join gamePOST /api/frame/lobby- Lobby statePOST /api/frame/start- Start gamePOST /api/frame/game- Game state
Image Generation
GET /api/og?type=landing- Landing imageGET /api/og?type=lobby&gameId=X&playerCount=5- LobbyGET /api/og?type=game&phase=day&round=1&userRole=mafia- Game
๐ ๏ธ Development Commands
# Development
npm run dev # Start dev server
npm run build # Build for production
npm run typecheck # TypeScript check
# Smart Contracts
npm run hardhat:compile # Compile contracts
npm run hardhat:test # Run tests
npm run hardhat:deploy # Deploy to testnet
๐จ Important Notes
Testnet Only
This is built for Base Sepolia testnet with 0.001 ETH entry fees. DO NOT use on mainnet without proper audits and legal review.
Legal Compliance
Online gaming with real money requires legal compliance in many jurisdictions. Consult legal counsel before accepting real ETH.
Built with โค๏ธ by Deb
Ready to play? Share the frame in Warpcast and let the games begin! ๐ญ
Challenges I ran into
Challenges I Ran Into
Building PrizeMafia as a Farcaster Frame involved integrating real-time multiplayer logic with blockchain payments, which led to several hurdles. Here are the key ones and how I overcame them:
1. Managing Real-Time Game State Across Players
Hurdle: Farcaster Frames are stateless by design, making it tricky to synchronize game phases (e.g., day/night cycles) and player actions in real-time for 9 players. Initial attempts using only API routes caused race conditions where votes or role assignments overlapped, leading to inconsistent game states.
Solution: I implemented Redis for persistent state management, storing game data with TTL (time-to-live) for automatic cleanup. This allowed atomic updates via Redis transactions, ensuring thread-safe operations. I also added cron jobs to handle phase transitions, tested thoroughly with mock players to simulate concurrency.
2. Integrating Embedded Wallets for ETH Payments
Hurdle: Using Privy for embedded wallets worked well for seamless payments, but on Base Sepolia testnet, transaction confirmations were slow, causing UI freezes during the 0.001 ETH entry fee process. Players sometimes saw "pending" states indefinitely, disrupting the lobby flow.
Solution: I polled the blockchain using Alchemy's API for transaction receipts, with exponential backoff to avoid rate limits. Added client-side loading indicators and error handling for failed txns, redirecting users to retry. Extensive testing on testnet with multiple wallets ensured reliability.
3. Dynamic Image Generation for Frames
Hurdle: Generating OG images with @vercel/og for lobby and game states was complex, especially for personalized content like player roles sent via DMs. Early versions had rendering issues on mobile Farcaster clients, with images not updating dynamically based on query params.
Solution: I refactored the API to use conditional rendering in the OG endpoint, caching images in Vercel for performance. Debugged by logging params and testing on Frame Ground, ensuring compatibility across devices. This improved load times and visual consistency.
These challenges pushed me to deepen my knowledge of serverless architectures and blockchain integrations, ultimately making the app more robust. All issues were resolved through iterative testing, documentation reviews, and community forums like Farcaster dev channels.
Tracks Applied (1)
