How the scheme works
For each UTC day we collect every live outcome, sort them by (clientSeed, cursor, nonce, timestamp, shortId) (clientSeed compared as raw UTF-8 bytes), hash each one into a leaf, and combine pairs upward with SHA-256 until a single root remains. The root is then written to daily_merkle_roots with a publish timestamp, together with the exact leaf list it was built from. Inclusion proofs are served from that stored list, and a published root is never rebuilt.
- Hash:
SHA-256throughout. - Leaf:
SHA256(0x00 || utf8("outcomeId|serverHash|clientSeed|timestampMs")), whereoutcomeId = clientSeed:cursor:nonce. - Internal node:
SHA256(0x01 || left(32) || right(32)). - Odd level: the last node is duplicated (Bitcoin-style).
- Empty day: root is the empty string
""andleafCount = 0.
A full reference is in the API reference, and the security overview walks through how the daily root fits into the rest of the verification chain. You can fetch any day's root at GET /api/merkle/:date and an inclusion proof at GET /api/merkle/:date/proof/:outcomeId.
Erratum: 33 days without inclusion proofs
Before 2026-09-28 a bug let a later draw overwrite a stored outcome that shared its chain position. The published roots for the days below are unchanged and still commit to the original outcomes, but one or two of those outcomes no longer exist in our database, so an inclusion proof cannot be built for any outcome on those days. Proof requests for them return an error that points here.
We recovered two more days (2026-09-09 and 2026-09-22) by searching for the overwritten outcome’s original timestamp: the only value that reproduces the published root. Their proofs work again. The bug was fixed on 2026-09-28: outcomes are now append-only and every root is stored with its leaf list.
2026-05-24 2026-06-01 2026-06-02 2026-06-03 2026-06-04 2026-06-05 2026-06-07 2026-06-08 2026-06-09 2026-06-10 2026-06-11 2026-06-12 2026-06-13 2026-06-14 2026-06-15 2026-06-20 2026-06-26 2026-07-01 2026-07-04 2026-07-05 2026-07-12 2026-07-18 2026-07-24 2026-07-27 2026-08-04 2026-08-07 2026-08-14 2026-08-24 2026-08-28 2026-09-07 2026-09-14 2026-09-19 2026-09-21
Published roots (last 30 days)
| UTC date | Leaves | Height | Root | Published | |
|---|---|---|---|---|---|
| Loading… | |||||
Verify an inclusion proof
Paste the JSON returned by GET /api/merkle/:date/proof/:outcomeId. We recompute the root in your browser from the leaf and siblings and compare it to the published root — no server roundtrip is needed.