The trust root is a 3-key notary federation. Each notary independently fetches a CEX price over TLS and signs (serverName, sourceId, price, timestamp, cycleSeq) with their Schnorr key.
Publishers are interchangeable relays — they cannot fake notary sigs. The covenant enforces everything else: ≥7 distinct publishers per cycle, monotonic time, position-checked median, threshold ratchet with 10%/cycle decay. No admin keys.
How to consume the price NFT
Spend a Ticker NFT (mutable, anyone-can-spend) as a tx input. The Ticker covenant requires identical re-emit at the same output index. Your tx becomes a chain-descendant of the Oracle.update — BCH consensus refuses to confirm it in any chain that excludes the Oracle update. Atomic co-finality.
Read price and lastTs from the input's 17-byte commit. Reference example: contracts/v10/examples/PriceGatedRelease.cash.
Run a notary or publisher
Notary: HTTP daemon that holds one of the 3 federation Schnorr keys. Publisher: daemon that requests notary sigs, mints VA NFTs, broadcasts Oracle.update. ~12k sats/cycle.
Code at contracts/aggregator-v0/scripts/ticker-node.ts. No registration, no allowlist. Repo private during chipnet validation.
usd.ticker.cash · v10.0.0 · chipnet
Where is the trust?
The trust root is a 3-key notary federation. Each notary independently fetches a CEX price over TLS and signs (serverName, sourceId, price, timestamp, cycleSeq) with their Schnorr key. The Oracle covenant trusts these signatures and nothing else off-chain.
Publishers are interchangeable relays. They request a notary signature, pay tx fees, broadcast. They have no special role and cannot fake notary sigs. Anyone with chipnet funds can run one.
The covenant is the only on-chain rule. It enforces: ≥7 distinct publishers attest per cycle (the quorum ratchets up with active committee), notary-attested time is strictly forward, the median is position-checked, the threshold-ratchet bleeds 10%/cycle so a single spike doesn't lock the system.
No admin keys. No upgrade path. The Oracle UTXO chain is self-perpetuating; the only way to update behavior is to deploy a new covenant at a new address.
What the federation can do if all 3 notaries collude: fast-forward time within a 7200-second-per-cycle stride cap, sign attestations for arbitrary prices. What the federation cannot do: rewind time, skip the quorum check, hide a cycle from observers, run faster than ~1 cycle/minute (notary throughput cap).
How to consume the price NFT
Each cycle mints 4 Ticker NFTs at the address shown in §3. They are mutable (capability 0x01), anyone-can-spend, and self-replicate via the Ticker covenant. A consumer's tx that spends a Ticker becomes a chain-descendant of the Oracle.update that produced it — BCH consensus refuses to confirm the consumer's tx in any chain that excludes the Oracle.update. That is co-finality, atomic by construction.
Minimal tx shape:
input[0] — your consumer contract
input[1] — Ticker NFT from the pinned Oracle category
output[0] — your business logic (payment, mint, settle…)
Read price and lastTs from tx.inputs[1].nftCommitment. The 17-byte layout is 0x80 | seq(4) | lastTs(4) | medianPrice(8). Use medianPrice / 10⁸ for USD. Pin the Oracle category as a constructor arg (LE-reversed) so an attacker can't feed you a Ticker from a different oracle.
A working reference covenant (PriceGatedRelease — locks BCH, releases on price ≥ strike) lives at contracts/v10/examples/ in the source tree, ~286 bytes compiled. Drop your own freshness gate on lastTs (avoid tx.locktime; that introduces a chain-MTP lag that v10 was designed to escape).
Run a notary or publisher
Notary: a stateless HTTP daemon that holds one Schnorr key from the OR-list. Exposes POST /sign; on each request fetches the current price from its assigned CEX, signs (serverName, sourceId, price, ts, cycleSeq), returns the signature. The federation's three keys live independently — separate hosts, separate operators. Add a fourth notary by deploying a new Gateway covenant with the extended OR-list.
Publisher: a daemon that polls the Oracle UTXO, requests notary signatures for its assigned source, mints a VerifiedAttestation NFT via the Gateway, waits ~25 s for peer VAs from other publishers, then builds and broadcasts the Oracle.update tx consuming all VAs. First publisher to broadcast wins the cycle; losers retry on the new tip. A publisher needs ~12 k sats per cycle (VA mint + Oracle.update share of fee + Ticker dust).
Unified binary:scripts/ticker-node.ts wraps both daemons. Run as ticker-node --notary --slot 0, ticker-node --publisher --slot 0, or both flags together. Federation operators bundle both for their slot (no HTTP roundtrip for own attestations); community operators run publisher-only.
No registration. No allowlist. Run as many publishers as you can fund — they compete to land the cycle, but they all contribute their attestation toward the median.