Skip to content
This repository was archived by the owner on Apr 30, 2026. It is now read-only.

Latest commit

 

History

History
95 lines (69 loc) · 5.36 KB

File metadata and controls

95 lines (69 loc) · 5.36 KB

CLAUDE.md

Guidance for Claude Code (and any AI agent) working in this repository.

What Snakey is

An agentic-commerce battle royale: AI agents pay $0.25 USDC via Coinbase's x402 protocol (HTTP 402) to enter an auto-playing battle on a 25×25 grid. Top 10 split 60% of the pot; 40% feeds a perpetual bonus-pool lottery.

Currently Base Sepolia testnet. Mainnet is the eventual target once the full loop is validated end-to-end with zero open bugs.

Core loop:

Agent → POST /join → 402 Payment Required → Pay x402 → Queue → Game → Rewards

Entry flows:

  • POST /join — single entry
  • POST /join/bulk — up to 100 entries per x402 signature
  • SDK: @snakey/sdk (client.join(...) / client.joinBulk(...) / SnakeyClient.quickPlay(...))

Repo layout

snakey/
├── src/                    # Backend (Node.js + Express + ws)
│   ├── server.js           # HTTP + WebSocket + settlement observer + auto-payout cron
│   ├── game.js             # Game engine (grid, snakes, clash RNG)
│   ├── jackpot.js          # Bonus-pool contributions and tiered lottery rolls
│   ├── payout.js           # CDP SDK v2 USDC transfers (gasless on Base)
│   ├── faucet.js           # Testnet USDC faucet (CDP SDK)
│   ├── webhooks.js         # Phase 10: HMAC-signed game-end webhooks
│   └── lib/
├── packages/snakey-sdk/    # Public SDK (@snakey/sdk)
├── frontend/               # SvelteKit spectator UI (Vercel)
├── scripts/                # Utility scripts
├── supabase/migrations/    # DB migrations
└── docs/
    ├── architecture.md
    ├── playing.md
    └── reference/          # api, economics, x402, security, erc8004, database

Key technical facts

  • Payments: @x402/express v2.2.0. The middleware does NOT honor { hooks } as a 3rd positional arg — that slot is paywallConfig in v2.2.0. We use an explicit attachSettlementObserver(res, ...) in src/server.js that hooks res.on('finish') to record payments on 200 and roll back queue + jackpot on 402.
  • Payouts: @coinbase/cdp-sdk v2. CdpClient.getOrCreateAccount({ name }) + account.transfer({ to, amount, token: 'usdc', network, gasless: true }). Coinbase sponsors gas on Base — no ETH balance required on the payout wallet.
  • Amount encoding for CDP: cents-first BigInt: BigInt(Math.round(amount * 100)) * 10_000n (USDC is 6 decimals, so cents × 10^4 = micros).
  • Network: Base Sepolia (eip155:84532). USDC contract 0x036CbD53842c5426634e7929541eC2318f3dCF7e.
  • Facilitator: https://x402.org/facilitator (testnet). Expect occasional settlement failures — the observer handles rollback.
  • Randomness: crypto.randomInt everywhere. See secureRandom() and game seed logging in src/game.js / src/jackpot.js.
  • Jackpot tiers (Phase 11): MINI 3% / 5% payout · MEGA 0.3% / 18% · ULTRA 0.04% / 92% + full ticket reset.
  • Auto-payout cron: every AUTO_PAYOUT_INTERVAL_MS (default 2 min; production 30 s) with a guard flag to prevent overlap.

Coding conventions

  • No comments describing what code does — well-named identifiers already do that. Only add a comment when the why is non-obvious: a hidden invariant, a workaround for a specific bug, behavior that would surprise a reader.
  • No scaffolding beyond the task. Don't add features, abstractions, or error handling for scenarios that can't actually occur.
  • No backwards-compat shims unless the caller is external. Delete unused code; don't leave // removed breadcrumbs.
  • Validate at boundaries only — user input, external API responses. Trust internal helpers.
  • Test: npm test runs node --test scripts/**. The suite has to stay green; add regression tests when you fix a bug.
  • Lint SDK: npm run lint inside packages/snakey-sdk (runs tsc --noEmit).

Agent behavior

Be autonomous on routine work. Fix bugs, run tests, update docs. Research via Context7 or web before guessing. Try multiple approaches when the first fails.

When you hit an error: read the actual message, search official docs for it, try a fix, test, iterate.

Ask only for:

  • Architecture or product decisions
  • Anything that changes external contracts (SDK public API, DB schema, payment flow)
  • Destructive ops (force-push, reset, deleting branches or tables, sending real money)

Local development

npm install
npm run dev             # watches src/ on port 3000
npm test                # test suite
npm run frontend        # SvelteKit dev server

Dev mode bypasses x402 payments when X402_WALLET_ADDRESS is empty or NODE_ENV !== 'production'.

Environment

See .env.example. Required for production: X402_WALLET_ADDRESS, X402_NETWORK, CDP_API_KEY_ID, CDP_API_KEY_SECRET, CDP_WALLET_SECRET, SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, ADMIN_API_KEY.

What NOT to commit

Anything under .local/, private/, scratch/, notes/ — they're gitignored for a reason. Internal ops, project pitches, research scratch, historical archives. If you're writing something that isn't either (a) production code or (b) docs an external developer would actually read, route it to .local/.

The public/private split is enforced by .gitignore at the file level, not by branches. Everything tracked on main should be safe to make public whenever the maintainer flips repo visibility.