{"service":"Elara Receipts — paid post-quantum verification (x402 on Algorand)","paid":["POST /verify/record ($0.005)","POST /authority/check ($0.02)"],"free_verifier":"https://crates.io/crates/elara-verify (same verdict logic, offline)","attestation":{"alg":"Ed25519","pq":false,"key_id":"9eb858f6e154f927","public_key_raw_b64":"z7Mpsyv0L0D6CBiVYZoB3BnVNTMbP0cFCm2JapZX9DI=","about":"paid calls return an Ed25519 (classical) countersignature bound to the Algorand payment transaction id; the exact signed string is attestation.canonical_signed; see GET /attestation-key"},"existed_by":{"what":"Every paid response carries existed_by: a SHA-256 digest bound to that call's exact attestation signature, submitted at response time to three public OpenTimestamps calendars run by three operators, which later commit it to Bitcoin. The Worker returns only PENDING proofs and keeps no copy; the holder upgrades and verifies them with any OTS client.","claim":"An upgraded proof shows the attestation — and so the signature over {input hash, verdict, payment id} — EXISTED BY the Bitcoin block time. It does not show when it was created, only that it was not created later. status 'pending' proves nothing yet; a pending proof is an unsigned calendar reply that anyone could forge, and only the calendar's own lookup at upgrade_url binds it. The Worker never emits 'anchored'.","rule":{"name":"elara-existed-by-v1","digest":"SHA-256( 'elara-existed-by-v1' || 0x00 || canonical_signed || 0x00 || signature_raw )","canonical_signed":"the exact newline-separated string that was signed: 10 lines, LF separators, no trailing newline (attestation.canonical_signed)","signature_raw":"base64-decode attestation.signature_b64 (64 bytes)","note":"Recompute the digest yourself from those two values; never trust the digest we print."},"test_vector":{"canonical_signed":"elara-attestation-v1\nalg=Ed25519\npq=false\nkid=9eb858f6e154f927\nnet=algorand-mainnet\nres=verify/record\nin=1111111111111111111111111111111111111111111111111111111111111111\nout=2222222222222222222222222222222222222222222222222222222222222222\npay=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\nat=2026-09-05T20:00:00.000Z","signature_raw_hex":"000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f303132333435363738393a3b3c3d3e3f","digest_sha256":"a9e2f04965bd2ea2661371ad66a70a332af0fe21127bb43c50321af51415ba2a"},"reproduce":{"python":"hashlib.sha256(b'elara-existed-by-v1' + b'\\0' + canonical_signed.encode() + b'\\0' + base64.b64decode(signature_b64)).hexdigest()","shell":"{ printf 'elara-existed-by-v1\\0'; printf '%s' \"$CANONICAL_SIGNED\"; printf '\\0'; printf '%s' \"$SIG_B64\" | base64 -d; } | sha256sum","footgun":"$(cat file) strips a trailing newline and echo adds one — use printf '%s' with the exact string; the signed string has no trailing newline."},"ots":{"pending_proof":"base64-decode existed_by.proofs[i].ots_b64 into proof.ots (a DetachedTimestampFile over the 32-byte digest); `ots info proof.ots` shows the calendar URI and the commitment","check_progress":"GET proofs[i].upgrade_url: 200 = upgraded proof bytes; 404 with body 'Not found' = the calendar has no such commitment (worthless); 404 with any other body = accepted and waiting for Bitcoin. Do not match on the exact wording.","upgrade":"ots upgrade proof.ots   (after the calendar's Bitcoin transaction has 6 confirmations — typically hours)","verify":"ots verify -d <digest_sha256> proof.ots   (needs a Bitcoin node or a block-explorer backend; recompute the digest first)","stamp_yourself":"ots stamp over the 32-byte digest at any later time yields an existed-by from YOUR stamping time; the Worker's submission is a convenience, not an authority."},"time_bracket":{"upper_bitcoin":"issued_at <= the proof's Bitcoin block time (+ ~2 h clock tolerance) — hard, once upgraded","upper_payment":"issued_at <= block time of payment_txid — hard and free: the attestation is signed BEFORE settlement submits the payment","lower_payment":"issued_at >= round time of the payment transaction's firstValid — the id cannot be referenced before the transaction exists","width":"the two payment bounds bracket an honest issued_at to the transaction's validity window (~30 s with default client settings); the Bitcoin bound is what stops a re-minted attestation from pointing at an old payment"},"latency":"adds up to 0.8 s to a paid call (three concurrent submissions under one shared deadline). The deadline is a budget against the payer's settlement window, so 'unavailable' is returned rather than risking a late settle.","privacy":"the calendars receive a 32-byte digest, the Worker's egress IP and the timing of the call (correlatable with the public Algorand payment). No record content leaves the Worker; the payment facilitator does not receive the response body.","key_rotation":"existed_by is bound to the signature, so rotating the attestation key changes nothing about older proofs: a proof shows the attestation existed while that key was current — 'signed by a key that was once current' — which is exactly the claim a verifier needs."},"try_it":{"about":"Runnable bodies for both paid routes, byte-identical to the fixtures the open-source repo ships — so a first paid call is a copy-paste, not a from-scratch ML-DSA-65 record.","free_first":"Both bodies give the same verdict offline, for free, with the elara-verify crate. A paid call adds an Ed25519 attestation bound to your own payment transaction id, plus existed_by, not a different verdict.","declined_calls_are_free":"Any response >= 400 cancels settlement, so a body this tier declines (413 over the size cap; 422 SPHINCS+, too many carriers, or a body in which nothing could be checked) costs nothing. Enforced by test, not by promise.","routes":{"POST /verify/record":{"body_url":"https://raw.githubusercontent.com/navigatorbuilds/elara-mesh/master/examples/verify/sample-record-profile-b.json","repo_path":"examples/verify/sample-record-profile-b.json","verdict":"VERIFIED","expect":"verdict VERIFIED — a real signed Elara record, Dilithium3 only (Profile B)"},"POST /authority/check":{"body_url":"https://raw.githubusercontent.com/navigatorbuilds/elara-mesh/master/examples/verify/mandate-bundle-valid.json","repo_path":"examples/verify/mandate-bundle-valid.json","verdict":"CONSISTENT","expect":"result.verdict CONSISTENT, flag valid, authorized true — a one-hop grant chain inside its window"}},"not_on_this_tier":{"examples/verify/sample-record.json":"SPHINCS+ dual-signature record: 422 here (over the edge CPU budget). Verify it free and offline with the elara-verify crate — same verdict logic.","examples/verify/sample-record-TAMPERED.json":"also SPHINCS+, and a deliberately tampered negative fixture: 422 here for the signature-scheme reason, before the tamper is ever reached."}},"project":"https://github.com/navigatorbuilds/elara-mesh","client_example":{"url":"https://elara-verify-x402.aivelikivodja.workers.dev/client-example.mjs","about":"copy-paste client: `node client-example.mjs` is a dry run (no wallet, nothing paid: it prints the runnable body and the 402 terms); `--pay` makes one paid call with @x402/fetch + @x402/avm and your own Algorand wallet. It refuses to pay from this service's own wallet.","key":"AVM_MNEMONIC takes the 25 words a wallet exports and converts them in memory; AVM_PRIVATE_KEY takes the base64 64-byte form if you already have it. Neither is printed, logged or written.","gas":"none. The facilitator advertises a fee payer in the 402 (accepts[0].extra.feePayer) and @x402/avm builds your transfer with fee 0 against it, so the call spends no ALGO: an account that already holds USDC needs nothing else."}}