Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
69fb57e
new tool: exit_certificate
krlosMata Apr 14, 2026
a934c76
Claude review
krlosMata Apr 14, 2026
233b4a0
fix: address review comments on exit_certificate tool
krlosMata Apr 15, 2026
da5a8cb
fix: resolve golangci-lint issues (mnd, prealloc)
krlosMata Apr 15, 2026
cd37d4f
refactor: use isClaimed on L2 bridge & reduce complexity (diffguard)
krlosMata Apr 17, 2026
fb6c902
feat: add exit_certificate to build-tools and mask RPC URL in error logs
joanestebanr Apr 24, 2026
6e52494
feat(exit-certificate): add L2StartBlock config, improve RPC error ha…
joanestebanr Apr 30, 2026
f02f7d3
feat: step F check cert using agglayer addmin
joanestebanr Apr 30, 2026
013c3d9
feat: step F verification
joanestebanr Apr 30, 2026
a5ef96f
fix: brigeEvent topic fixed
joanestebanr May 4, 2026
2122813
feat: add doc, check genesis
joanestebanr May 4, 2026
0314ec6
feat: unclaimed bridges must be set into imported_exit_root and also …
joanestebanr May 5, 2026
5d6b526
feat: add logs to traceTransactions
joanestebanr May 5, 2026
c0007bd
feat: split step A into A1 and A2
joanestebanr May 5, 2026
c604b30
feat: revert A1/A2 split and add sign step
joanestebanr May 5, 2026
6f99c19
feat: add continueOnTraceError option and failed traces output
joanestebanr May 5, 2026
c44e2e8
perf: collect tx hashes directly from block headers scan
joanestebanr May 5, 2026
434f520
feat: create launch.json always
joanestebanr May 8, 2026
d4fadec
feat: add steps G, H, I and submit to exit-certificate pipeline
joanestebanr May 11, 2026
250c8cc
feat: use SignerConfig for certificate signing and extend kurtosis sc…
joanestebanr May 11, 2026
2c93009
fix(exit-certificate): handle custom gas token in step G token resolu…
joanestebanr May 12, 2026
553472c
feat(exit-certificate): add CHECK/WAIT steps, l1GlobalExitRootAddress…
joanestebanr May 13, 2026
8a2d4b6
feat(exit-certificate): pipeline improvements β€” step ranges, LER trac…
joanestebanr May 13, 2026
80de345
fix: add metadata to certificate
joanestebanr May 13, 2026
23ab917
fix(exit-certificate): hash bridge exit metadata and improve sign log…
joanestebanr May 14, 2026
7617c70
feat(exit-certificate): add per-window ETA progress logging to Step A
joanestebanr May 14, 2026
a8e46e1
feat(exit-certificate): Step E bridge service validation and message …
joanestebanr May 15, 2026
19412cc
fix(exit-certificate): batchRPC should not error on individual RPC er…
joanestebanr May 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,22 @@ build-aggkit: ## Builds aggkit binary
GIN_MODE=release $(GOENVVARS) go build -ldflags "all=$(LDFLAGS)" -o $(GOBIN)/$(GOBINARY) $(GOCMD)

.PHONY: build-tools
build-tools: $(GOBIN)/aggsender_find_imported_bridge $(GOBIN)/remove_ger ## Builds the tools
build-tools: $(GOBIN)/aggsender_find_imported_bridge $(GOBIN)/remove_ger $(GOBIN)/exit_certificate ## Builds the tools


.PHONY: $(GOBIN)/aggsender_find_imported_bridge
$(GOBIN)/aggsender_find_imported_bridge: ## Build aggsender_find_imported_bridge tool
$(GOENVVARS) go build -o $(GOBIN)/aggsender_find_imported_bridge ./tools/aggsender_find_imported_bridge


.PHONY: $(GOBIN)/remove_ger
$(GOBIN)/remove_ger: ## Build remove_ger tool
$(GOENVVARS) go build -ldflags "all=$(LDFLAGS)" -o $(GOBIN)/remove_ger ./tools/remove_ger/cmd

.PHONY: $(GOBIN)/exit_certificate
$(GOBIN)/exit_certificate: ## Build exit_certificate tool
$(GOENVVARS) go build -o $(GOBIN)/exit_certificate ./tools/exit_certificate/cmd

.PHONY: build-docker
build-docker: ## Builds a docker image with the aggkit binary
docker build -t aggkit:local -f ./Dockerfile .
Expand Down
4 changes: 4 additions & 0 deletions tools/exit_certificate/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
parameters.json
output/
*.json.tmp
exit-certificate
284 changes: 284 additions & 0 deletions tools/exit_certificate/CLAUDE.md

Large diffs are not rendered by default.

323 changes: 323 additions & 0 deletions tools/exit_certificate/README.md

Large diffs are not rendered by default.

81 changes: 81 additions & 0 deletions tools/exit_certificate/cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package main

import (
"fmt"
"os"

aggkit "github.com/agglayer/aggkit"
exit_certificate "github.com/agglayer/aggkit/tools/exit_certificate"
"github.com/urfave/cli/v2"
)

func main() {
app := cli.NewApp()
app.Name = "exit-certificate"
app.Usage = "Generate exit certificates for zkEVM chain migration"
app.Version = aggkit.Version
app.Description = `Builds an exit certificate by running a multi-step pipeline against an L2 chain.

Pipeline steps (run in order by default):

0 Generate the Locked Balance Table (LBT) by scanning the L2 bridge contract
for wrapped token mappings. Skipped when lbtFile is set in the config.

A Collect all unique sender/receiver addresses from bridge events up to the
target block.

B Scan EOA native-token balances and wrapped-token balances for every address
found in step A.

C Scan smart-contract locked values using the LBT from step 0.

D Aggregate step B and C results into a draft exit certificate.

E Cross-check the draft certificate against L1 to filter out bridge exits that
have already been claimed. Skipped when l1RpcUrl is not set in the config.

F Verify agglayer token balances against the certificate exits.

G Calculate NewLocalExitRoot from the certificate bridge exits.

H Fetch PreviousLocalExitRoot from the agglayer via interop_getNetworkInfo.
Requires agglayerRpcUrl in options.

I Assemble the final certificate by writing NewLocalExitRoot (from G) and
PreviousLocalExitRoot (from H) into exit-certificate-final.json.

SIGN Sign the final certificate with the configured keystore.

SUBMIT Send the signed certificate to the agglayer via gRPC.
Requires agglayerGrpcUrl in options. Not part of the default pipeline.

WAIT Poll the agglayer every 5 seconds until the submitted certificate is
settled or enters an error state. Reads step-submit-result.json for
the certificate hash. Requires agglayerGrpcUrl in options.

Use --step to run a single step (e.g. --step a). When running steps individually
the output files from previous steps must already exist in the output directory.`
app.Flags = []cli.Flag{
&cli.StringFlag{
Name: "config",
Aliases: []string{"c"},
Usage: "Path to parameters.json config file",
Value: "parameters.json",
},
&cli.StringFlag{
Name: "step",
Usage: "Run a specific step: 0, a, b, c, d, e, f, g, sign, or all",
Value: "all",
},
&cli.BoolFlag{
Name: "verbose",
Usage: "Enable debug logging",
},
}
app.Action = exit_certificate.Run

if err := app.Run(os.Args); err != nil {
_, _ = fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1)
}
}
Loading
Loading