Installation

A quick guide to self-hosting an ERC-4337 bundler for handling UserOperations.

The bundler package is implemented in Go and is open source at github.com/stackup-wallet/stackup-bundler.

πŸ“˜

Looking for a fully managed instance for your project instead?

Use our hosted services to get set up with a bundler in 2 minutes πŸš€

Install

Here are some convenient ways to install a stable release of Stackup Bundler. Additional distribution methods will be added and listed here over time.

Docker images

Pre-built docker images are publicly available on Docker Hub.

docker pull stackupwallet/stackup-bundler:latest

# Alternatively, for older versions.
# See github.com/stackup-wallet/stackup-bundler/releases for version releases.
docker pull stackupwallet/stackup-bundler:vX.Y.Z

Build from source

If you have Go setup in your environment, you can clone and build the bundler from source.

git clone https://github.com/stackup-wallet/stackup-bundler.git
cd stackup-bundler

# It is recommended to build from a specific release version.
# See github.com/stackup-wallet/stackup-bundler/releases for version releases.
git checkout vX.Y.Z

# This will build a binary from source and output it to the ./tmp directory.
# You can move the binary to a different directory in your PATH (e.g. /usr/local/bin).
go build -o ./tmp/stackup-bundler main.go

Running the bundler

Make sure to have your environment variables configured before running the bundler. See the configuration page for details.

Run an instance in private mode:

stackup-bundler start --mode private
# Make sure to set all relevant env vars.
docker run -d --name bundler -p 4337:4337 \
  -e ERC4337_BUNDLER_ETH_CLIENT_URL=... \
  stackupwallet/stackup-bundler:latest \
  /app/stackup-bundler start --mode private

For a description on the CLI commands and other supported modes:

stackup-bundler start --help
docker run stackupwallet/stackup-bundler:latest /app/stackup-bundler --help

Best practices for underlying nodes

A bundler should be considered as an extension, or a side-car, to a full node. It extends the eth method namespace in order to provide account abstraction capabilities.

At minimum, the bundler requires access to the node's debug_traceCall method for custom JS tracing. Without access to tracing, the bundler will not be able to estimate gas or properly validate incoming User Operations.

Running in the same machine or data centre

On top of tracing, the bundler will also make numerous RPC requests to the node in order to receive, validate, and bundle User Operations. To minimise latency from waterfall requests, it is recommended to run the bundler as close to the node as possible.

Using native tracing

Although custom JS tracing is the minimum requirement, it is recommended to use custom Go tracing in production for faster performance. Smart Accounts with more complex validation methods may also cause timeouts when using the base JS tracer.

The trade-off in using native tracing is the overhead of having to compile the execution client from source with the additional Go tracer file. To make this easier, Stackup also maintains an ERC-4337 Execution Clients repo to streamline this process.