Warp Simulate SVM Txs
SkillDev toolsSimulate pending Sealevel (SVM) warp-route governance txs — signed directly or via a Squads multisig — by forking Solana mainnet locally with surfpool, replaying the exact transactions, then running warp check against the desired registry config. Use to verify that a not-yet-submitted SVM governance change produces the intended on-chain config before it is signed/executed.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Warp Simulate SVM Txs skill
What this skill tells your AI
The instructions your AI receives, as published by hyperlane-xyz/hyperlane-monorepo in .claude/skills/warp-simulate-svm-txs/SKILL.md and read by ahel’s review.
Verify that a pending Sealevel (SVM) warp-route governance change produces the
desired warp route config before it is submitted to mainnet or executed through
a Squads multisig. This forks Solana mainnet locally with surfpool, replays the
exact transactions that will be signed (base58 wire txs, not a re-derived
approximation), then runs warp check against the target registry config.
This is the SVM side of the "fork → replay → check" loop (the Solana analog of
/warp-simulate-safe-txs). It catches wrong owners, wrong ISMs, missing router
enrollments, or bad gas/fee config that would otherwise only surface after the txs
are executed on-chain.
Unlike the EVM Safe flow, SVM warp governance is same-domain: there is no ICA
fan-out and no cross-fork relay to worry about. Impersonation is handled by
surfpool's --skip-signature-verification, so the txs replay as-is even though you
don't hold the authority's key.
When to use
- An engineer has an SVM warp-route config change (owner/ISM/router/gas/fee) and asks "do these txs lead to the desired config in registry PR #XXXX?"
- Before signing or executing any SVM warp-route governance transaction, including ones routed through a Squads vault.
Input Parameters
| Parameter | Required | Description |
|---|---|---|
warp_route_id | Yes | The warp route ID being changed, e.g. SOL/solanamainnet-.... |
svm_txs | Yes | The governance transactions to replay, as a PrintableSvmTransaction[] file — the output of warp apply --submitter file, or a Squads export in that shape. |
target_config | Yes | The desired config to check against — usually a hyperlane-registry PR branch. Serve it via the local HTTP registry. |
Prerequisites
- surfpool installed: the CLI
warp forkSVM path runs a locally-installedsurfpoolbinary (>= 1.5.0) onPATH— there is no Docker fallback. Install the pinned, checksum-verified release the way CI does — see theInstall surfpoolstep in.github/workflows/test-cli-e2e.yml(a pinnedv1.5.0tarball verified against its SHA-256); do not pipe the mutablerun.surfpool.runinstaller to a shell. If it's missing,warp forkaborts before replaying anything with a "surfpool 1.5.0+ is required" error. - Monorepo root:
MONOREPO_ROOT=$(git rev-parse --show-toplevel). Prefix CLI commands withcd $MONOREPO_ROOT &&. - A local HTTP registry serving the target (PR) config (use
/start-http-registrypointed at the PR branch, or pass--registry).warp forkreads the warp route from this registry to decide which chain to fork. - A scratch dir, e.g.
WORK=$(mktemp -d).
Instructions
Step 1 — Produce the transactions to replay (PrintableSvmTransaction[])
If you don't already have the tx file, generate it with warp apply and the file
submitter, which writes the governance txs (as base58 wire transactions) to a file
instead of submitting them:
# strategy.yaml — route the Sealevel chain's txs to a file
<sealevelChain>:
submitter:
type: file
chain: <sealevelChain>
filepath: <WORK>/svm-txs.json
cd $MONOREPO_ROOT && pnpm -C typescript/cli exec tsx cli.ts warp apply \
--warpRouteId $WARP_ROUTE_ID --registry http://localhost:3333 \
--strategy $WORK/strategy.yaml
The result is $WORK/svm-txs.json — a flat PrintableSvmTransaction[] array (each
element carries transaction_base58, and optionally waitForSlotAdvance). A Squads
proposal export in the same shape works too.
Step 2 — Build the fork-config
warp fork accepts a per-chain fork-config; the Sealevel slice takes the tx file by
path (SvmRawForkConfigSchema's { path } form — the array is read from disk):
# $WORK/fork-config.yaml
<sealevelChain>:
path: <WORK>/svm-txs.json
(Inline { transactions: [...] } is also accepted, but path avoids embedding
base58 blobs.)
Step 3 — Fork, replay, and serve the overlaid registry
Serve the target (PR) registry so fork/check read the intended addresses, then run
warp fork in the background (it forks the route's Sealevel chain with surfpool,
replays the txs under skip-sigverify/skip-blockhash, and serves an overlaid registry
whose Sealevel RPC points at the local fork):
cd $MONOREPO_ROOT && pnpm -C typescript/cli exec tsx cli.ts warp fork \
--warpRouteId $WARP_ROUTE_ID --registry http://localhost:3333 \
--fork-config $WORK/fork-config.yaml --port 8545
- Run it with
run_in_background: true(the command serves HTTP and holds the fork). - The overlaid registry is served on
port - 10(e.g.8535for--port 8545). - Note the task/shell ID so you can stop it in Step 5.
Finalization note: surfpool's copy-on-read fetches the datasource at finalized commitment. Mainnet state is long-finalized, so this is a non-issue in practice. (Only matters when forking a freshly-written local validator.)
Step 4 — warp check against the desired config
cd $MONOREPO_ROOT && pnpm -C typescript/cli exec tsx cli.ts warp check \
--warpRouteId $WARP_ROUTE_ID --registry http://localhost:8535
Point --registry at the served fork registry (port - 10) so warp check
reads the fork's post-replay on-chain state. Expect zero violations — that means
the replayed txs produce exactly the target config.
Step 5 — Cleanup (mandatory)
Stop the background warp fork process (KillShell with its ID). It terminates the
local surfpool process (SIGTERM) — don't leave it running.
Step 6 — Report
- PASS/FAIL with the concrete config deltas (owner/ISM/router/gas/fee) vs the target config.
- Anything not covered.
Gotchas (learned)
- surfpool forks the datasource's current head; there is no fork-at-slot flag
(unlike anvil's
--fork-block-number). Config validation against current mainnet state is exactly what this loop does. - Impersonation is global
--skip-signature-verification(handled inside the SVM fork path) — you don't need the authority's key, and Squads vault PDAs sign via program CPI seeds so they need nothing special. - The tx file is the exact
warp apply --submitter fileoutput; don't re-serialize or re-sign it. warp checkworks for Sealevel — it reads the fork's on-chain PDA state and diffs against the target config.
Related skills
/warp-fork— fork a warp route's chains (per-protocol: anvil for EVM, surfpool for SVM)./warp-simulate-safe-txs— the EVM/Safe analog of this loop./start-http-registry— serve a local/PR registry for fork+check./warp-route-check— standalone warp check.
Signals
- GitHub stars
- 75
- Forks
- 601
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
warp-simulate-svm-txs- Source
- github.com/hyperlane-xyz/hyperlane-monorepo