Skip to main content
Source code: github.com/agglayer/aggkit (tools/exit_certificate, tools/exit_certificate_claimer)

Overview

The Exit Certificate Tool decommissions an Agglayer-connected chain by producing one final certificate that moves every value-holding balance back to a destination network, then serves the claim proofs that end users need to withdraw those balances on L1. It ships in AggKit as two standalone binaries: The two binaries are built with make build-exit_certificate and make build-exit_certificate_claimer and are also included in the AggKit Docker image.

When to use it

Use this tool to sunset an Agglayer-connected chain and return user balances to L1. Prerequisites, verified by the tool before it does any work:
  • The sequencer is stopped, and every pre-halt L2 to L1 bridge exit is already settled.
  • The chain runs the Pessimistic Proof consensus. FEP chains are rejected.
  • The Agglayer committee threshold for the chain is 1.
  • The chain uses no custom gas token.
  • The L2 RPC endpoint is an archive node that exposes debug_accountRange.
  • Anvil is available on the operator’s machine when shadow-fork verification is enabled (the default).

Two-phase workflow

The CLI is deliberately split into a generation phase and a submission phase so that the signed certificate can be reviewed before it is sent to Agglayer.
1

Generate and sign

Runs the full pipeline CHECK → 0 → A → B → C → D → E → F → G → H → I → SIGN and writes exit-certificate-signed.json. SUBMIT and WAIT are intentionally excluded from the default step set.
2

Submit and wait

submit sends the signed certificate to the Agglayer node over gRPC. wait polls the node until the certificate is Settled or InError, then confirms settlement on L1 by matching the VerifyBatchesTrustedAggregator and UpdateL1InfoTree(V2) events.
3

Serve claim proofs

Start exit_certificate_claimer behind an HTTP endpoint that end users can query. For each destination address it returns the bridge exits that belong to the address together with the merkle proofs, global index, exit roots, and leaf fields required to call AgglayerBridge.claimAsset on L1. The claim-asset.sh, claim-all.sh, and list-bridges.sh helper scripts (and a docker-compose file) live next to the binary.
--step also accepts single step names, comma-separated lists, and ranges (a-c, g-, 0-wait). Every step persists its result to the output directory and reads its inputs from files written by earlier steps, so any step can be re-run in isolation.

Pipeline steps

Configuration

exit_certificate reads a standalone configuration file. Both TOML and JSON are accepted; the format is chosen from the file extension. It does not consume the main AggKit configuration. Minimum viable parameters.toml:
Fully annotated templates live next to the source at tools/exit_certificate/parameters.toml.example and tools/exit_certificate/parameters.json.example. Pre-filled configurations for known networks live under tools/exit_certificate/config-examples/ (for example zkevm-cardona.toml and zkevm-mainnet.toml); the operator only needs to fill in the RPC URLs, exitAddress, Agglayer endpoints, and signer. The claimer service has its own configuration template at tools/exit_certificate_claimer/service/config.toml.example.

Signer

signerConfig uses the same shape as the AggSender signer, so any signer supported by AggKit is accepted, including local keystore files and cloud KMS backends. See the aggsender documentation for the full field list.

Output files

Each step writes its result to options.outputDir. The main artifacts are: Intermediate files persist between runs, which is what allows any step to be resumed independently.

Notes

  • Step A requires an archive L2 node that exposes debug_accountRange.
  • Anvil is only needed in shadow-fork mode (options.verifyNewLocalExitRootUsingShadowFork = true, the default). Setting it to false skips the extra verification and removes the Anvil requirement.
  • Only Pessimistic Proof chains are supported. FEP chains are rejected by Step CHECK.
  • The Agglayer committee threshold must be 1.
  • The sequencer must be stopped, with every pre-halt L2 to L1 exit already settled, before the CHECK step will pass.
  • parameters.json / parameters.toml and the output directory are git-ignored in the AggKit repository so that operator inputs and intermediate artifacts stay local.