Thesettlementlayerforthemachineeconomy.

LayerX agent domain

Check a paid call without a node

Receipt proofs and offline verification

Pin the signed genesis manifest, then verify a receipt and its batch inclusion from local files.

You keep the genesis manifest and a receipt, and the layerx-verify command re-derives that the sequencer signed exactly those bytes. Point it at a receipt on its own, or at a receipt with its Merkle inclusion proof and the signed batch header that commits it. It reads every input from a local file or standard input, so nothing touches a node or chain state. Refusals name the failing stage, so you can tell a bad receipt from a bad proof.

What it does

Every LayerX activity returns a receipt that the sequencer signs over its canonical encoding. The layerx-verify command pins the signed genesis manifest as its trust root, then checks either a receipt on its own or a receipt or activity together with a Merkle inclusion proof and the signed batch header that commits it. It re-encodes the input and compares the bytes, recomputes the leaf hash, folds the sibling path to the root carried in the header, and checks the Ed25519 signatures on the header and the receipt. Every input is read from a local file or standard input, so verification touches no node and no chain state.

Key capabilities

  • layerx-verify trust-root parses and signature-checks the genesis manifest, then prints the pinned authority and guarantor keys.
  • layerx-verify receipt decodes a receipt, confirms it is canonical, checks the sequencer signature, and prints its digest.
  • layerx-verify bundle folds an activity or receipt leaf into the batch header's activity or receipt Merkle root.
  • A checkpointed path binds a receipt to a guarantor certificate and a registered Paxeer settlement reference.
  • State witnesses prove one key and value into the state root across the account, module and root layers.
  • Both SDKs verify receipts, batch inclusion and checkpoints from canonical bytes in TypeScript and Python.

Who it's for

Buyers, auditors and settlement services that need to check a paid call without trusting or operating a node.

Why it matters

A relying party can keep the genesis manifest and a receipt, and later re-derive that the sequencer signed exactly those bytes, that the receipt sits at a stated index of a stated batch, and which state root it moved the network from and to. Refusals name the stage that failed, so a bad receipt, a bad proof and an unauthorised signing key are distinguishable.

Differentiators

The bundle verifier ignores the public key its input carries and checks the header signature against the key pinned from genesis, refusing anything else with LXP_ERR_AUTH_SCOPE; a responder cannot widen the trusted set. The locally rebuilt authority is narrowed to the single batch number in the presented header, so a broad batch range in the input grants nothing. Verification runs in a fixed 4 MiB arena over static input buffers, with no network access.

Outcomes

  • Verify receipts and batch inclusion from canonical bytes in TypeScript or Python.
  • Header signatures check against the key pinned from genesis, not the input.
  • Verification runs in a fixed arena with no network access.

Technical notes

  • Both the Merkle and state proof depth caps are LXP_MERKLE_MAX_DEPTH = 32 and LXP_STATE_PROOF_MAX_DEPTH = 32, and a proof is rejected unless its declared depth equals the depth implied by its leaf count.
  • CLI limits: proof bundle at most 8,192 bytes, value at most 1,048,576 bytes, wire version 1, bundle kind 1 for an activity and 3 for a receipt, canonical batch header exactly 354 bytes, at most one - stream per invocation. Exit codes are 0 accepted, 1 refused, 2 usage.
  • The receipt digest is SHA-256 over the domain tag LXP/v1/receipt plus a zero byte plus the receipt encoded without its signature; a Merkle leaf is SHA-256 over LXP/v1/merkle-leaf plus a zero byte plus the canonical bytes. A root that does not match returns LXP_ERR_ROOT_MISMATCH (-801).
  • The kernel keeps at most LXP_VERIFIED_RECEIPT_INDEX_MAX = 4096 verified receipt records in memory, each holding the digest, result code, global sequence, timestamp, asset, amount and resulting state root, with a fallback hook for anything older.
  • Not yet implemented as a library: include/layerx/lxp_verify.h declares lxp_verify_receipt_against_requirement, but it is defined in cmd/layerx-verify/lxp_verify_receipt.c, outside src/. The trust-root loader, the pinned receipt check and the bundle check also live only in cmd/layerx-verify/, so nothing outside that command can call them.
  • Checkpoint verification in the SDKs is incomplete on its own: verifyCheckpoint takes a caller-supplied LocalSignatureVerifier, because neither SDK implements recoverable secp256k1 verification.
  • Install with npm install layerx-sdk on Node.js 22 or newer, or pip install layerx-sdk on Python 3.11 or newer.
import { verifyReceipt } from "layerx-sdk";

const verified = await verifyReceipt(canonicalReceipt, {
  batchId,
  asset,
  previousStateRoot,
  resultingStateRoot,
  sequencerPublicKey,
});
console.log(verified.level, verified.receiptDigest);

More in LayerX agent domain

Build on Paxeer.

Give your agent a wallet, set its policy, and settle your first call on LayerX.