Operations

Run locally

Step-by-step for getting the full stack running on a single Windows + WSL2 + Docker host, in the order the components depend on each other. By the end of this you should be able to: hit eth_chainId on the gateway, see a balance in the read API, create a merchant on Pay, create an invoice, and watch settlement detect a payment.

The whole stack is local development. Nothing here is exposed to the public internet. Do not run these commands on a host that the public internet can reach.

Prerequisites

OS Windows 10/11 with WSL2 (Ubuntu)
Container runtime Docker Desktop with WSL2 integration or Docker Engine inside WSL
Disk 20 GB free (chain image is large)
RAM 8 GB minimum, 16 GB recommended
Tools curl.exe (or curl from inside WSL), jq (optional)
Wallet MetaMask in your host browser (optional, for the wallet-side check)

A reasonable check:

wsl -l -v
docker --version

The 5-step quickstart

1. Build and start the chain

cd ~/babychain
docker build -f chain\Dockerfile.babychain -t babychain:local chain

Start the node. The script is mounted read-only so editing chain\babychain_local.sh does not require a rebuild; just restart the container.

2. Start the gateway

cd ~/babychain
docker compose -f gateway\docker-compose.yml up -d

Three containers come up: openresty (:8080), indexer, api (:3000), and postgres (:5432).

3. Start Pay

cd ~/babychain
docker compose -f pay\docker-compose.yml up -d

Three containers: pay-api (:4000), pay-settlement, pay-webhooks, pay-sweep.

4. (Optional) start the explorer and monitoring

docker compose -f explorer\docker-compose.yml up -d
docker compose -f monitoring\docker-compose.yml up -d

5. Verify

curl http://localhost:8080 -X POST -H "Content-Type: application/json" `
  --data ''{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}''

You should see {"jsonrpc":"2.0","id":1,"result":"0x07eb"} (2027 in hex).

What runs where

Service Port Container name Healthcheck
evmd (chain) 8545, 8546, 26657, 1317 babychain-node curl localhost:1317/...
OpenResty (gateway) 8080 babychain-rpc-proxy curl localhost:8080 returns 405 to GET, 200 to POST
Gateway indexer (internal) babychain-indexer logs every 1.5s
Gateway read API 3000 babychain-api curl localhost:3000/health
Postgres 5432 babychain-postgres pg_isready
Pay API 4000 pay-api curl localhost:4000/health
Pay settlement (internal) pay-settlement logs "loop" every 1.5s
Pay webhooks (internal) pay-webhooks logs "dispatcher" every 30s
Pay sweep (internal) pay-sweep logs "sweep loop" every 30s
Blockscout 4001, 4002 blockscout-frontend, blockscout-backend visit localhost:4001
Prometheus 9090 prometheus visit localhost:9090
Grafana 3001 grafana visit localhost:3001

Troubleshooting

Chain fails to start with "validator set is empty": your genesis.json is missing the local validator key. Re-run chain/babychain_local.sh to regenerate the genesis and the validator key together.
Gateway returns 502 to every call: the chain container is not up yet, or it bound to a different IP. Check docker ps and the chain''s logs.
Pay cannot reach the chain at http://host.docker.internal:8545: on Linux Docker, host.docker.internal is not always mapped. Edit pay/.env and set CHAIN_RPC_URL=http://<chain-container-ip>:8545 instead.
Want a full clean restart? docker compose -f <file> down -v removes containers and volumes. Use this when changing secrets in .env.