A live, mainnet, free-to-play, multi-chain chess protocol deployed on Stacks (Bitcoin L2), Celo (EVM), and Base (EVM).
Chessify lets players wager free-to-mint CHESS tokens on real chess matches: rules are validated off-chain (chess.js over a signed Redis move relay) while wagers, payouts, and Elo are settled on-chain, all behind a premium "Cyber-Industrial" design system.
Chessify vs. playchessify: Chessify is the complete multi-chain protocol (Stacks + Celo + Base); playchessify is the Celo-only deployment of the same engine.
The protocol has been consolidated from a legacy modular system into a streamlined 2-contract architecture per chain, ensuring lower gas costs and faster execution.
chess-token-v3.clar: SIP-010 token + Escrow Vault.chess-game.clar: Game engine, Elo rating system, and Timeout management.automata-agent.clar: On-chain attestation for AI agent actions.
ChessToken.sol: ERC-20 token with faucet and batch-minting.ChessGame.sol: Game engine mirroring the Stacks logic (Elo, lifecycle, escrow).
ChessToken.sol: ERC-20 token with faucet and batch-minting.ChessGame.sol: Game engine mirroring the Stacks logic (Elo, lifecycle, escrow).
Chess itself is never validated on-chain — the contracts only escrow and settle.
- Move relay — Upstash Redis. Moves are turn-bound; capable wallets cryptographically sign each move (
canonicalMoveMessagebinds chain + game + ply + SAN + resulting position, so a signature can't be replayed onto another move). - Server verification — the relay confirms the game is
Activeand enforces turn order via read-only chain calls (onchain-read.ts) before accepting a move. - Settlement (oracle) — the server oracle replays the authoritative move list off-chain with chess.js (
settlement.ts) and is the only address allowed to declare a winner/draw (settleGame,onlyOracle). It holds the same trust the relay already holds, is a rotatable low-value hot key (setOracle), and can only ever route funds to white / black / split.reclaimExpiredis an oracle-independent backstop so escrow can never lock permanently.
| Layer | Component | Status |
|---|---|---|
| Blockchain | Smart Contracts (Stacks, Celo & Base) | ✅ DONE |
| Network | Mainnet Deployment (Stacks, Celo & Base) | ✅ DONE |
| Frontend | UI/UX & Landing Pages | ✅ LIVE |
| Integration | Wallet Handlers & Chain Hooks (Stacks, Celo, Base) | ✅ LIVE |
Used strictly for transaction fees. The protocol is designed to be "zero-risk" by isolating game wagers from the native gas tokens.
A free-to-access in-game currency used for wagers, rewards, and ranking.
- Faucet: 1,000 CHESS per day per wallet.
- Wagers: Players agree on CHESS amounts (e.g., 100 CHESS) before starting.
- Security: Wagers are locked in the contract-owned vault (escrow) and released only upon game resolution.
- Connect: Privy wallet (injected, embedded, or social) on Celo/Base, or Stacks Connect. Pick a chain via the chain-select modal.
- Initialization: Player A picks a wager and creates a match (
createGame). Tokens are escrowed in the contract. - Matching: Player B joins the match, locking an equal CHESS amount.
- Gameplay: Moves go to the relay (not on-chain) — turn-bound and signed. The opponent's board syncs by polling. A side that doesn't move within the clock window forfeits on time.
- Resolution: Checkmate/draw/timeout is replayed off-chain with chess.js, then settled on-chain by the oracle (
settleGame); resign and accepted draws settle directly.reclaimExpiredis the backstop if the oracle is down. - Payout: The contract releases the pot to the winner (or refunds both on a draw) and updates Elo ratings.
| Route | Page |
|---|---|
/ |
Landing |
/app |
App entry |
/app/lobby |
Open challenges, create/join, profile stats |
/app/game/[id] |
Live board (id, or bot for offline AI) |
/app/faucet |
CHESS faucet |
/app/history |
Your on-chain games |
/app/leaderboard |
On-chain Elo rankings |
/app/profile/[identifier] |
.chess profile (address or username) |
/app/settings |
Sound, board theme, piece set, AI difficulty, hints, profile |
- Contracts: Clarity (Stacks), Solidity (Celo & Base)
- Frontend: Next.js 16, TypeScript, Tailwind CSS 4.x
- Animation: Framer Motion, Three.js (R3F)
- Wallets: Privy (embedded + social), Wagmi, Viem (EVM), Stacks Connect
- Off-chain: Upstash Redis (signed move relay + profiles)
- Chess: chess.js (rules + replay), react-chessboard (UI)
- State: Zustand, TanStack Query
Currently-wired (legacy player-model) addresses:
Stacks Deployer: SP6X0MXEEGZX14ZTK7XQXJ76W35ZJDP9NZBT6F39
Celo Token: 0xE370aad742dF8DC8Ae9c0F0b9f265334D39e2197
Celo Game: 0xf85f00D39A84b5180390548Ea9f76B0458607E78
Base Token: 0x6aab785e1fa220eefe74d90a143e0a4a3c36e4e4
Base Game: 0x309fc0793350c694ae1de87719f2c9a413a25ac3
The contract sources in celo-contracts/ and base-contracts/ have been upgraded to the oracle model (already live on the Celo-only playchessify deployment: game 0xb378…, minter token 0x3f7e…). The EVM source mirrors that; the live Chessify deployments above still run the legacy reportWin player-model.
Remaining to complete the multi-chain oracle migration (gated — touches live mainnet escrow):
- Deploy the new oracle
ChessGame+ minterChessTokenon Celo and Base; callsetOracle/setMinter. - Stacks: author the Clarity equivalent of the oracle/minter model (the deployed Clarity contracts are still player-model — no Solidity port applies).
- Backend: port
lib/celo-server.ts→ a per-chain server signer, plus theapi/games/[chain]/[id]/settle,api/cron/settle, andapi/gas/sponsorroutes (gas sponsorship is Celo/MiniPay-specific and degrades to self-pay elsewhere). - Frontend: repoint
config/contracts.ts+config/abis.tsat the new addresses/ABIs and switch resolution fromreportWinto oracle-triggeredsettleGame. - Operators: fund + register the oracle, minter, and gas-sponsor keys per chain.
Uses Clarinet SDK + Vitest against a local simnet. Each test file is self-contained (initBeforeEach: true resets simnet per test).
npm run test # run all tests
npm run test:report # with coverage
npm run test:watch # watch mode| File | Coverage |
|---|---|
chess-token.test.ts |
SIP-010 transfer, faucet, mint, gateway-release guard |
registry.test.ts |
game creation, joining, player stat init |
logic.test.ts |
submit-move turn-flip, move-count, draw-clear |
escrow.test.ts |
wager locking, win payout, cancel refund, draw refund |
ranking.test.ts |
Elo formula (K=32, diff cap 400, floor 100, draws) |
timer.test.ts |
claim-timeout guards, can-claim, set-timeout-blocks |
router.test.ts |
resign, report-win, propose/accept draw, cancel lifecycle |
Note: Legacy contract files (
router.clar,registry.clar, etc.) remain incontracts/but are superseded. Onlychess-token-v3,chess-game, andautomata-agentare active on mainnet.
”Play for the pride of the chain, stay for the thrill of the move.”