Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,15 @@ 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
#
# docs/src/DEPLOYMENT.md is excluded: its "Canonical testnet
# deployment" section deliberately documents the one shared,
# long-lived Tholos instance integrators should point at (see
# INTEGRATION.md), which is exactly where that address belongs.
# This exception is for that one reference table, not a general
# license to hardcode addresses elsewhere; application code and
# examples must still use placeholder env vars.
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
Expand Down
8 changes: 5 additions & 3 deletions demos/freelance-escrow/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,14 @@ client and freelancer actually agreed to pay for the milestone.
## Running it

Contract addresses are never committed to source (see CONTRIBUTING.md), so
point this at a deployed Tholos instance yourself:
point this at a deployed Tholos instance yourself. The
[canonical testnet deployment](../../docs/src/DEPLOYMENT.md#canonical-testnet-deployment)
works for this app out of the box:

```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 contract id from
# docs/src/DEPLOYMENT.md (or your own deployment, if you have a reason to need one)

pnpm install
pnpm dev
Expand Down
19 changes: 19 additions & 0 deletions docs/src/DEPLOYMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,25 @@ can be changed after `initialize`:
| `resolvers` | Odd-length, non-zero, distinct, and at most 21 addresses. `initialize` rejects duplicates with `DuplicateResolvers`. Pick people who'll actually be reachable to vote within a reasonable time of a dispute; a slow resolver committee stalls every disputed assertion until it acts. |
| `finalize_reward_bps` | Basis points (0–1000) of the bond paid to whoever calls `finalize`. `caller` must authorize the call unconditionally, even at 0. 0 means no reward: the full bond returns to the asserter. A non-zero value creates an economic incentive for prompt finalization at the cost of a small bond haircut the asserter accepts when posting. 100 bps (1 %) is a reasonable starting point; 1000 bps (10 %) is the maximum enforced by the contract. |

## Canonical testnet deployment

Before deploying your own instance, check whether this one already fits: it's
meant to be the shared, long-lived Tholos deployment on testnet, so that trust
in the resolver committee's track record accumulates in one place instead of
fragmenting across many one-off deployments. Deploy your own only if you
genuinely need different parameters (a different bond size or token, for
example); see [INTEGRATION.md](INTEGRATION.md#should-you-deploy-your-own-instance-or-share-one).

| Field | Value |
| --- | --- |
| Network | Stellar testnet |
| Contract id | `CAOSNC2SKQPGT7WHXKQJQ2RL2J7RECXE5QKZFYIMEHYA3DZTOZG76YYI` |
| `token` | Native XLM SAC (`CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC`) |
| `bond_amount` | `50000000` (5 XLM), per `BOND_SIZING.md`'s public-testnet/low-value profile |
| `challenge_window_secs` | `21600` (6 hours) |
| `finalize_reward_bps` | `100` (1%) |
| `resolvers` | `resolver1`/`resolver2`/`resolver3` test identities from this repo's own testnet workflow, a stopgap: they have no real-world accountability behind them yet. Revisit before treating this instance's dispute history as trustworthy long-term. |

## Deploying

```sh
Expand Down
24 changes: 15 additions & 9 deletions docs/src/INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,21 @@ 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:

- 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.
- 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.
Default to sharing the [canonical deployment](DEPLOYMENT.md#canonical-testnet-deployment).
Tholos is only trustworthy as an oracle if its resolver committee's track
record accumulates somewhere: one committee, one dispute history, building a
reputation over time. Fragmenting into a separate deployment per integrator
throws that away, each new instance starts with zero history and a
committee nobody's evaluated yet, which is no better than each integrator
building its own bespoke escrow logic instead of using Tholos at all.

Each deployment is initialized once with a single token, bond amount,
challenge window, and resolver committee (`initialize` in [CONTRACT.md](CONTRACT.md)),
with no per-call override, so a separate deployment is only justified when your
parameters are genuinely incompatible with the canonical one: a materially
different bond size for a much higher- or lower-value market, or a token the
canonical instance doesn't use. If that's not your situation, share the
canonical instance and just track the assertion `id`s that belong to you.

There is currently no built-in way for a calling contract to distinguish "its"
assertions from anyone else's within one instance beyond tracking the `id`s it
Expand Down