Skip to main content
Verifying a Tokscale receipt needs no account and no trust in the gateway: you recompute every digest locally.
The commands on this page run against local localnet evidence. The provability format is identical on public GIWA Sepolia, where the first public Usage Root anchoring is still ahead of us and tracked on Live Evidence.

What a receipt is

A receipt is a UsageReceiptV1: a narrow, immutable EIP-712 typed-data statement the gateway signs after it observes provider usage for one request and fixes the pricing snapshot that applies. It is not an x402 payment receipt, not a wallet attestation, and not an on-chain transaction. The V1 EIP-712 domain is exactly:
The domain name is quoted exactly as the gateway signs it, capitalization included, because the string is hashed into the digest. Receipts issued before the domain cutover derive a different digest and no longer validate; they were not migrated. The full field list and evolution rule are in UsageReceiptV1.

Get a receipt to verify

Retrieval from a running gateway is authenticated: GET /v1/receipts/:request_id under a project-scoped tok_ bearer key, which only ever sees its own project’s receipts. No public gateway origin is published yet, so that route is not reachable today. See Gateway API. Verification does not need one. The published cross-language vector fixture is a complete receipt payload carrying its committed digest, signature, and recovered signer, and the steps below reproduce it from that payload alone. The fixture’s signing key is a development-only Anvil key: it is fixed public test data, not an operational secret.

Verify the signature yourself

Given the receipt’s typed data and signature, verification is mechanical.
1

Recompute the EIP-712 digest

Rebuild it from the domain above and the UsageReceiptV1 fields exactly as serialized:
Field order, integer widths, and the costUsd scale of 1e-4 USD units are part of the immutable schema.
2

Recover and check the signer

Recover the signer from the ECDSA signature and look the envelope’s signerAddress up in the gateway’s signer registry under the receipt’s signerVersion. That field is not receiptSchemaVersion: the schema version is fixed at 1 for every V1 receipt, while signerVersion names the registered key generation the envelope was issued under. V1 receipts are EOA-signed; a future contract-wallet signer must use an explicit ERC-1271 path, never an ECDSA fallback.
3

Recompute the leaf and hash the sibling path

Build the wallet-bound receipt leaf under the merkle domain TOKSCALE_RECEIPT_LEAF_V1, then hash up the sibling path with TOKSCALE_RECEIPT_NODE_V1 domain separation.
4

Compare against the attested root

Check that the computed root equals the epoch’s attested receiptRoot, then resolve the EAS attestation UID and schema UID on-chain.
The web app ships exactly this as a public tool at /receipts/verify: the holder pastes or deep-links the typed-data payload, the page recomputes the digest client-side with viem’s verifyTypedData, resolves the signer through the registry, recomputes the leaf, and renders the merkle path to the attested root with the attestation UID. No login is required, and disclosure stays holder-controlled.

The provability chain

One request becomes public evidence through four hops:
Because each hop is a hash or a signature you can recompute, a single receipt proves inclusion in an epoch without revealing any other request in it. One attestation anchors the whole epoch: 1M or 100M requests. Same on-chain cost. The attestation format is specified in Receipt Attestation.

Cross-language vector checks

The protocol is locked by fixed test vectors verified three independent ways: Rust (Alloy), TypeScript (viem), and Solidity (forge), so no single library is trusted twice. The receipt vectors run under one target, covering domain, digest, signature, and recovered signer:
The attestation vectors add the on-chain decoding path via forge test --match-contract ReceiptAttestationV1Test:
The full index with markers is in Verification Log.

Verification in the browser

The sealed harness proves the in-browser path end to end: a Playwright container with no credentials verifies a real issued receipt through /receipts/verify and seals the artifacts.
Today the browser verifier runs against localnet evidence, and local evidence carries no Sepolia explorer links. Once the first public Usage Root lands, the same page verifies receipts against the public attestation on sepolia-explorer.giwa.io. The verification steps do not change; only the provenance label does.

Next steps