MEE Node is the main node in the Modular Execution Environment (MEE) protocol. It issues cryptographically signed quotes for supertransactions and executes them across multiple chains.
- Overview
- Architecture
- Prerequisites
- Dependencies
- Quick start
- Configuration
- Running the node
- Docker
- API
- Health and operations
- Further documentation
- Contact
The node:
- Quotes user intents (supertransactions) and returns signed quotes with gas limits, deadlines, and fees.
- Executes signed quotes on-chain: it simulates, batches, and submits transactions via worker processes.
- Uses Redis for job queues (BullMQ), quote/userOp storage, and caching.
- Uses a Token Storage Detection service to resolve ERC20 balance storage slots for simulation.
- Master process: Initializes chains, RPC manager, gas manager, batcher, health checks, and spawns workers.
- API workers (cluster): Serve HTTP API (quote, execute, info, explorer).
- Simulator workers (threads, per chain): Process simulation jobs from the queue.
- Executor workers (threads, per chain): Process execution jobs from the queue.
Quote flow: Quote API → Storage (Redis) → Simulator queue → Batcher → Executor queue → Chain RPC.
See docs/architecture.md for details.
- Bun (runtime and package manager)
- Docker (optional, for Redis and token-storage service)
- Rust toolchain (only if you build the token-storage-detection service from source)
The node requires two external services to run.
Redis is used for:
- Job queues (BullMQ): simulator and executor queues per chain
- Storage: quotes and userOps (by hash), and custom fields
- Caching: e.g. token slot detection, price feeds
Configuration (see .env.example):
REDIS_HOST(default:localhost)REDIS_PORT(default:6379)
Run Redis locally (Docker):
docker run -d --name redis -p 6379:6379 redis:7-alpineOr use the project’s Compose file (includes Redis Stack):
docker compose up -d redis-stackEviction: Quote and userOp keys are not set with TTL, so Redis can grow over time. For production, configure an eviction policy (e.g. maxmemory + maxmemory-policy allkeys-lru). See docs/dependencies.md for details.
See docs/dependencies.md for more detail.
A separate HTTP service that returns the ERC20 balance storage slot for a given token and chain. The node calls it during simulation to build correct state overrides (e.g. for balanceOf).
Configuration:
TOKEN_SLOT_DETECTION_SERVER_BASE_URL(default:http://127.0.0.1:5000)
The service is implemented in Rust in apps/token-storage-detection. It exposes:
GET /{chainId}/{tokenAddress}→{ success, msg: { slot } }
You can run your own instance or use a hosted one. See docs/dependencies.md and apps/token-storage-detection/README.md.
-
Clone and install
git clone <repo-url> cd mee-node bun i
-
Start Redis
docker run -d --name redis -p 6379:6379 redis:7-alpine
-
Start Token Storage Detection (see apps/token-storage-detection)
cd apps/token-storage-detection cp .env.example .env # set RPC URLs for chains you need cargo run --release --bin token-storage-detection
Default:
http://127.0.0.1:5000. Adjust port in the app’s.envif needed (e.g.SERVER_PORT). -
Configure the node
cp .env.example .env # Set at least: # - NODE_ID (required) # - NODE_PRIVATE_KEY (required) # - REDIS_HOST / REDIS_PORT if not localhost:6379 # - TOKEN_SLOT_DETECTION_SERVER_BASE_URL if not http://127.0.0.1:5000 # - CUSTOM_CHAINS_CONFIG_PATH or use built-in chains
-
Run the node
bun run start # production bun run start:dev # development (watch mode)
API listens on
PORT(default4000). Check http://localhost:4000/v1/info (or yourPORT) for version and health.
All options are documented in .env.example. Key groups:
| Area | Main variables |
|---|---|
| Server | PORT, NODE_ENV, ENV_ENC_PASSWORD (production/staging secrets) |
| Node identity | NODE_ID, NODE_PRIVATE_KEY, NODE_NAME, NODE_FEE_BENEFICIARY |
| Chains | CUSTOM_CHAINS_CONFIG_PATH, batch gas limits, simulator/executor concurrency |
| Redis | REDIS_HOST, REDIS_PORT |
| Token slot service | TOKEN_SLOT_DETECTION_SERVER_BASE_URL |
| Workers | NUM_CLUSTER_WORKERS, MAX_EXTRA_WORKERS, queue attempts/backoff |
| Logging | LOG_LEVEL, PRETTY_LOGS |
For production/staging, the node can load encrypted secrets from keystore/key.enc (see ENV_ENC_PASSWORD and src/common/setup.ts).
| Command | Description |
|---|---|
bun run start |
Run with Bun (uses src/main.ts); cluster + workers. |
bun run start:dev |
Watch mode; single process, all modules loaded. |
bun run build && bun run start:prod |
Build to dist/ and run dist/main.js. |
Ensure Redis and the token-storage-detection service are up and reachable; otherwise quote/execute and health may fail. See docs/operations.md for runbooks.
- Node image: bcnmy/mee-node. Use with your own Redis and token-storage service.
- Token Storage Detection: See apps/token-storage-detection/Dockerfile. Build and run with the same env vars as the Rust app (RPC URLs, optional Redis, etc.).
Example (node only):
docker run -e NODE_ID=... -e NODE_PRIVATE_KEY=... \
-e REDIS_HOST=host.docker.internal \
-e TOKEN_SLOT_DETECTION_SERVER_BASE_URL=http://host.docker.internal:5000 \
-p 4000:4000 bcnmy/mee-nodePublic HTTP API (see also live docs):
| Method | Path | Description |
|---|---|---|
| GET | /v1/info |
Node version, supported chains, health (Redis, token-slot, queues, etc.) |
| GET | /v1/explorer/:hash |
Get quote by hash (optional confirmations) |
| POST | /v1/quote |
Request a quote (intent → signed quote) |
| POST | /v1/quote-permit |
Request a quote with permit flow |
| POST | /v1/exec |
Execute a signed quote |
The quote endpoint returns a signed quote (node’s commitment). The execute endpoint accepts the user-signed quote, validates it, and runs the intent on the configured chains.
/v1/info: Returns node info and health for Redis, token-slot detection, chains, simulator, executor, and workers.- Logs: Structured (e.g. Pino). Level via
LOG_LEVEL;PRETTY_LOGS=1for development. - Graceful shutdown: Use SIGTERM; the process uses
tiniin Docker.
See docs/operations.md for runbooks (startup, dependency checks, scaling, troubleshooting).
- docs/architecture.md — Process model, queues, and data flow
- docs/dependencies.md — Redis (including eviction) and Token Storage Detection in detail
- docs/chain-configuration.md — Adding and configuring chains: all config fields, price oracles (native + payment), and requirement that any chain referenced by an oracle must be in chain config
- docs/operations.md — Runbooks and operations
- .env.example — All configuration options
Reach out: connect@biconomy.io