ExchainDocs
DocsAPI

Verification and securityVerify a decision

Verify a decision

Check a decision against Exchain's signed journal and the Cardano mainnet anchor, and read a wallet's signed worst case.

Check any decision yourself, three ways from quickest to strongest, and read the wallet's signed worst case.

What each method proves

MethodNeedsProvesDoes not prove
Journal page in the browserNothingMerkle path to the wallet root, the wallet root's Ed25519 signature, the path to the run root; shows the anchorDoes not recompute the leaf; does not check the anchor on chain
exchain-verifyThe decision JSON (token-gated), the wallet root, publisher.jsonRecomputes the leaf, matches it to the request, checks inclusion and the signed rootDoes not check the run-root path, the anchor transaction or auditHead
Manual anchor checkA Cardano mainnet explorerThe run root is in a Cardano mainnet transaction under metadata label 1958—

The journal's layers and files: Journal. x402 sellers check a payment's guard receipt: Guard receipt.

In the browser

Search a decision id, wallet id or transaction hash on journal.exchain.network. The status shows how far the decision is committed:

StatusMeaning
pendingNo root includes the decision yet
signedIn a signed wallet root; no anchor has landed for its run yet
anchoredIts own run is anchored on Cardano mainnet
coveredA later run's anchor is the first to land after this decision's run

With exchain-verify

Ask Exchain for the exchain-verify binary.

Get the inputs

InputWhere
DecisionGET /v1/decisions/{decisionId} with a node or read token, or proofs/<decisionId>.json from the evidence bundle
Roothttps://journal.exchain.network/<walletId>/<epoch>.json (the decision's proof.epoch), or latest.json
Keyhttps://journal.exchain.network/publisher.json

Run it

Verify offline
exchain-verify \
  --decision decision.json \
  --root wal_01J9XK3M4N5P6Q7R8S9T0V1W2Z/42.json \
  --publisher publisher.json \
  --offline

--offline refuses any http(s):// source.

Read the output

Output
decision  dec_01J9XK3M4N5P6Q7R8S9T0V1W2X   wallet wal_01J9XK3M4N5P6Q7R8S9T0V1W2Z   outcome ALLOWED
leaf      recomputed == proof.leaf
request   1 intent(s) == bound members (purchase, output, amount, asset, counterparty, job, agent)
inclusion index 3 of 8   path 3   root 9c1f…  OK
root      epoch 42   published 2026-11-05T10:00:00Z   signature OK (publisher <key hash>)
anchor    tx <anchor tx hash>  slot <slot>   (verify on any explorer)
VERIFIED  no access to Masumi or Exchain was required
Exit codeMeaning
0Verified
2Mismatch. The failing line ends in FAIL and the tool prints NOT VERIFIED
1Usage, read or parse error, or the decision has no proof yet

The anchor line is informational: check it on chain with the next section.

Check the anchor on Cardano

Find the run root

Take proof.globalRoot from the journal's decision file d/<decisionId>.json, or the root of the matching entry in anchors.json.

Read the anchor metadata

The anchor is a Cardano mainnet transaction with metadata label 1958. Open it on any explorer and read { v: 1, root, walletCount, epochRange }: root must equal the run root.

Climb to the run root

Hash proof.walletRoot up proof.globalPath with SHA-256(left ‖ right), pairing a lone node with itself, and compare the result with the run root.

Bound statement

GET /v1/wallets/{walletId}/bound (node or read token) returns the wallet's worst case at one block, signed as a JWS by the journal key.

FieldMeaning
v, walletId, issuedAtStatement version, the wallet, when it was signed
rail, network, assetcardano or x402; cardano:preprod, cardano:mainnet or eip155:<chainId>; the wallet's first governed asset
slot or blockThe Cardano slot or EVM block the statement was read at
honest, worstCase, worstCasePartsThe honest-case amount, the worst-case amount, and the parts of the worst case
assets[]On Cardano, the same three amounts for each governed asset
statementThe JWS over the statement

On Cardano, worstCase is the lesser of what the wallet holds and what remains of the on-chain period limit (walletValue, periodRemaining). On an EVM Safe, it is the Safe's balance of the asset plus its Permit2 approval, plus the treasury's allowance per period when treasurySafe is set (safeBalance, permit2Approval, treasuryAllowancePerPeriod). Chain errors return 502 rpc_failed or 503 chain_unavailable.

Evidence bundle

GET /v1/wallets/{walletId}/evidence.zip?from=&to= with a node or read token returns a wallet's history for offline checks.

FileContent
README.txt, VERIFY.mdInstructions
mandate.jsonThe mandate
decisions.jsonlEvery decision in the range
roots.jsonlEvery signed wallet root
publisher.jsonThe publisher key
proofs/<decisionId>.jsonOne proof per decision

The default range is the last 30 days. Bundles over 50 MB return 413; narrow from and to.

On this page