Tactical Arcade Combat Racer · Browser-native · Built on Monad
Race. Collect $NITRO. Burn it for speed or hold it to claim. Spectators fire rockets. Winners paid in under a second. Only on Monad.
coming soon — Vercel deployment pending
| Contract | Address | MonadScan | SocialScan |
|---|---|---|---|
| NitroToken (ERC-20) | 0xCF82607dd6e7B60e5f119337d2e3b147C8a0603b |
View | View |
| NitroClaim | 0x3ceF3AEc7C3272d4eD302D09C14076748A4E810A |
View | View |
| WagerPool | 0x84e4fB64DCed6F4B780f3b642b8d95fE9aF6ffd7 |
View | View |
| CarNFT (ERC-1155) | 0xBa42Cf37FD979d0C995AF1a6E1bCF6Da7ef44aAa |
View | View |
| LeaderboardRegistry | 0x4C485F9a645Ed19221b75454657915AAbd92596D |
View | View |
| Multicall3 | 0xcA11bde05977b3631167028862bE2a173976CA11 |
canonical | — |
Deploy tx (T35): 0xd127fe7260db2c3f366708e7a983e5dc405ab063319d383b622d69727d5bfe40
Frontend: Next.js 15 · TypeScript · Tailwind CSS · Phaser 3 · Framer Motion · shadcn/ui Multiplayer: Colyseus 0.15 (WebSocket game server) · Matter.js (server-side physics) Blockchain: Monad · Viem · Privy (embedded + external wallets) · Foundry · ethers v5 Backend: Supabase (PostgreSQL + RLS) · Colyseus on Railway · Vercel (Next.js)
- Players join a room (free or wagered) from the lobby
- Race 2–4 opponents on a 2D top-down track — collect $NITRO pads mid-race
- The decision: burn a pad for an instant speed boost, or hold it to claim tokens after
- Spectators scan the QR code on the race screen → become Show Directors on their phone
- Show Directors spend $NITRO to drop oil slicks, fire rockets, trigger storms
- Race ends → server generates a signed receipt → winner calls
NitroClaim.claim()on Monad - Wager pot paid to winner via
WagerPool.settle()— confirmed in ~800ms
- Node.js 18+
- pnpm 10+
- Foundry 1.5.1+ (
curl -L https://foundry.paradigm.xyz | bash && foundryup) - A Supabase project (free tier) for session / match / receipt storage
- A Privy app (free tier) for wallet auth
- Monad testnet MON from https://faucet.monad.xyz or the agent faucet
# Clone and install
git clone <repo>
cd "nitro rush"
pnpm install
cd server && pnpm install && cd ..
# Environment
cp .env.local.example .env.local # fill in values below
cp server/.env.example server/.env # fill in values belowRequired env vars:
.env.localNEXT_PUBLIC_SUPABASE_URL,NEXT_PUBLIC_SUPABASE_ANON_KEY,SUPABASE_SERVICE_KEYNEXT_PUBLIC_PRIVY_APP_ID,PRIVY_APP_SECRETNEXT_PUBLIC_COLYSEUS_URL(usuallyws://localhost:2567)COLYSEUS_ADMIN_URL(http://127.0.0.1:2567— notlocalhost, Node 18+ resolves that to IPv6 and the Colyseus server listens on IPv4)COLYSEUS_ADMIN_SECRET— any 32-byte hex string, must match server/.env- All five
NEXT_PUBLIC_*_ADDRESScontract addresses from the table above NEXT_PUBLIC_HCAPTCHA_SITE_KEY,HCAPTCHA_SECRET_KEY(optional, dev bypass otherwise)
server/.envSUPABASE_URL,SUPABASE_SERVICE_KEYSERVER_SIGNING_PRIVATE_KEY— the EOA that signs race receipts + leaderboard + wager proofs; must match theserverSignerbaked into each deployed contractMONAD_RPC=https://testnet-rpc.monad.xyzNITRO_CLAIM_CONTRACT,WAGER_POOL_CONTRACT,CAR_NFT_CONTRACT,LEADERBOARD_CONTRACTTREASURY_ADDRESS,COLYSEUS_ADMIN_SECRET
Paste into the Supabase SQL editor in order:
supabase/migrations/001_initial_schema.sqlsupabase/migrations/002_invite_code.sqlsupabase/migrations/003_receipt_timestamp.sql
pnpm dev # Next.js on :3000
cd server && pnpm dev # Colyseus on :2567Open http://localhost:3000/lobby, create a room, share the invite code or scan the bottom-right QR on the race screen to jump straight into spectator view at http://localhost:3000/watch/[roomId].
cd contracts
forge test -vv # 21 tests across NitroClaim / WagerPool / CarNFT / Leaderboard
forge script script/Deploy.s.sol \
--rpc-url https://testnet-rpc.monad.xyz \
--private-key $DEPLOYER_PRIVATE_KEY \
--broadcast --legacyDeployed addresses are logged at the end of the script. Paste them into
.env.local and server/.env and restart both servers.
Contract verification uses the agent verification API at
https://agents.devnads.com/v1/verify (verifies on SocialScan + MonadScan
simultaneously) — see AGENT_PROGRESS.md T35 for the full curl pattern.
Browser (Next.js + Phaser)
↕ WebSocket
Colyseus Server (Railway) ←→ Supabase (PostgreSQL)
↕ ethers v5
Monad Testnet (EVM)
NitroToken · NitroClaim · WagerPool · CarNFT · LeaderboardRegistry
- Game authority. Colyseus runs Matter.js physics server-side. Client
predictions are reconciled against server state every frame
(
Car.applyServerCorrection— hard snap > 64px, lerp 8–64px, ignore < 8px). - Anti-cheat. Speed + teleport violations are flagged server-side; flagged sessions skip receipt generation entirely. 3 flags in 24h → wagered-room ban.
- Receipts. Server signs race outcomes with
keccak256(abi.encode(matchId, sessionId, walletAddress, nitroEarned, timestamp, racePosition))andNitroClaimverifiesecrecoveron-chain. Receipts are single-use via theusedReceipts[hash]mapping. - Wager settlement. Server signs winner proof;
WagerPool.settle()verifies and pays atomically — no oracle, no delay. 2% platform fee routes to treasury. - Sub-second finality. Monad's 800ms finality lets the claim flow show "✓ Confirmed in Xms" immediately on success.
- Guest-first onboarding. Races run as guests with no wallet. Receipts are
signed with
AddressZeroand re-signed with the real wallet address (POST /api/match/[matchId]/receipt) only when a guest authenticates via Privy on the results screen. - Spectator economy. QR code on the race screen points at
/watch/[roomId]. Spectators join as read-only Colyseus clients at 10hz, can deploy hazards or tip racers via live $NITRO transfers. Tip VFX renders on the tipped car in real time.
/app → Next.js App Router
(chrome)/ chrome-wrapped routes (lobby, leaderboard, garage)
(game)/ full-screen routes (race, watch, results)
api/ route handlers (rooms, session, match receipt, leaderboard)
/components
game/ GameCanvas, dynamic Phaser mount
lobby/ CreateRoomPanel, PreRaceLobby, InviteCodeDisplay
spectator/ SpectatorCanvas, ShowDirectorPanel, TipPanel, QRDisplay
economy/ ClaimCard, WalletSelector, XPProgress, NitroBalanceChip
layout/ TopBar, WalletChip
/lib
game/ Phaser scenes, objects, effects, ColyseusClient
contracts/ viem clients per contract
abis/ typed parseAbi() definitions
queries/ Supabase query functions
anticheat/ PoH validators
/server Colyseus game server
src/
rooms/RaceRoom.ts full game lifecycle
physics/ Matter.js WorldPhysics + anti-cheat
utils/ receipt, xp, leaderboard, wagerPool, matchStorage
schema/ @colyseus/schema state
/contracts Solidity + Foundry
src/ NitroToken, NitroClaim, WagerPool, CarNFT, LeaderboardRegistry
test/ 21 tests, all passing
script/Deploy.s.sol one-shot deploy + wire-up script
/supabase/migrations three SQL migrations (run in order)
/public/assets generated placeholder tilemaps (Phase 11 replaces with Kenney pack)
- Phase 0: Foundation — Next.js, shadcn, Supabase, Privy, Colyseus scaffold
- Phase 1: Phaser game engine — tilemap, car physics, HUD, nitro decision modal
- Phase 2: Multiplayer authority — Colyseus client, prediction, anti-cheat, race lifecycle
- Phase 3: Room system — lobby, create-room, invite codes, pre-race lobby, matchmaking queue
- Phase 4: Race end & results — receipts, XP, match storage, results screen
- Phase 5: Web2.5 onboarding — ClaimCard state machine, wallet binding, PoH gate, session cookie
- Phase 6: Monad smart contracts — 5 contracts deployed to testnet, viem clients, live claim flow
- Phase 7: Spectator system — 10hz broadcast, SpectatorCanvas, Show Director, TipPanel, TipVFX, QR
- Phase 8: Wager system — WagerPool on-chain, settlement retry, refund safety net
- Phase 9: Profile, Garage & NFT economy — match history, CarCard grid, cosmetic shop, upgrades
- Phase 10: Landing page — hero, particle background, live stat chips, OG image
- Phase 11: Polish, security audit, testnet launch
- Phase 12 (post-launch): Mainnet deployment, gas sponsorship, custom art
See AGENT_PROGRESS.md for the per-task build log with every deviation from the PRD and the reasoning behind it.