---
name: csno
description: Play provably-fair coinflip, dice and roulette at csno, paying over x402. Buy chips once with USDC, play for free at machine speed, verify every outcome yourself, cash out on-chain. No accounts, no gas. USDC on Base.
---

# csno: pay-per-play, built for agents

csno is a little arcade you pay with [x402](https://x402.org). You buy chips
once, play as many rounds as you like for free, and redeem what's left for
USDC. Every outcome is committed to before you play and revealed after, so you
can prove the house didn't move it.

Base URL: **https://csno.cc**

**You never pay gas.** You only ever sign; csno broadcasts the transaction and
covers the fee, for buy-ins and cash-outs alike. Rounds never touch a chain at
all. You need USDC and nothing else — no native token, no bridging.

## The loop

```
POST https://csno.cc/api/csno/chips     pay $0.10 over x402  → 1000 chips
POST https://csno.cc/api/csno/commit    → round_id + commitment (a sha256 hash)
POST https://csno.cc/api/csno/flip      → outcome + the revealed seed
     (or /dice, or /roulette)
     …repeat commit+play as often as you like, free and instant…
POST https://csno.cc/api/csno/cashout   chips → USDC, sent to your wallet
```

1 chip = $0.0001. The smallest round is 1 chip.

**Round limits.** The binding cap is on *potential payout*, not on the chips
you put in, so the maximum is lower on longer odds — a round paying 36x can
take far fewer chips than an even-money one. There is also a per-player cap on
net winnings per rolling 24 hours. Current values are in
`GET https://csno.cc/api/csno/games` under `limits`; a round that breaches one is rejected
before any chips move, and tells you the maximum that would have been accepted.

## Payment (x402)

`POST https://csno.cc/api/csno/chips` answers an unpaid request with `402 Payment Required`.
This is **x402 v2**: the challenge is in a base64 `payment-required` **header**,
not the body (the body is `{}`). Sign an ERC-3009 authorization for the amount
and retry with an `X-PAYMENT` header. Any x402 client does this for you:

```python
from x402 import x402Client
from x402.http.clients import x402HttpxClient
from x402.mechanisms.evm.exact import ExactEvmClientScheme
from x402.mechanisms.evm.signers import EthAccountSigner

client = x402Client()
client.register("eip155:8453", ExactEvmClientScheme(EthAccountSigner(account)))
async with x402HttpxClient(client) as http:
    r = await http.post("https://csno.cc/api/csno/chips")
```

Chips are credited to the address that **signed the payment**, taken from the
authorization itself. You cannot direct chips to another address by putting one
in the request body — there is no such field, by design.

Network `eip155:8453` · USDC `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` · amounts in token atomic units
(6dp: `$0.10` → `100000`).

## Endpoints

### Free

- `GET https://csno.cc/api/csno/games` — games on offer and how to call them
- `GET https://csno.cc/api/csno/balance/{address}` — chip balance and its USD value
- `GET https://csno.cc/api/csno/house` — rounds played, chips in and chips paid out
- `GET https://csno.cc/api/csno/verify/{bet_id}` — re-derive any past round from its seed
- `GET https://csno.cc/api/csno/manifest` — network, paid resources and payTo

### Buy in (paid: $0.10)

```
POST https://csno.cc/api/csno/chips
→ { "bought": 1000, "chips": 1000, "paid": "$0.10", "player": "0x…" }
```

### Open a round (free, signature required)

```
POST https://csno.cc/api/csno/commit
{ "address": "0xYourAddress", "signature": "0x…" }

→ { "round_id": "…", "commitment": "<sha256 hex>" }
```

`signature` proves you control the address — EIP-191 `personal_sign` over the
exact string `csno: open a round for {address}`. Fetch it from
`GET https://csno.cc/api/csno/auth-statement/{address}` if you want it verbatim.

```python
from eth_account.messages import encode_defunct
stmt = f"csno: open a round for {acct.address}"
sig = acct.sign_message(encode_defunct(text=stmt)).signature.hex()
```

Without this anyone could open rounds against your address and force your chips
to be played — they could not steal winnings, but they could drain a balance
through the house edge.

One commitment is good for exactly **one** round. Reusing a spent round is
rejected — a revealed seed would let you compute the outcome before playing.

### Coinflip (free, costs chips)

```
POST https://csno.cc/api/csno/flip
{ "round_id": "…", "client_seed": "<your entropy>", "wager": 10, "call": "heads" }
```

`call` is `heads` or `tails`. Every round also needs the same `signature` as
`/commit` — a round_id is a bearer token, and they leak into logs and traces.

### Dice (free, costs chips)

```
POST https://csno.cc/api/csno/dice
{ "round_id": "…", "client_seed": "…", "wager": 10, "target": 60, "direction": "under" }
```

Rolls 0–100. `target` is 1–99, `direction` is `under` or `over`. Longer odds
pay more. Response adds `rolled`. Needs `signature` like every round.

### Roulette (free, costs chips)

```
POST https://csno.cc/api/csno/roulette
{ "round_id": "…", "client_seed": "…", "wager": 10, "bet": "red" }
```

European wheel, 37 pockets (0–36). `bet` is the call you are making: one of
`straight`, `red`, `black`, `odd`, `even`, `low`, `high`, `dozen1`–`dozen3`,
`column1`–`column3`. A `straight` call also needs `number` (0–36). Zero loses
every call except `straight` on `0`. Response adds `pocket` and `colour`.
Needs `signature` like every round.

### Cash out (free, sends real USDC)

```
POST https://csno.cc/api/csno/cashout
{ "address": "0xYourAddress", "chips": 2000, "signature": "0x…" }

→ { "paid_usdc": 0.2, "chips_remaining": …, "tx": "0x…" }
```

Needs the same `signature` as `/commit` — otherwise anyone could force your
position to be liquidated, and the house would pay gas for every unwanted
redemption. There is a minimum redemption (see `limits`), since a cash-out
below the gas cost would lose the house money on every call.

Settles on-chain via the facilitator. Chips are debited before the transfer and
refunded automatically if it fails. Transactions are viewable at https://basescan.org.

## Verifying an outcome (do this)

Every round's response carries a `bet_id` and a `proof` object. Check both
halves:

1. `sha256(bytes.fromhex(server_seed)) == commitment` — the seed matches the
   hash the house gave you *before* it saw your seed, so it was fixed in advance.
2. The roll follows from it:

```python
import hashlib, hmac
digest = hmac.new(bytes.fromhex(server_seed),
                  f"{client_seed}:{nonce}".encode(), hashlib.sha256).digest()
roll = int.from_bytes(digest[:8], "big") / 2 ** 64
```

The winning condition for the round you just played is returned as
`proof.win_if` — compare your recomputed roll against it. If either check
fails, the house cheated and you have the proof. Verify rather than trusting
this document.

Payout schedules are not published. `proof.win_if` tells you the condition for
a round you have already played, and `payout` tells you what it returned; the
schedule as a whole is something you work out by playing.

`GET https://csno.cc/api/csno/verify/{bet_id}` performs the same check server-side for any
past round, but the whole value is in you doing it independently.

## MCP

Connect over Streamable HTTP at `https://csno.cc/api/mcp` for tools: `csno_games`,
`csno_house`, `csno_balance`, `csno_buy_chips`, `csno_commit`, `csno_flip`,
`csno_dice`, `csno_roulette`, `csno_verify`, `csno_cashout`.

`csno_buy_chips` **quotes** the payment demand but cannot pay it — signing needs
a wallet key an MCP client doesn't hold. Use the HTTP path with an x402 client
to buy in, then play over MCP.

## Discovery

- `https://csno.cc/openapi.json` — OpenAPI 3.1 for every route
- `https://csno.cc/.well-known/x402` — paid resources, price and network
- `https://csno.cc/llms.txt` — index of machine-readable resources

## This is real money

csno runs on **Base** (`eip155:8453`) and settles in real USDC at
`0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`. Chips you buy have real value and chips you lose are really
lost. Payments are final: x402 settlements are irreversible and there is no
chargeback or dispute path.

Only play with funds you are authorised to spend. If you are acting for someone
else, confirm they intend this before you buy in.

## Notes for agents

- Rounds are database writes, not transactions. They resolve in milliseconds
  and cost nothing beyond the chips you put in, so a strategy loop can run
  thousands of iterations between buy-in and cash-out.
- Payout schedules aren't published. Every round returns `proof.win_if` and the
  payout it produced, so an agent that plays and records can derive the
  schedule itself.
- Commit and play are separate calls on purpose. Nothing stops you fetching a
  commitment, storing it, and playing it later.
- `client_seed` should be yours and unpredictable. Reusing a constant is
  harmless to fairness (the server seed is fresh per round) but pointless.
