var img = document.createElement('img'); img.src = "https://nethermind.matomo.cloud//piwik.php?idsite=6&rec=1&url=https://www.surge.wtf" + location.pathname; img.style = "border:0"; img.alt = "tracker"; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(img,s);
Skip to main content

Deploy Surge

This guide walks you through spinning up a full Surge devnet on your local machine (or a VM): an L1 Ethereum devnet, all L1 protocol contracts, and the L2 execution stack.

Total time: ~15 minutes for mock prover. Real prover setup takes longer — mainly waiting for ZisK keys to install.


Before you start

Pick your prover mode

The biggest decision upfront is which prover to use. You can change this later, but it's easier to decide now.

The mock prover skips real ZK proof generation. A dummy contract accepts any signed proof, so blocks propose and finalize immediately without GPU hardware.

Use this if:

  • You're just exploring or developing locally
  • You don't have an NVIDIA GPU with 24 GB+ VRAM
  • You want the fastest possible setup

No extra setup required — the script handles everything.


System requirements

Full local devnet (L1 + L2)

MinimumRecommended
CPU8 cores16 cores
RAM16 GB32 GB
Disk80 GB SSD200 GB SSD
OSUbuntu 22.04+ / macOS 13+Ubuntu 24.04

L2 stack only (connecting to existing L1)

MinimumRecommended
CPU4 cores8 cores
RAM8 GB16 GB
Disk50 GB SSD100 GB SSD
OSUbuntu 22.04+ / macOS 13+Ubuntu 24.04

Prover (separate machine, real prover only)

See Prover Setup — minimum 1x RTX 3090 (24 GB VRAM); multi-GPU L40 / RTX 5090 recommended for real-time-feel proof times.


Prerequisites

Install these tools before running the deploy script.

Docker Desktop

Download and install from docker.com. Make sure Docker is running before you continue.

On Linux, install Docker Engine + Compose plugin instead:

# Quick install on Ubuntu
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER # log out and back in after this

Foundry (includes cast)

curl -L https://foundry.paradigm.xyz | bash
foundryup

Kurtosis CLI

# macOS
brew install kurtosis-tech/tap/kurtosis-cli

# Linux / other — see https://docs.kurtosis.com/install

Standard tools

jq, curl, and bc are needed. They're usually already installed, but if not:

# Ubuntu/Debian
sudo apt install -y jq curl bc

# macOS
brew install jq

Step 1 — Clone the repo

git clone https://github.com/NethermindEth/simple-surge-node.git
cd simple-surge-node
git submodule update --init --recursive
cp .env.devnet .env

The .env.devnet file has pre-funded test keys — you don't need to set up any wallets.


Step 2 — Deploy

Run the script with all flags set so it doesn't stop to ask questions:

./deploy-surge-full.sh \
--environment devnet \
--deploy-devnet true \
--deployment local \
--stack-option 2 \
--mock-prover \
--mode silence \
--force

This starts a fresh L1 devnet, deploys all L1 contracts with a mock proof verifier, generates the L2 genesis, and brings up the full L2 stack (Nethermind + Driver + Catalyst).

Progress is saved

The script saves a lock file after each phase. If something fails or you press Ctrl+C, just re-run the same command — completed phases are skipped.

What --force does

--force skips every interactive prompt and uses sensible defaults: real prover (unless --mock-prover is set), deploy provers, register ZISK vkey, and suppresses the "Start a new deployment?" confirmation when locks exist.

What gets deployed

L1 devnet (Kurtosis / ethereum-package)
└── Execution client + beacon chain

L1 protocol contracts
├── RealTimeInbox
├── SurgeVerifier
├── Bridge + SignalService
├── ERC20/721/1155 vaults
├── Multicall + UserOpsSubmitter
└── ProofVerifierDummy ← mock prover only

L2 genesis + chainspec

L2 stack (Docker Compose)
├── l2-nethermind-execution-client
├── l2-taiko-consensus-client (Driver)
├── web3signer-l1, web3signer-l2
└── l2-catalyst-node (Catalyst)

Step 3 — Verify it's working

After the script finishes, it prints a summary table with all endpoints. You can also check manually:

# Are all L2 containers running?
docker compose ps

# Does the L2 RPC respond?
curl -s -X POST -H "Content-Type: application/json" \
--data '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}' \
http://localhost:8547

Default service endpoints:

ServiceURL
L1 RPChttp://localhost:32003
L1 WebSocketws://localhost:32004
L1 Beaconhttp://localhost:33001
L2 RPChttp://localhost:8547
L2 WebSocketws://localhost:8548
L2 Blockscouthttp://localhost:3001
DEX UIhttp://localhost:5173
note

On a remote VM, replace localhost with the machine's public IP.

Once Catalyst starts proposing blocks, you'll see new L2 blocks appear. With the mock prover they finalize immediately. With the real prover, finalization follows proof generation (~10–17 seconds).


Troubleshooting

L1 health check fails right after devnet start

Kurtosis is still assigning ports. Wait 15–30 seconds and re-run.

cast not found

curl -L https://foundry.paradigm.xyz | bash && foundryup

Kurtosis enclave already exists

The script will offer to remove it. Force-remove manually:

kurtosis enclave rm surge-devnet --force

Blocks propose but never finalize (mock prover)

ProofVerifierDummy requires proofs signed by MOCK_PROOF_SIGNER. Confirm --mock-prover was passed (or MOCK_PROOF_MODE=true was set) during L1 deployment and that the key in .env matches.

Real prover: ZISK guest data is missing

Raiko must be running before you deploy. Check:

curl http://<prover-ip>:<prover-port>/guest_data

Collect diagnostic logs

If something goes wrong and you want to file a bug report or share logs:

# Full snapshot: L1 enclave + all L2 containers
./collect-devnet-logs.sh

# Just the last 30 minutes
./collect-devnet-logs.sh --since 30m

# L1 only (kurtosis enclave dump)
./collect-devnet-logs.sh --l1-only

# L2 only (docker logs per container)
./collect-devnet-logs.sh --l2-only

Logs are saved to ./logs/snapshot-YYYYMMDD-HHMMSS/.


Restart or redeploy

Restart L2 containers only (no redeploy)

Stop and restart just the L2 stack, keeping the L1 devnet and all deployment artifacts intact:

# Stop L2 containers
./remove-surge-full.sh \
--remove-l1-devnet false \
--remove-l2-stack true \
--remove-data false \
--remove-configs false \
--force

# Start L2 stack again against the existing deployment
./deploy-surge-full.sh \
--environment devnet \
--deploy-devnet false \
--deployment local \
--stack-option 2 \
--force

Redeploy L2 from scratch (keep L1 devnet)

Wipe everything except the Kurtosis enclave and redeploy L1 contracts + L2 from scratch:

# Wipe L2 containers, data, and all deployment files
./remove-surge-full.sh \
--remove-l1-devnet false \
--remove-l2-stack true \
--remove-data true \
--remove-configs true \
--force

# Redeploy against the existing L1 enclave
./deploy-surge-full.sh \
--environment devnet \
--deploy-devnet false \
--deployment local \
--stack-option 2 \
--force

Cleanup

# Remove everything except .env
./remove-surge-full.sh --force

# Remove everything including .env
./remove-surge-full.sh --force --remove-env true

Next steps


Our deployment (for reference)

ComponentHardwareNotes
L1Gnosis mainnetQuickNode RPC
L2 stackStandard VMNethermind, Driver, Catalyst
ProverNVIDIA RTX 5090 (×8)~10–11s proofs
Secondary proverL40s cluster~13–14s proofs