# TON PRIMES > A number-theory game on TON. Integers are minted strictly sequentially as NFTs for a flat > 1 TON: composites require a submitted prime factorization, primes require on-chain > Miller–Rabin. Every mint is split five ways, and the residual is injected into a ratchet > whose internal floor price `p_f = T / S` is strictly increasing on every mint — a > contract-verifiable invariant, not a promise. Status: pre-launch. Testnet only — no mainnet deployment, no real money. The design principle that shapes everything here is that every economic claim must be a contract-verifiable invariant, and every number the interface shows must map to a public get-method. `CONCEPT.md` is the specification the contracts are written against, and it is sectioned so each rule can be checked against the code. ## Specification - [CONCEPT.md](https://primes.live/docs/CONCEPT.md): The full spec. §3 assets, §4 core loop and the mint split, §5 tokenomics and the ratchet theorem, §6 genesis, §7 primorial eras, §8 anti-abuse, §9 distribution and the UI honesty rule. - [FAQ.md](https://primes.live/docs/FAQ.md): Plain-language "why is it built this way" — one entry per design decision, each citing the CONCEPT.md section that settles it. Rendered as a page at [/faq](https://primes.live/faq); the two are the same file. - [math-note.md](https://primes.live/docs/math-note.md): The ratchet proof — why `k < 1` forces `p_f` to be monotonically increasing. ## Audit surface - [/verify](https://primes.live/verify): The four claims in one page, each next to what checks it — no code-upgrade primitive in any contract, the whole outbound-message table (every place TON can leave a contract, classified by destination), the single `K_CEIL` clamp that keeps `k < 1`, and `S` never decremented. Carries the per-contract code hashes and the rebuild procedure. Every figure on it is parsed from the documents below rather than re-typed. - [contract-surface.md](https://primes.live/docs/audit/contract-surface.md): Every contract's get-methods and message opcodes, regenerated from HEAD. - [parameter-provenance.md](https://primes.live/docs/audit/parameter-provenance.md): Where each economic constant comes from. Simulation-derived values live in `shared/params.json`; a number traceable to neither the sim nor CONCEPT.md is a bug. - [known-limitations.md](https://primes.live/docs/audit/known-limitations.md): What is not done, not proven, or deliberately out of scope. - [withdraw-surface.md](https://primes.live/docs/audit/withdraw-surface.md): Every `createMessage` site across all contracts, classified by who the destination is. TON only leaves a contract through an outbound message, so this set is the set of ways money can move — CONCEPT.md §8's "no admin withdraw path" reduces to a property of it. - [privileged-credentials.md](https://primes.live/docs/audit/privileged-credentials.md): The other half of the sentence above. § 8 is a claim about moving TON, and three standing credentials do exist — the venue timelock's proposer and two signing keys — none of which can move a TON balance. Each one's powers, limits, publishing get-method and bounding test, enumerated from the contract sources rather than from memory. - [key-loss.md](https://primes.live/docs/audit/key-loss.md): The failure half of the page above. What stops working the day each credential is lost, whether the system degrades or halts, and — said in those words where it is true — which of them cannot be replaced without a genesis redeploy. Includes the coupling most likely to be missed: the venue proposer is a subwallet of the operator's gas wallet, so losing the replaceable one loses the unreplaceable one with it. - [index-rebuild.md](https://primes.live/docs/audit/index-rebuild.md): The recovery path for the day the backups are gone. Everything the indexer holds is derived from chain events that are still on chain, so it can be rebuilt — and on 2026-09-17 it was, from an empty database, in 16.7 s, reconstructing a byte-identical `tx_hash` to the running index. Carries the measured wall-clock, the per-cycle bound the estimate rests on, and the three gaps the run exposed. - [invariant-coverage.md](https://primes.live/docs/audit/invariant-coverage.md): Which of the must-never-break invariants have a named test proving them, and which do not. - [threat-model.md](https://primes.live/docs/audit/threat-model.md): What an attacker, an operator or a bug could do, and what stops each. - [reproducible-build.md](https://primes.live/docs/audit/reproducible-build.md): The pinned toolchain, the build procedure, and the code hash every contract compiles to. - [read-proxy.yaml](https://primes.live/docs/api/read-proxy.yaml): OpenAPI 3.0 for the read API every number on the site is fetched through. Each response carries a `provenance` object naming the get-method and contract address the figure came from, so a reader can re-run the call themselves — that is CONCEPT.md §9.1 on the wire rather than in prose. - [read-index.yaml](https://primes.live/docs/api/read-index.yaml): OpenAPI 3.0 for the indexer read API — the aggregate, historical and per-wallet views that no single get-method answers. - [/docs/audit/](https://primes.live/docs/audit/): The whole pack — twenty-two documents, with a one-line summary of each and the order to read them in. The ten linked above are the entry points; the index names the rest (money arithmetic, sender gates, bounce coverage, the test inventory, the genesis emission curve, secrets posture, TEP-64 conformance). ## Playing from a program Programs are welcome players, and nothing below is a promise beyond what CONCEPT.md §8 already prices for them (§9.10 states the stance). No contract path has a cooldown, per-wallet cap or proof-of-humanity; every read surface is anonymous with `CORS *`; every write is a TON message any wallet can sign. Two packages are published so you do not have to build the loop by hand. Both sign locally: there is no hosted endpoint, no API key, and no service of this project ever holds a player's key. With no mnemonic set, both are read-only and refuse to sign before any network call is made. - **`@ton-primes/agent`** (npm, MIT, Node ≥ 20) — the TypeScript SDK. Sixteen actions (`mint`, `bid`, `openLot`, `closeLot`, `openBuild`, `proveInput`, `sendGenerator`, `closeBuild`, `expireBuild`, `claimTribute`, `topUp`, `claimDiscovery`, `annotate`, `flush`, `swap`, `openHeadLot`), each pre-checking the contract's own asserts against a live get-method read before a wallet opens, plus the reference arithmetic the contract uses (`factorize`, `isqrt`, `isProbablePrime` — deterministic Miller–Rabin over the same 13 bases). `npm install @ton-primes/agent`. - **`@ton-primes/mcp`** (npm, MIT) — a stdio MCP server whose tools are one SDK call each: 35 tools, 21 reads and 14 writes. Every write quotes what it will spend and sends only on `confirm: true`; the three irreversible ones say so in the quote. Run it with `npx -y @ton-primes/mcp`, or add it to Claude Code with `claude mcp add ton-primes -- npx -y @ton-primes/mcp`. Configuration is environment variables only: `PRIMES_MNEMONIC` (unset = read-only), `PRIMES_NETWORK`, `PRIMES_REFERRAL_KEY`, `TONCENTER_API_KEY`. Scripted play is encouraged, not merely tolerated. Every strategy below is a computation over public get-method state, and none is a promise of return: §8 prices every automated loop at the floor (`k · β · P < P`) and §8.1 publishes the one regime where that inverts. - **Wait out the clock.** `k(t)` ramps from `k_min` to `k_max` over `T_ramp` since the last mint and then holds (§5.1). Mint near the top of the ramp and the rebate is the largest the ratchet allows — still `k < 1`, so the floor rises on your mint like on any other. - **Search the graph.** D-107's discovery bounties are finite, first-come windows over a deterministic graph below 10⁶ (§3.2.2), paid only when the built RESULT IS PRIME. The SDK repo ships `examples/prospector.ts`, which enumerates every target a wallet can reach, rarest operation first, and drops the ones someone is already building. - **Run under your number.** A referral key is a number you own (§4.1, §9.2); set it and the 10% referral line on every mint your program makes is paid back to you. - **Trade the floor band.** The ratchet buys only at or below `p_f = T / S` and `flush()` is permissionless (§4.3.1). Verify the floor from the two counters, trade PRIMES around a bound you computed yourself, and call the flush when the market sits under it. The floor is an accounting ratio and a standing bid, not a peg; the AMM can trade below it. - **Price a prime lot.** A prime at its turn descends from `P0(p)` toward `max(NPV(p) / 2, P0(p) / 3, MINT_PRICE)` over seven days and parks there (§4.4, D-88). Its tribute NPV is a sum over the composites it divides — all public — so value the lot from chain state and bid when the curve crosses your number. The same loop by hand, over plain HTTP: 1. **Read the head.** `GET /api/ledger/head` (read-proxy; `/api/ledger/floor` for `p_f`) — the next integer to be minted, with `provenance.getMethod`. Anything you are about to spend against must be re-read live from the chain by the get-method the provenance names; the index (`/idx/*`) is for browsing (CONCEPT.md §9.1). 2. **Prove it.** A composite mints with its factorization plus `⌊√p⌋` per factor; a prime with nothing — the contract runs Miller–Rabin itself. `shared/factors.ts` (`encodeFactors`, `isqrt`) and `shared/primality.ts` (`factorize`, `isProbablePrime`) are the reference helpers; `shared/opcodes.ts` holds every opcode; `shared/schemas/*.tlb` is the wire format. 3. **Send 1 TON plus a fee margin** to the ledger with the `mint` body. Set the referral key to a number you own and its owner is paid 10% of your own mint (§4.1); set none and that line goes to the pool, never to the team. 4. **Verify** by get-method: `getOwner(n)` on the collection, `p_f = T / S` on the ratchet. Every figure the site shows is recomputable this way, which is the whole point. Other write paths, all permissionless: `open_lot`/`bid` on the market for any number ahead of the head (§4.4 — opening is the first bid; winning mints in the closing transaction); `open_build` on the ledger, then `prove_input`/`close_build` on the registrar, for constellations (§3.2.2 — a build is named by (target, registrant), so anyone may open a target someone else is building; free of TON, first confirmed close wins it, and D-107's discovery bounties are a finite first-come window over a deterministic graph, which is a search problem); `flush()` on the ratchet (§4.3 — TON has no scheduler, so the protocol relies on someone calling it). Limits: read-proxy 600 requests/min per IP, read-index 120/min, `429` with `Retry-After` (ops/rate-limit-budget.md). Throttle at your client. Sign locally with a dedicated wallet funded with what you are willing to spend. Reference headless senders: `contracts/scripts/ proveDutchBuyLive.ts`, `phase4ConstellationBuildLive.ts`, `backend/keeper/`. ## Live surfaces - [The app](https://primes.live/): Client-rendered. `/how` explains the loop, `/verify` is the auditor's page, `/governance` is the treasury and its vote, `/n/` is one integer's page, `/auction` is the market. - [Collection metadata](https://primes.live/nft/2.json): TEP-64 metadata for minted number 2. `/generator/.json` and `/constellation/.json` serve the two other collections.