What
Today simulate() is validate+compile+ordering only: PlannedStep.address is always null and there are no costs. Add an optional fork-backed simulation mode that executes the plan against an ephemeral Anvil fork of the target network, returning predicted addresses (CREATE nonce-based / CREATE2), per-step gas estimates, and total cost at current gas prices.
Scope sketch
- core:
simulate(spec, { mode: "fork", rpcUrl, ... }) — spawn/attach to an Anvil fork, run the compiled plan, collect receipts; pure plan-only mode remains the default and dependency-free.
- deploy-server: extend
POST /api/simulate with the mode (network-aware via the existing selector); stream per-step results (address, gasUsed) over the existing SSE step events.
- studio picks this up for free in the plan view (address/gas columns populate when present) — deeper UI polish can be a follow-up.
Acceptance
Fork simulate of the sample contracts returns non-null addresses and gas per step; a spec that reverts on-chain surfaces the failing step instead of a generic error.
What
Today
simulate()is validate+compile+ordering only:PlannedStep.addressis always null and there are no costs. Add an optional fork-backed simulation mode that executes the plan against an ephemeral Anvil fork of the target network, returning predicted addresses (CREATE nonce-based / CREATE2), per-step gas estimates, and total cost at current gas prices.Scope sketch
simulate(spec, { mode: "fork", rpcUrl, ... })— spawn/attach to an Anvil fork, run the compiled plan, collect receipts; pure plan-only mode remains the default and dependency-free.POST /api/simulatewith the mode (network-aware via the existing selector); stream per-step results (address, gasUsed) over the existing SSEstepevents.Acceptance
Fork simulate of the sample contracts returns non-null addresses and gas per step; a spec that reverts on-chain surfaces the failing step instead of a generic error.