
One order everyone can check
Sequencer, batches and ordering
A single sequencer seals activities into signed 354-byte headers that carry every Merkle root.
Every activity you submit gets a global sequence number and lands in exactly one batch, so two parties reading the chain see the same order. Sealing writes one 354-byte header over the batch number, the sequence range, the previous and resulting state roots, five Merkle roots and a millisecond timestamp, signed with Ed25519 inside an authorized batch-number range. Admission runs before ordering, so a rejected activity spends no sequence number and no fee.
What it does
LayerX runs a single sequencer that admits activities, assigns each admitted activity a global sequence number, and groups them into batches. Sealing a batch writes one 354-byte header that carries the batch number, the first and last global sequence in the batch, the previous and resulting state roots, five Merkle roots, a millisecond timestamp and the sequencer identifier. The sequencer then signs the header hash with Ed25519 under an authorization that names its identifier, public key and the range of batch numbers it may seal. Every sealed header must continue the previous one: same-plus-one batch number, contiguous sequence range, and a previous state root equal to the prior batch's resulting state root.
Key capabilities
- Assigns global sequence numbers and enforces consecutive per-account sequence numbers.
- Admits activities in a fixed order: envelope, timestamp, signature, sequence, idempotency, fee.
- Seals a batch header over activity, receipt, event, availability and oracle roots.
- Signs each header with Ed25519 inside an authorized batch-number range.
- Rejects gaps, root mismatches and non-increasing timestamps at the header level.
- Detects two different headers for one batch number and publishes equivocation evidence.
Who it's for
Agent developers and node operators who depend on a single, checkable order of activities.
Why it matters
Every activity lands at exactly one position in one ordered history, so two parties reading the chain see the same sequence. Because each batch header commits to activities, receipts, events, availability and oracle inputs, a client can verify that a specific activity belongs to a specific batch without trusting the node that served it.
Differentiators
One header carries all five Merkle roots plus the oracle root for the batch, so a single 354-byte object is enough to check activity, receipt, event, availability and oracle inclusion. Admission is decided before ordering, so a rejected activity consumes no global sequence, no account sequence and no fee. Two conflicting headers at the same batch number produce signed evidence and halt checkpointing rather than being silently dropped.
Outcomes
- Verify that an activity belongs to a batch without trusting the node.
- Gaps, root mismatches and timestamp regressions each get a distinct code.
- Two conflicting headers produce signed evidence and halt checkpointing.
Technical notes
- Caps in code:
LXP_MAX_BATCH_ACTIVITIES = 65535leaves per root list,LXP_MAX_BATCH_BODY_BYTES = 16777216, header encoded size exactly 354 bytes. - The admission queue is a bounded ring with a monotone admission-order counter; a full queue returns a length-limit error. The daemon fills at most 64 activities per batch from a 4096-entry queue.
- Continuity errors are distinct codes:
LXP_ERR_BATCH_GAP(-800) for a broken batch or sequence range,LXP_ERR_ROOT_MISMATCHfor a state-root break, andLXP_ERR_TIMESTAMP_REGRESSION(-802) for a timestamp that does not strictly increase or that jumps past the configured forward drift. - Execution reads time from the sealed header through an exec clock bound to that header, not from a local wall clock.
- The sequencer keeps the last 256 sealed headers to detect equivocation; on detection it marks checkpointing halted and publishes the two conflicting records. Sequencer loss stops admission and requires an explicit handover authorization before sealing resumes.
- Batch bodies publish to at most 32 replicas in chunks of at most 65536 bytes, and eligibility waits for a configured acknowledgement threshold.
- No batch interval is set in code, so no batch cadence or rate is stated here.
spec/layerx-protocol/docs/checkpointing.mdlists a 250 ms interval and larger activity and byte caps; those names do not appear in the headers or sources, and the two cap values contradict the code. - Reading a sealed header needs Node.js 22 or newer:
import { JsonRpcClient, decodeBatchHeader } from "layerx-sdk";
const client = new JsonRpcClient(process.env.LAYERX_RPC_URL as string);
const read = await client.getBatchHeader("1200");
const header = decodeBatchHeader(
Buffer.from(String(read.canonical_header), "hex"),
);
console.log(header.batchNumber, header.firstSequence, header.lastSequence);More in LayerX agent domain
Build on Paxeer.
Give your agent a wallet, set its policy, and settle your first call on LayerX.