Anvil for MEVM external provider

The devnet provided by suave-geth operates in total isolation, which is good for basic testing, until you want to test your SUAPP against some real L1 smart contracts (e.g. Uniswap on mainnet Ethereum). This is solved by either using the testnet (which is only connected to goerli), or making a local fork of that chain to test against. It’s been a solved problem (see hardhat, anvil) for a while, and SUAVE needs it, too.

I have a working fork of foundry that implements suavex_call in anvil. This is particularly useful for testing SUAPPS that send transactions to, or read from, complicated onchain protocols that you’d rather not re-deploy yourself.
See this PR for detailed instructions to use it yourself :slight_smile:

I also plan to add the other suavex_ endpoints, so that anvil can entirely replace the existing devnet provider:

  • suavex_buildEthBlock
  • suavex_buildEthBlockFromBundles
  • suavex_newSession
  • suavex_addTransaction
1 Like

These probably don’t need to be added:

  • suavex_newSession
  • suavex_addTransaction

These are responsible for caching transactions for a builder.

suavex_buildEthBlock[FromBundles] relies on confidential data stores to retrieve transactions, which (IIUC) makes these endpoints unnecessary, since we can set confidential stores directly with a precompile that doesn’t rely on a suavex_ endpoint.

suavex_buildEthBlock returns an ExecutionPayloadWrapper, which will then be passed to the precompile submitEthBlockToRelay.

We should be able to implement suavex_buildEthBlock[FromBundles] (I believe we need both) in anvil by using the built-in tx pool. We can control the block-mining behavior directly in the API handler, which will allow us to load up the pool with transactions, then simulate execution and build an execution payload from the resulting state.


working PR to add suavex_buildEthBlock[FromBundles] to anvil: Suavex builder endpoints by zeroXbrock · Pull Request #2 · zeroXbrock/suavex-foundry · GitHub

1 Like

New endpoints buildEthBlock[FromBundles] are now merged in suavex-foundry. One thing I didn’t notice before was that the simulateBundle precompile uses suavex_buildEthBlock on the backend. So now with the addition of this endpoint, you can simulate bundles from suave locally!

Now that this is working, I thought it would be helpful to post some info so others can start using it, too!

Instructions to run a local suave dev environment with suavex-anvil:

First you need to run the suave-geth devnet with the --suave.eth.remote_endpoint flag set to point to our anvil node (which we’ll run next):

if you haven’t installed suave, you can do so by running this:

curl -L | bash

This will install suave-geth into /usr/local/bin/suave-geth, so you should be able to use it in your terminal immediately.

# if you built from source, replace `suave-geth` with `./build/bin/suave`
suave-geth \
    --dev \
    --dev.gaslimit=30000000 \
    --http \
    --http.port=8545 \
    --http.vhosts='*' \
    --http.corsdomain='*' \
    --ws \'*' \
    --keystore=./suave/devenv/suave-ex-node/keystore \
    --unlock=0xB5fEAfbDD752ad52Afb7e1bD2E40432A485bBB7F \
    --password=./suave/devenv/suave-ex-node/password.txt \
    --suave.eth.remote_endpoint=http://localhost:8555 \

Also note the --suave.eth.external-whitelist flag. This setting lets precompiles that make HTTP requests (like DO_HTTPREQUEST or SUBMIT_ETH_BLOCK_TO_RELAY) target any URL.

Now that suave-geth is running, open a new terminal, and run the following to spin up suavex-anvil with a mainnet fork. Note: you’ll need the Rust toolchain installed.

# clone the repo & go into its directory
git clone
cd suavex-foundry

# run anvil with cargo
cargo run --bin anvil -- -p 8555 --chain-id 1 -f $RPC_URL

All done. Now when you send a CCR to suave-geth, it will use anvil as its eth provider for any precompiles that call suavex_ endpoints. This includes simulateBundle, ethCall, submitEthBlockToRelay, buildEthBlock, and probably more that I haven’t tested.

You can test it out with an example like Unisuapp:

Note: you’ll want to install bun and foundry if you haven’t already.

# clone repo if you haven't already, and enter its directory
git clone
cd unisuapp

# populate .env, uses pre-funded default accounts
echo "L1_CHAIN_ID=1
SUAVE_RPC_URL=http://localhost:8545" > .env

# install solidity dependencies & build contracts
forge install
forge build

# install NPM dependencies
bun install
# first run the script with DEPLOY set to deploy the contracts
# deployed contract address will be saved to `addresses.json`
DEPLOY=true bun run index.ts

# now you can run again without deploying
bun run index.ts