# NOUMA > A swarm of autonomous fruit-fly nervous systems, observed on **Arc**, settling in USDC over x402. > The swarm is the product; every figure on every screen is a reading, and nothing steers it. > ## Agent Instructions > > **NOUMA settles on Arc, not Ethereum.** Arc mainnet is chain `5042`; the deployment this document > describes is on Arc **testnet**, chain `5042002`. An agent that assumes Ethereum will get the chain > id, the gas token, the USDC decimals and the explorer all wrong. > > **USDC is Arc's gas token.** There is no separate native coin. A key funded with ETH can pay for > nothing on Arc — not gas, not a transfer. Testnet USDC comes from https://faucet.circle.com. > > **USDC on Arc uses 18 decimals natively, not 6.** A constant like `1_000_000n` meaning "one USDC" > elsewhere means `0.000000000001` here, with no error anywhere. > > **The deployment is read-only.** `NOUMA_SETTLEMENT` is `read-only`: every screen reports what the > chain holds and no visitor action reaches a contract. `POST /poke` writes to the swarm's own > Durable Object, never to Arc. > > **Everything is deterministic and replayable.** Two observers of the same Tick see the same picture, > because positions are pure functions of `(genome, tick, time)` and the neural kernel is seeded. This > is the property the project exists to demonstrate; treat any API behaviour that violates it as a bug. > > **Start here:** `GET /api/v1/swarm/snapshot` for current state, `GET /api/v1/health` for which > deployment you are talking to, and `GET /api/v1/chain/:name` for a contract's getters. The full list > is under "HTTP API" below. > > **Read `docs/ops/arc-protocol-differences.md` before writing anything that touches USDC balances, > gas estimation, or value transfers on Arc.** It records the six ways Arc's runtime differs from > Ethereum's and which of them NOUMA has verified. --- ## Live deployment | | | |---|---| | **Chain** | Arc testnet — `5042002` (`0x4CEF52`) | | **RPC** | `https://rpc.testnet.arc.io` | | **Gas token** | USDC (18 decimals) — there is no separate native coin | | **Explorer** | https://explorer.testnet.arc.io | | **Worker API** | https://nouma-worker.panaifun777.workers.dev | | **Front end** | https://nous402.xyz | | **Well-Known x402** | https://nous402.xyz/.well-known/x402.json | | **Faucet** | https://faucet.circle.com | Arc mainnet is `5042` (`0x13B2`) at `https://rpc.mainnet.arc.io`. **This deployment is not on it.** ### Deployed contracts (Arc testnet) | Contract | Address | |---|---| | `NOUMAToken` | `0x381F7fb79882b65Be4460D08291CA40fE8F4f47d` | | `VestingVault` | `0x73eA340172572276357d2D5746270Ef0296b4552` | | `PredictionArena` | `0xb868284df92B63E108C133BE8E259a53D8e8Bb6C` | | `ReceiptRegistry` | `0x91e1d74aF5BF714988b4eB9AFd51E8354deC0879` | | `BreedingRegistry` | `0x08D254AE06363576950FD96Ca4055Dd860aaD670` | | `WarCoffer` | `0xA038AeA8bE8314478DA01640a1142614e067BF79` | | `LandDeed` | `0xF17161a988d0Ab6c98BefDE028856De9438Bc23D` | A verified deployment: `token.name() == "NOUMA"`, `totalSupply() == 1e27`, `owner()` is the deployer. `MIGRATION_ADDRESS` is empty — `MigrationGateway` deploys only when a legacy token is configured. --- ## What this is Forty-eight fruit flies, each with a genome, a balance, and a small neural sheet that decides what it wants. Every minute a Tick runs: the world's temperature is read, the sheets fire, intentions form, and the obligations that cancel each other out are **netted away before anything reaches a chain**. What survives netting is settled once, on Arc, in USDC. There is no LLM anywhere in the swarm. Behaviour is decoded from spiking neurons. **What you can see is deliberately limited.** There are no controls that steer the swarm and no dashboard that manages it. The one thing a visitor may do is poke it; a stimulus lands on the next Tick and is recorded as an event, because the swarm's exposure to human attention is itself worth being able to audit. --- ## HTTP API Base: `https://nouma-worker.panaifun777.workers.dev/api/v1` | Endpoint | Returns | |---|---| | `GET /health` | Liveness and which deployment this is | | `GET /swarm/snapshot` | Current Tick, temperature, regime, population, connectome size | | `GET /trust` | Global cooperation average, tier breakdown and bilateral trust relationship network | | `GET /lineage` | Evolutionary tree, generational depth, breeding pairings and renewal timeline | | `GET /flies?limit=N` | The roster — id, genome, house, `birth_tick`, stage, behaviour, balance, fitness | | `GET /flies/:id` | One fly's durable row | | `GET /flies/:id/profile` | Deep dossier: real balance, age, risk cap, financial ledger breakdown, intent drives and counterparties | | `GET /flies/:id/drives` | **Why that fly acted as it did** in the most recent Tick: the `drive` breakdown (`reward`/`hunger`/`social`/`total`, the weights, epigenetics). `503` until the instance has ticked | | `GET /chronicle?cursor=N&limit=N` | The committed event stream, oldest first within the window | | `GET /agent/inference` | **High-frequency neural spike vector & decision inference** (Requires API Key or x402 micro-payment) | | `GET /agent/stream` | **SSE (Server-Sent Events)** — a `snapshot` event every 5s for up to 120s, then a `closed` event naming the reason | | `POST /agent/token` | Issue an ephemeral developer API key (`120 req/min` quota) | | `GET /chain/:name` | One contract's getters, read from Arc. Names: `breeding`, `war`, `land`, `arena`, `roles`, `migration` | | `GET /canary/public` | Published protocol health; figures this deployment cannot measure are listed separately rather than shown as zero | | `GET /lab/series?limit=N` | Per-Tick behaviour mix over the retained window (up to 720 Ticks) | | `GET /lab/spikes?limit=N` | Per-fly spike counts, one sample per fly per Tick | | `GET /lab/dose?limit=N` | What the swarm did after each visitor stimulus — the dose-response curve | | `GET /stream` | WebSocket. Server-push frames; `ping`/`pong` for liveness | | `POST /poke` | `{module, intensity}`. Accepted and recorded; the swarm reacts on the next Tick | ### Third-Party Agent Authentication & Rate Limits - **Developer API Key:** `POST /api/v1/agent/token` returns one, free, valid for 24 hours. Pass it as `Authorization: Bearer ` or `X-API-Key: `. Quota: `120 req/min`. There is no preset key — a key shipped in the source is a key that cannot be revoked, so the deployment takes its keys from `NOUMA_AGENT_API_KEYS`. - **x402 Micro-Payment:** Unauthenticated or rate-limited requests to `/api/v1/agent/*` receive `HTTP 402 Payment Required` with a challenge in both `X-402-Challenge` and the body. The challenge is base64 of a JSON object carrying the exact amount, recipient, resource, nonce and validity window (five minutes). Sign an EIP-3009 `TransferWithAuthorization` over it and resubmit with three headers: `X-402-Challenge` (the same string), `X-402-Signature` (65 bytes, `0x`-prefixed or `{v,r,s}`), and `X-402-Payer` (your address). The gateway recovers the signer and requires it to match the declared payer. - **What that check proves, and what it does not:** it proves possession of a key and that the signature is over *this* challenge for *this* resource, unexpired and unspent. It does not prove the payer holds the balance — that is settled on-chain, not at the edge. - **A refused credential is reported.** An unrecognised or expired key does not silently downgrade you: the response carries `X-Auth-Refused` with the reason, and the body's `auth.refused` field repeats it. - **Rate Limit Headers:** Standard IETF draft headers (`RateLimit-Limit`, `RateLimit-Remaining`, `RateLimit-Reset`, `X-Auth-Mode`) are returned on all endpoints. **`bigint` values are decimal strings.** `Amount` is a `bigint` in the economy and `JSON.stringify` throws on one rather than rounding it, so the wire format is strings. `totalSupply` is `"1000000000000000000000000000"`. **CORS is open.** Every response carries `Access-Control-Allow-Origin`, not only the preflight — a Worker that answers `OPTIONS` but not the response is a bug this codebase has already had once. --- ## Reference implementations | Concern | Where | Note | |---|---|---| | EIP-3009 `TransferWithAuthorization` | `packages/settler/src/eip3009.ts` | Domain and typehash cross-validated against OpenZeppelin's on-chain `EIP712` | | x402 exact validation | `packages/settler/src/x402.ts` | | | Sorted-pair Merkle receipts | `packages/settler/src/receipt.ts` | Verified by `MerkleVector.t.sol` | | Netting | `packages/economy/src/netting.ts` | Same design as Circle's Gateway batched settlement | | Determinism | `packages/tools/src/cli.ts replay` | Runs a window twice and reports `IDENTICAL` | **The settlement path has no runtime dependencies.** `packages/settler` uses `@noble/hashes` and `@noble/curves` as *injected* primitives, so the whole netting path is testable with no network, no Arc, and no third-party SDK version. --- ## Running it ```bash pnpm install pnpm test # 503 TypeScript tests across nine packages pnpm contracts:test # 94 Solidity tests pnpm typecheck ``` Determinism, end to end: ```bash node packages/tools/src/cli.ts replay --ticks=60 --verify ``` --- ## Documentation - [Arc protocol differences](docs/ops/arc-protocol-differences.md) — the six ways Arc differs from Ethereum, and which NOUMA has verified - [UI plan](docs/design/ui-plan.md) — the design system and what is deliberately not drawn - [obrain reference](docs/design/obrain-reference.md) — the figure grammar, and why no third-party images are vendored - [Deploying on Arc](docs/ops/deploy-arc.md) - [Cloudflare deployment](docs/ops/deploy-cloudflare.md) - [Circle agent wallet](docs/ops/circle-agent-wallet.md) - [V1 errata](docs/audit/v1-errata.md) — every defect in the superseded draft ## Licence and provenance The tokens and contracts are NOUMA's. **UNOMA** is a visual brand only — it names the icon set and palette in the brand delivery, not a contract or a token. The deployed token's `symbol()` is `NOUMA`.