Skip to content

feat(explorer): decode Cartesi sequencer batches natively - #211

Merged
tuler merged 2 commits into
prerelease/v2from
feat/sequencer
Oct 15, 2026
Merged

tuler merged 2 commits into
prerelease/v2from
feat/sequencer

Conversation

@tuler

@tuler tuler commented Oct 15, 2026

Copy link
Copy Markdown
Owner

Why

With a Cartesi sequencer, the payloads the batch submitter posts to the InputBox are SSZ batches of signed user operations. Through a payload decoder they can only appear as one summary line plus a JSON blob, whether the batch carries 2 operations or 200. The batch envelope is protocol-defined, like portal deposits, so the explorer now decodes it itself. The application's decoder only sees each operation's data.

What

Classification and settings

  • A per-application batch submitter address, set on the Overview page. It can be shared as a ?submitter= link param, but a banner asks before a link's suggestion is adopted.
  • An input is a batch only when its sender is that address, which is how the scheduler classifies inputs. The explorer never guesses by trying to decode the bytes.

UI

  • Inputs list: a batch row reads like "Batch #0 · 3 frames · 5 user ops". Its caret unfolds the operations, showing signer, nonce, max fee and the decoded payload. A malformed batch is flagged and does not unfold.
  • Input page: a "Sequencer batch" section shows the batch nonce and submitter, then each frame with its safe block, fee price and operations.
  • User-op page: each operation has its own linkable page at inputs/:i/ops/:frame/:op.
  • User ops tab: lists operations by scanning the submitter's batches, 25 at a time, with a signer filter. The page states how many batches it has scanned so far.

Decoding (apps/explorer/src/sequencer)

  • Mirrors the scheduler: decodeBatch follows ethereum_ssz's rules, recoverUserOpSigner follows alloy's signature rules, and feeToLinear follows fee_to_linear.
  • Signers are recovered under the EIP-712 domain carried by each input (its chain id and application contract), not under the explorer's settings.
  • Pinned by 334 tests against vectors generated from cartesi/sequencer@8a7c914 by scripts/fixturegen. generate-fixtures.sh first checks that the generator uses the same crate versions as the sequencer.

Decoder contract (@deroll/decoder, minor)

  • New UserOp record and optional userOp method. input is no longer called for batches. Existing decoders are unaffected.
  • The kit README and the explorer docs page describe both.

Mock server

  • Adds signed batches to the perp-dex app: two batches with five and one operations, an empty frame, a forged signature, and a malformed submitter payload.

Not included, on purpose

Operations are labelled submitted. The explorer flags only the outcomes that follow from the bytes: a batch that fails to decode, and an operation whose signature recovers no signer. Other outcomes need more than one batch's bytes: stale or out-of-sequence batches, fee and application validation. Copying those scheduler rules into a UI risks misleading users if the copy drifts, so they are left out.

Testing

  • bunx tsc -b, bun run lint and the explorer's vitest suite (334 tests) pass.
  • Checked in a browser against the mock server with a test userOp decoder:
    • batch rows unfold
    • signers recover to the test keys
    • the forged op shows as unrecoverable
    • the malformed batch is flagged
    • the user-op page and the User ops tab with the signer filter work
    • no console errors

Follow-ups

🤖 Generated with Claude Code

With a Cartesi sequencer, the InputBox payloads from the batch submitter
are SSZ batches of signed user operations, unreadable as one summary line
plus JSON. The batch envelope is protocol-defined, so the explorer now
decodes it itself, as it does portal deposits, and hands only each
operation's data to the application's decoder.

- Per-app batch-submitter setting on the Overview page, shareable as
  ?submitter= behind a confirmation banner. An input is a batch only when
  its sender is the submitter, as the scheduler classifies it.
- Batch rows unfold into their user operations in the inputs list; the
  input page shows the batch frame by frame; each operation has its own
  page; a User ops tab scans the submitter's batches with a signer filter.
- Batch decoding, signer recovery and fee conversion mirror the scheduler
  (ethereum_ssz, alloy) and are pinned by vectors generated from
  cartesi/sequencer@8a7c914 (scripts/fixturegen).
- @deroll/decoder gains the UserOp record and the userOp decode method;
  input is no longer called for batches.
- Operations are shown as submitted: outcomes beyond a malformed batch or
  an unrecoverable signature are not derivable from one batch.
- The mock server gains signed batches for the perp-dex app.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
deroll Ready Ready Preview Oct 15, 2026 3:19pm UTC
deroll-explorer Ready Ready Preview Oct 15, 2026 3:19pm UTC

@changeset-bot

changeset-bot Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3400a86

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@deroll/decoder Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@deroll/explorer and @deroll/mock-server are private and not tracked by
changesets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tuler
tuler merged commit 252d7a7 into prerelease/v2 Oct 15, 2026
4 checks passed
@tuler
tuler deleted the feat/sequencer branch October 15, 2026 15:24

This branch was successfully deployed

2 active deployments
Preview – deroll-explorer — 3400a86c Deployed Oct 15, 2026 by vercel[bot]
Preview – deroll — 3400a86c Deployed Oct 15, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant