Proof of Data
App
Open the app
Seal, rent, verify, waitlist.
Seal a plate
Encrypt a file in this browser to the enclave key.
402
Rent a query
Quote an aggregate and pay it over x402 in USDG.
Verify the enclave
Check a TDX quote against the onchain registry.
The Armour
The model its uploaders own. Trains when the enclave is live.
Join the waitlist
Uploads open in waves, in sign-up order.
Read
Protocol
Documentation
Dev log
X
Protocol

Sealed data, rented by the query

The whole mechanism in one document: who holds what, what each contract checks, where every USDG goes, and how a leak is proved and paid for. Edition of 19 October 2026.

Roles

Uploaders seal plates and are paid. Renters deposit USDG and pay per query. Operators run an Intel TDX enclave and bond $POD behind it. The keeper watches canary traps, the facilitator settles x402 payments, the publisher (inside the enclave) posts daily epochs. The timelock owns every parameter.

Plates

A plate is one file and its type. The browser seals it with HPKE (X25519, HKDF-SHA256, AES-128-GCM) to the enclave's attested key, with the type and enclave id as associated data. Plates.register accepts a plate only from an active enclave signer and only with the owner's EIP-712 Seal(cipherHash, kind, size, enclaveId, owner) signature. Invariant: live = Σ liveByKind, and a deleted plate never counts again.

The enclave

The CVM's TDX quote binds the image (keccak256(MRTD ‖ RTMR0 ‖ RTMR1 ‖ RTMR2), on the timelock's allowlist) and report_data[0:32] = sha256(sealPub ‖ signer). Enclaves.register stores the image hash, the quote hash, the signer, the sealing key hash and the enclave canary root, and pulls the bond. Anyone checks the quote with the verifier.

Queries

Price for an aggregate reading n plates, in micro-USDG: ceil(n × 10000 / 100), refused when n < 25. An Armour call costs 2000. Meter.settle requires the enclave signer's EIP-712 receipt, a renter deposit of at least 5 USDG with no withdrawal pending and no open case, the exact quoted price, and an EIP-3009 receiveWithAuthorization for it. Each query id settles once.

The split

ShareQueryArmour call
Uploaders, via Epochs70%100%
Armour treasury15% minus the operator0
Operator of the enclave5% of revenue0
Burn reserve15%0

Rounding: uploaders and burn round down, the Armour takes the remainder, so the four parts always sum to the price (fuzzed in the tests).

Epochs

Once a day the publisher, inside the enclave, turns the day's receipts into each uploader's total, pro-rata to the plates each query read, and posts a merkle root to Epochs with the total. A root can never commit more than the contract's uncommitted balance. Uploaders claim to their account, or the relayer claims for them; funds always go to the account. Leaf: keccak256(keccak256(abi.encode(account, amount))).

Canaries

Each renter view has its own canary rows, committed as a merkle root before its first query. Revealing a canary secret with its proof opens a case and freezes the renter's deposit. 48 hours to dispute; undisputed cases finalize by anyone and move the whole deposit to Epochs. A disputed case goes to the arbiter. Enclave canaries, never shown to any renter, slash the operator's bond the same way.

The bond

100,000 $POD per enclave. Exit takes 7 days and the bond stays slashable until it is withdrawn. Slash: 50% to 0x…dEaD, 50% to Epochs for the uploaders.

The burn

burnBuy(minOut) is permissionless, at most once every 60 minutes, for at most 0.5% of the pool's USDG depth, with a 1% tip to the caller. The Meter measures the $POD that reached the dead address and reverts if it is below minOut. The route is set by the timelock once the $POD pool exists. The house services never call it.

The Armour

A LoRA adapter (rank 8) on Qwen2.5 0.5B Instruct, trained weekly on CPU inside the enclave on live text plates, canaries and deleted plates excluded, with at least 25 text plates. Weights stay in the enclave. It trains when the enclave is live.

Parameters

Price per 100 plates0.01 USDG
Armour call0.002 USDG
Operator share5% of revenue, at most 15%
Minimum deposit5 USDG
k floor25 plates
Challenge window48 hours
Withdrawal notice48 hours
USDG0x5fc5360D…F1d168
Enclaves0xc83bff8d…3B1288
Plates0x1f458896…4170F2
Meter0xf5451fa3…bC47EE
Canaries0xA7700813…41449C
Epochs0x9e38b1a6…6B792F
Timelock0xC10cc3DC…31509C

Timelock and security

Every parameter (prices, operator share, minimum deposit, image allowlist, bond size for new enclaves, the burn route, the Armour treasury, the arbiter) changes only through a 48 hour timelock with no admin. The split percentages, the k floor, the challenge window and the burn limits are constants. The Epochs owner can withdraw, as with every distributor of ours, and any withdrawal past what is uncommitted shows onchain as a shortfall. The contracts are tested with unit, fuzz and fork tests against the chain's USDG; they have not been audited.