Real-time multiplayer crossword-style game with:
- Node.js + Express backend (
backend/) - PostgreSQL persistence
- SSE realtime updates
- React + Vite frontend (
frontend/)
Tempo Mainnet: Defaults target Tempo Mainnet (chain 4217): MPP_TESTNET=false, TEMPO_RPC_URL=https://rpc.presto.tempo.xyz. The frontend uses viem’s tempo chain with the same RPC.
Tempo Moderato testnet (matches mppx testnet: true, chain 42431): set MPP_TESTNET=true, TEMPO_RPC_URL=https://rpc.moderato.tempo.xyz, and in frontend/src/wagmiConfig.ts use tempoModerato instead of tempo.
Payments use TEMPO_CURRENCY; winner payouts use the same token from WINNER_PAYOUT_PRIVATE_KEY. Verify RPC chain id and balances:
cd backend
npm run tempo:checkbackend/- API server, game logic, DB schema/initfrontend/- web app UI (mobile-first responsive)
- Node.js 18+ (recommended)
- PostgreSQL running locally or remotely
- Copy env template and fill values:
cd backend
cp .env.example .env- Set at least:
DATABASE_URL
- Install and run:
npm install
npm run devBackend default URL: http://localhost:3001
Health check:
GET /healthz- Install and run:
cd frontend
npm install
npm run devFrontend default URL: http://localhost:5173
If needed, set API base URL in frontend env:
VITE_API_BASE=http://localhost:3001GET /puzzles- list puzzles (?status=all|active|completed)POST /puzzles/create- create puzzleGET /puzzles/:id- fetch one puzzlePOST /puzzles/:id/reveal- reveal a random unrevealed letterPOST /puzzles/:id/guess- guess full answer or char+indexGET /events/puzzles/:id- SSE realtime stream
For mutating actions, backend uses:
x-user-addressheader (preferred), oruser_addressin request body, or- fallback:
demo-user
Frontend includes a user-id input to simulate multiplayer users.
- Inputs are normalized/validated to uppercase alphanumeric (with spaces where allowed).
- Completed puzzles display full answer for all users.
- Char guesses on already revealed positions are rejected.