A free-to-play decentralized Rock Paper Scissors game with AI and multiplayer modes. Multi-chain support (Celo + Base). Built with scaffold-eth-2.
Available on Farcaster at: https://farcaster.xyz/miniapps/e7MMsOYu-YxM/rps-onchain
- Wallet Authentication: Reown AppKit + Wagmi integration
- Free to Play: No betting, just pure fun
- Single Player: Play against AI instantly
- Multiplayer: Create/join rooms with 6-character codes
- Unlimited Rematches: Play again and again with friends
- Match History: Persistent storage via Turso + IPFS backup
- Blockchain Verification: Optional on-chain match publishing
- On-Chain Matches: View all published matches with filters
- Gaming UI: Neon aesthetics with smooth animations
- Stats Tracking: Win/loss records stored in Turso database
- PWA Support: Install as mobile app with offline capabilities
packages/
โโโ hardhat/ # Smart contracts & deployment
โ โโโ contracts/ # Solidity contracts (RPSOnline.sol)
โ โโโ deploy/ # Deployment scripts
โ โโโ scripts/ # Utility scripts
โโโ nextjs/ # Frontend application
โโโ app/ # Next.js 13+ app directory
โ โโโ game/ # Game interface pages
โ โโโ history/ # Match history page
โ โโโ play/ # Room creation/joining
โ โโโ api/ # Backend API routes
โโโ components/ # React components (Header)
โโโ hooks/ # Custom hooks (useRPSContract)
โโโ lib/ # Storage utilities
โโโ utils/ # Game utilities (hashing, moves)
- Node.js 18+
- Yarn or pnpm
-
Install dependencies
yarn install
-
Start local blockchain
yarn chain
Keep this terminal open - it runs your local Hardhat network.
-
Deploy contracts (in a new terminal)
yarn deploy
This deploys the RPSOnline contract to your local network.
-
Start frontend (in a new terminal)
yarn start
Frontend runs on
http://localhost:3000
- Connect Wallet: Use any wallet (MetaMask recommended)
- Choose Mode: Single Player (AI) or Multiplayer (Free)
- Create Room: Generate 6-character room code
- Share Code: Give the room code to your opponent
- Join Room: Enter room code to join
- Choose Move: Select rock, paper, or scissors
- See Results: Winner determined instantly
- Play Again: Request rematch for unlimited games
- Cancel Room: Room creators can cancel unjoined rooms
- Leave Room: Exit after game finishes
- Rematch System: Request/accept rematches instantly
- Rock beats Scissors
- Scissors beats Paper
- Paper beats Rock
- Same moves = Tie
- All games are free
- Stats tracked on IPFS
- Unlimited rematches available
# Blockchain
yarn chain # Start local Hardhat network
yarn deploy # Deploy contracts to local network
yarn deploy --network celo # Deploy to Celo mainnet
yarn deploy --network base # Deploy to Base mainnet
# Frontend
yarn start # Start Next.js development server
yarn build # Build for production
yarn lint # Run ESLint
# Full stack
yarn dev # Start frontend (same as yarn start)app/page.tsx- Home page with wallet connectapp/play/page.tsx- Room creation/joining with bettingapp/game/[roomId]/page.tsx- Game interface with commit-revealapp/history/page.tsx- Match history with IPFS linkscomponents/Header.tsx- Navigation with username editinghooks/useRPSContract.ts- Smart contract interactions
contracts/RPSOnline.sol- Full RPS game with betting, commit-reveal, and cancellationdeploy/00_deploy_rps_online.ts- Deployment script
app/api/username/route.ts- Username managementapp/api/stats-fast/route.ts- Stats from Turso (direct reads)app/api/store-match/route.ts- Match storage (Turso + IPFS backup)app/api/user-matches/route.ts- Query match history from Tursoapp/api/init-db/route.ts- Initialize Turso database tablesapp/api/migrate-data/route.ts- Migrate Redis data to Tursoapp/api/store-blockchain-proof/route.ts- Blockchain proof storageapp/api/resolve-name/route.ts- ENS/Basename resolutionapp/api/verify/route.ts- Self Protocol verificationapp/api/check-verification/route.ts- Check user verification status
utils/gameUtils.ts- Move hashing and game logiclib/tursoStorage.ts- Turso storage layer (users, stats, matches)lib/turso.ts- Turso SQLite database clientlib/pinataStorage.ts- IPFS storage utilities (Pinata)lib/upstash.ts- Redis client for active game roomslib/edgeConfigClient.ts- Edge Config clientcontexts/AuthContext.tsx- Unified authentication contexthooks/useSelfProtocol.ts- Self Protocol integrationhooks/useGoodDollarClaim.ts- GoodDollar UBI claim integrationstyles/colorThemes.ts- Dynamic color theme systemstyles/fontThemes.ts- Dynamic font theme systemstyles/spacingThemes.ts- Dynamic spacing scale system
Celo Mainnet:
- Contract:
0xace7999ca29Fc9d3dfDD8D7F99A1366a5cF62091 - RPC: https://forno.celo.org
- Gas Token: CELO or cUSD
- Recommended Wallets: MiniPay, MetaMask
Base Mainnet:
- Contract:
0x17f238a671CEEa5b6ac9b44E280a42a2Bb080feC - RPC: https://mainnet.base.org
- Gas Token: ETH
- Recommended Wallets: Coinbase Wallet, MetaMask
Local Development:
- Hardhat network (localhost)
Contract addresses are auto-exported to contracts/deployedContracts.ts after deployment.
- โ Pivoted to free-to-play model
- โ Removed all betting/paid room functionality
- โ Gaming UI with neon aesthetics and animations
- โ Migrated to Turso as primary database (stats, matches, users)
- โ Redis for active game rooms only (no stats caching)
- โ IPFS backup storage via Pinata
- โ PWA support with offline capabilities
- โ Dynamic theme system (colors, fonts, spacing)
- โ Unlimited rematch system
- โ On-chain matches page with filters
- โ Per-match publishing with ENS/Basename resolution
- โ Performance optimizations (84% faster load, 60 FPS locked)
- โ GoodDollar UBI daily claims integration
- โ Self Protocol human verification
- โ Farcaster & Base miniapp support
- โ MiniPay integration for Celo
- Tournament brackets with multi-round matches
- Global leaderboards & player statistics
- Achievement system
- Real-time multiplayer lobbies (Random matchmaking)
- Mobile app development
- Optional betting mode (future)
- Frontend: Next.js 15, React 18, TypeScript, TailwindCSS
- Wallet: Reown AppKit, Wagmi, Viem
- Blockchain: Hardhat, Solidity
- Networks: Celo Mainnet + Base Mainnet (Multi-chain)
- Database: Turso SQLite (primary), Redis (active rooms), IPFS (backup)
- Themes: Dynamic color/font/spacing with CSS variables
- Testing: Vitest + React Testing Library
- Identity: Self Protocol (@selfxyz/core)
- Payments: GoodDollar (G$) tipping
- PWA: Service Worker with offline support
- Deployment: Vercel
Create .env files in respective packages:
DEPLOYER_PRIVATE_KEY=your_private_key
NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID=your_project_id
# Turso Database (primary storage)
TURSO_DATABASE_URL=libsql://your-database.turso.io
TURSO_AUTH_TOKEN=your_turso_auth_token
# Redis (caching layer)
REDIS_URL=your_redis_url
KV_URL=your_kv_url
KV_REST_API_TOKEN=your_token
KV_REST_API_URL=your_url
# IPFS (backup storage)
PINATA_JWT=your_pinata_jwt_token
NEXT_PUBLIC_IPFS_GATEWAY=https://gateway.pinata.cloud
# Edge Config (verification storage)
EDGE_CONFIG=https://edge-config.vercel.com/...
EDGE_CONFIG_ID=ecfg_...
VERCEL_API_TOKEN=...
# Optional
NEYNAR_API_KEY=your_neynar_key
JWT_SECRET=your_jwt_secret
After deploying to production:
-
Initialize Turso tables:
curl https://your-domain.com/api/init-db
-
Migrate existing data (if upgrading from Redis-only):
curl -X POST https://your-domain.com/api/migrate-data
- Turso (Primary): Users, stats, matches - persistent, ACID-compliant
- Redis (Temporary): Active game rooms, 7-day match history cache
- IPFS (Backup): Decentralized match storage via Pinata
- Fork the repository
- Create a feature branch
- Make your changes
- Test thoroughly
- Submit a pull request
MIT License - see LICENSE file for details.
Ready to play? Run yarn chain, yarn deploy, yarn start and visit http://localhost:3000!