Choosing a Verify Surface
Three packages verify motebit receipts — crypto, verifier, state-export-client. Which one you import depends on the deepest binding rung you need and whether you can use the network.
There are three motebit packages that verify receipts, and picking the wrong one is the single most common integration mistake — not because the cryptography is hard (it isn't; it's the same Ed25519-over-JCS floor in all three) but because the composition is easy to misread. This page is the map.
The decision turns on two questions: how deep a binding rung do you need, and can you make a network call?
The three surfaces
All three sit on @motebit/crypto, the zero-dependency floor. They differ in what they add on top.
| Package | Adds over the floor | Reaches | Network | Use it for |
|---|---|---|---|---|
@motebit/crypto | nothing — it is the primitive (verifyReceipt, suite-dispatch, JCS) | integrity + the sovereign-binding primitive | no | building another verifier; never call it from a UI |
@motebit/verifier | result.sovereign + formatHuman | integrity → sovereign | no (offline) | in-browser proof, the CLI — anything that must verify with no server |
@motebit/state-export-client | the relay second channel | integrity → sovereign → pinned → anchored | relay (pinned/anchored only) | the full ladder incl. operator anchoring |
Which do I use?
- "Verify a receipt in the browser, no server." →
@motebit/verifier(verifyArtifact+formatHuman). It reaches thesovereignrung offline —motebit_idis the commitment to its own signing key, so the strongest offline binding needs no relay and no chain. This is what most integrations want. - "Show the full ladder, including
anchoredagainst the operator's transparency log." →@motebit/state-export-client(verifyReceiptDocument).anchoredrequires a second channel — fetching and verifying the operator's signed transparency declaration — so this surface is online by construction. - "I'm building my own verifier UI on raw crypto." → don't. That's reimplementing one of the two wrappers above, and a sibling verifier that drifts from the spec is the worst possible artifact for a proof. Import the wrapper.
// Offline, up to sovereign — the common case
import { verifyArtifact } from "@motebit/verifier";
const r = await verifyArtifact(receiptJson);
// r.valid (integrity) · r.sovereign (the binding rung)// Full ladder, including anchored — needs the relay
import { verifyReceiptDocument } from "@motebit/state-export-client";
const view = await verifyReceiptDocument(receiptJson /*, anchor options */);The binding ladder maps to the surface
The binding rungs — integrity-only → pinned → anchored → sovereign — are not all reachable from every surface:
integrityandsovereignare offline facts (signature valid;motebit_idcommits to the key).@motebit/verifiergives you both with no network — it is the surface that computes the offlinesovereignrung.pinnedandanchoredare second-channel facts (the key was pinned against the operator's relay transparency declaration). Only@motebit/state-export-clientreaches them, because only it makes that call. It also computes the offlinesovereignrung (same@motebit/crypto.verifySovereignBindingprimitive as@motebit/verifier), so the two surfaces agree on both integrity and the offline sovereign rung —check-receipt-conformanceenforces that agreement. The practical split: reach for@motebit/verifierwhen you only need the offline rungs (smaller, browser-pure, zero network); reach for@motebit/state-export-clientwhen you also wantpinned/anchored.
So sovereign is not a weaker anchored — it's a different axis. sovereign proves the motebit_id commits to the signing key, offline; anchored proves the operator's transparency log vouches for that key. A proof brand that wants "verified with no server" should lead with sovereign; that claim is stronger, not weaker, for being offline.
The anchored upgrade path
If you start on @motebit/verifier (offline, sovereign) and later want to show anchored, you do not fork anything or invent a trick (a same-origin /.well-known/... you serve yourself is self-attestation, not anchored — the trust root is the operator's relay signature, not your origin). You graduate to @motebit/state-export-client — same family, same floor, one layer up — and accept that anchored is online where sovereign was offline.
The one rule
Never call @motebit/crypto from a UI, and never reimplement a verifier. Pick the wrapper by the deepest rung you need; the floor (@motebit/crypto's JCS canonicalization + the fixed suite) is shared, so every surface agrees on the integrity core byte-for-byte. See Verify a Receipt for the install-and-go path, and the receipts concept for the artifact family.
Verify a Receipt
The fastest correct path to verify a motebit ExecutionReceipt — install the published verifier, do not reimplement it.
The Governance Triad
Proof of permission before action — verify offline what a motebit was allowed to do (auto), what a human consented to (approve), and what governance refused (deny).