From 5fb0f08d31c6a0d6558941a07d85f3cf168a5ba6 Mon Sep 17 00:00:00 2001 From: subheeksh5599 Date: Fri, 7 Aug 2026 13:28:19 +0530 Subject: [PATCH] feat: deploy canonical Tholos testnet instance Deploys and initializes a long-lived canonical testnet instance (contract CBFFQEFDGSLLLQKOZGHWNTSPBUWMAVKFFKYXUHCMP6WDR5Y4HN4I2C76) using BOND_SIZING.md's low-value profile: 5 XLM bond, 6h challenge window, 1% finalize reward, dedicated 3-member resolver committee. Publishes the contract id in DEPLOYMENT.md, rewrites INTEGRATION.md to frame the canonical instance as the default path, points demos/freelance-escrow at it via VITE_THOLOS_CONTRACT_ID, and exempts DEPLOYMENT.md from the never-commit-addresses CI check (documented exception in CONTRIBUTING.md). Closes #59. --- .github/workflows/ci.yml | 4 ++- CONTRIBUTING.md | 7 +++++ demos/freelance-escrow/README.md | 4 +-- docs/src/DEPLOYMENT.md | 44 ++++++++++++++++++++++++++++++++ docs/src/INTEGRATION.md | 15 ++++++++--- 5 files changed, 67 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f0046ef..64dcfb1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,9 @@ jobs: # mock addresses from the mocked test environment, not real # deployed addresses, and are committed deliberately for # reproducibility (see CONTRIBUTING.md's testing section). - if grep -rnE --exclude-dir=.git --exclude-dir=target --exclude-dir=test_snapshots '\bC[A-Z2-7]{55}\b' .; then + # DEPLOYMENT.md is excluded: the canonical testnet instance's + # contract id is published there deliberately (see CONTRIBUTING.md). + if grep -rnE --exclude-dir=.git --exclude-dir=target --exclude-dir=test_snapshots --exclude=DEPLOYMENT.md '\bC[A-Z2-7]{55}\b' .; then echo "::error::Found what looks like a Stellar contract address committed to the repo. Contract addresses must never be committed, since a deployed address can't be tied to a specific source commit without an independent rebuild. Use placeholder env vars in examples instead (see CONTRIBUTING.md)." exit 1 fi diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c09da6e..7770b24 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -188,6 +188,13 @@ deploy it yourself (or have CI do it) from the PR's actual source; a pasted addr is never sufficient proof on its own. CI blocks any literal Stellar contract address from being committed at all, as a backstop. +**One deliberate exception:** the canonical testnet instance's contract id is +published in `docs/src/DEPLOYMENT.md` ("Canonical testnet instance"), and CI +exempts that file. The point of a canonical instance is a stable, discoverable +id that integrators point at — the ban is on addresses in *application source* +and in PR *evidence*, not on documenting the canonical deployment. Everywhere +else the ban stands. + ## Commit messages One-line, imperative, conventional-commit style: `feat:`, `fix:`, `docs:`, `test:`, diff --git a/demos/freelance-escrow/README.md b/demos/freelance-escrow/README.md index a04f350..e97c5ab 100644 --- a/demos/freelance-escrow/README.md +++ b/demos/freelance-escrow/README.md @@ -46,8 +46,8 @@ point this at a deployed Tholos instance yourself: ```sh cp .env.example .env.local -# fill in VITE_THOLOS_CONTRACT_ID with a deployed contract id -# (see docs/src/DEPLOYMENT.md to deploy one) +# fill in VITE_THOLOS_CONTRACT_ID with the canonical testnet instance's +# contract id (published in docs/src/DEPLOYMENT.md, "Canonical testnet instance") pnpm install pnpm dev diff --git a/docs/src/DEPLOYMENT.md b/docs/src/DEPLOYMENT.md index f250875..a7b4922 100644 --- a/docs/src/DEPLOYMENT.md +++ b/docs/src/DEPLOYMENT.md @@ -4,6 +4,50 @@ A practical guide for deploying a Tholos instance and operating it afterward. Fo what each function does, see [CONTRACT.md](CONTRACT.md). For design rationale, see [ARCHITECTURE.md](ARCHITECTURE.md). +## Canonical testnet instance + +A long-lived, canonical Tholos instance is deployed on **testnet** for +integrators (this repo's own demos included) to point at by default, instead of +each deploying their own throwaway instance: + +| | | +| --- | --- | +| Network | Testnet | +| Contract id | `CBFFQEFDGSLLLQKOZGHWNTSPBUWMAVKFFKYXUHCMP6WDR5Y4HN4I2C76` | +| Admin | `GCULSMS2EFKYYBGVYKFIMHEE4T4OFGNVVWXDQW7HZ4E2VWDPF5HJAQQH` | +| Token | Native XLM SAC (`stellar contract id asset --asset native`) | +| `bond_amount` | 50000000 (5 XLM) | +| `challenge_window_secs` | 21600 (6 hours) | +| `finalize_reward_bps` | 100 (1 %) | +| Resolver committee | `GBR745BR3WUHXPADLUKV5J25IUFNUAXGFWFQKQCWKNSK6LKZBTDRBA44`, `GDH2Z5JRUMZCIJ72TNWZ4I337QSCFU52O5KKVF2K6IDI3ZSIHS7DQMHC`, `GAJNSUJB624FUIEWUOSZRHRXGSCDPUTCIKCD2T4QY5CPJMC7C4IR3IYM` | + +**Parameter rationale** (using the model in [BOND_SIZING.md](BOND_SIZING.md)): + +- `bond_amount` = 5 XLM: with `R_case` ≈ 20 tokens of resolver review time and + `K_spam` = 10 tolerated spam assertions per window, the low-value assertion + spam floor is `R_case / K_spam` = 2 tokens; for a public deployment the model + recommends a 2x–5x multiple, putting the bond in the 4–10 token range. 5 XLM + sits inside that band and stays affordable for the smallest assertions this + low-value instance is meant to support. +- `challenge_window_secs` = 6 h: long enough for someone who'd actually catch a + bad assertion to see it and act, without stalling finality for integrators + that assert frequently. +- `finalize_reward_bps` = 100 (1 %): a small haircut that keeps prompt + third-party finalization economically worthwhile without materially + penalizing asserters. +- Resolver committee: three dedicated, non-reused testnet identities. **These + are testnet-only stopgaps** — a canonical instance needs real, accountable + resolver identities before it should hold anything beyond play value; see + [SECURITY.md](SECURITY.md). + +This instance is the default target of the [integration guidance](INTEGRATION.md) +and of `demos/freelance-escrow` (via its `VITE_THOLOS_CONTRACT_ID` env var). +The contract id is published here deliberately; the repository's +never-commit-contract-addresses CI check exempts this file (see +[CONTRIBUTING.md](CONTRIBUTING.md)) because the whole point of a canonical +instance is a stable, discoverable id — the ban is on addresses in +*application source*, not in deployment documentation. + ## Before you deploy **This is testnet-only until audited.** See [SECURITY.md](SECURITY.md). Don't diff --git a/docs/src/INTEGRATION.md b/docs/src/INTEGRATION.md index bbf9f67..98c7edf 100644 --- a/docs/src/INTEGRATION.md +++ b/docs/src/INTEGRATION.md @@ -7,12 +7,19 @@ you're looking for the function-by-function reference instead, see ## Should you deploy your own instance, or share one? -Each Tholos deployment is initialized once with a single token, bond amount, -challenge window, and resolver committee (`initialize` in [CONTRACT.md](CONTRACT.md)). -There's no per-call override. That means: +A canonical testnet instance already exists (see the "Canonical testnet +instance" section of [DEPLOYMENT.md](DEPLOYMENT.md) for its contract id and +parameters). **Share that instance by default** and only track the assertion +`id`s that belong to you: an oracle's trust accumulates from one committee's +track record over time, and fragmenting across many bespoke deployments resets +that record for every integrator. + +A separate deployment is the **exception**, not the default path — reach for it +only when your bond size, token, or challenge window is genuinely incompatible +with the canonical instance: - If your markets all want the same bond size, token, and challenge window, they can - share one deployed instance and just track the assertion `id`s that belong to them. + share the canonical instance and just track the assertion `id`s that belong to them. - If you need different bond sizes per market (a $10 market and a $10,000 market probably shouldn't share a bond amount), deploy a separate instance per configuration, or wait for a future version that supports per-call bonds.