Attestations are live over REST — contracts are not deployed yetRead an attestation
Cleaton

Read an attestation

Fetch a pool's horizon and confidence, check the signature and the freshness, and refuse the allocation if the lock outruns the horizon.

Three steps end to end: fetch, verify, branch. The whole point of the design is that step three is cheap enough to sit inside a deployment path.

Fetch it#

terminal
curl -s https://api.cleaton.xyz/v1/pool/0xA0b8...eB48 \
  -H "Authorization: Bearer $CLEATON_KEY"

Reading the current attestation is metered per request. Reading one already committed to the registry on chain is free — there is no way to charge for a storage read without inserting a gatekeeper, which would defeat the point. Revenue comes from freshness, not access.

The response#

response.json
{
  "pool":          "0xA0b8...eB48",
  "chainId":       8453,
  "accountingId":  "0x9f2c...",
  "refLiquidity":  "512400000000000000000000000",
  "horizonDays":   9,
  "confidenceBps": 7000,
  "thresholdBps":  7000,
  "observedAt":    1786112400,
  "validUntil":    1786198800,
  "modelHash":     "0x4d1a...",
  "featureRoot":   "0x7b30...",
  "flags":         [],
  "nonce":         184223,
  "attester":      "0x51Ce...",
  "signature":     "0x1c8f..."
}

That reads as: this pool is expected to hold at least 70% of its reference liquidity for nine days, and across the calibration distribution at least 70% of claims made at this confidence were not breached.

Branch on it#

allocate.ts
const a = await getAttestation(pool);

// 1. The claim is worth exactly what the signature is.
if (!verify(a)) throw new Error("signature does not recover to a registered attester");

// 2. validUntil is about the ATTESTATION, not the pool. Default validity is 24h.
if (a.validUntil < now()) throw new Error("stale — request a fresh attestation");

// 3. Refuse out-of-support claims unless you have a policy for them.
if (a.flags.includes("OUT_OF_SUPPORT")) return skip(pool);

// 4. Compare against YOUR lock, not against a generic threshold.
if (a.horizonDays < lockDays) return skip(pool);
if (a.confidenceBps < 6000) return skip(pool);

await allocate(pool, amount);

Three mistakes to avoid#

MistakeWhy it bites
Treating horizon and validUntil as the same expiryA 90-day horizon issued once would otherwise be quoted for 90 days against conditions that changed on day two. Validity defaults to 24 hours.
Comparing refLiquidity to live TVLrefLiquidity is a six-hour time-weighted average under the committed accounting method, not a spot read. Comparing it to an instantaneous number will look like drift that is not there.
Ignoring flagsOUT_OF_SUPPORT means the current feature distribution sits outside every calibration stratum. The confidence on that attestation carries a weaker guarantee, and the bond terms differ.