Skip to main content
This guide shows you how to run the full ProofBridge stack locally, using only Docker and the scripts in scripts/docker-local/. You do not need the Rust, Foundry, or Noir toolchains installed — contract artifacts are pulled from the public Proofbridge-Contracts GitHub Release.

What you get

A single command brings up:
  • Anvil — a local EVM chain on http://localhost:9545
  • Stellar Quickstart — a local Soroban RPC on http://localhost:8000
  • Postgres — the relayer’s database on localhost:5433
  • Backend Relayer — the coordinator service on http://localhost:2005
  • Deployer — a one-shot container that deploys contracts, runs migrations, and seeds the database
  • Optional: funded dev wallets for the frontend

Prerequisites

  • Docker + Docker Compose — the only hard requirement.
  • A POSIX shell (bash, zsh). On Windows, run under WSL2 or Git Bash.
That is the baseline. You can optionally install the full toolchain (Foundry, Rust/Soroban, Noir/bb) if you want to build contracts from source — see Using a local build below.

Compiler versions

If you’re building contracts locally (not just consuming the prebuilt bundle), the EVM side requires Solidity ^0.8.34. The minimum bump is deliberate — the concrete contracts use ReentrancyGuardTransient, which needs transient storage opcodes introduced in 0.8.24 and stabilised in later patch releases.
  • Foundryfoundryup fetches the matching solc via svm the first time you run forge build. No manual install needed.
  • CI — if you’re replicating the GitHub Actions matrix, the foundry-toolchain@v1 action must be pinned to version: stable. The default (nightly) ships an svm-rs compiler list that doesn’t know about 0.8.34 yet and fails with:
    Pinning to stable is the difference between a green build and that error.

The one-command flow

On first run this will:
  1. Download the latest contract bundle (WASMs, EVM ABIs, deposit verification key) from the Proofbridge-Contracts GitHub Release.
  2. Extract it into scripts/docker-local/.artifacts/.
  3. Build the deployer image (node:20-slim + stellar-cli, ~1 minute cold).
  4. Start anvil, Stellar quickstart, postgres, and the relayer.
  5. Run the deployer container, which deploys contracts on both chains, runs prisma migrate deploy, and seeds the database.
When it finishes you will see:

Funding dev wallets

You can have the deployer fund your frontend wallets automatically. Copy the example env file and fill in whichever addresses you want funded:
Both fields are optional — leave blank to skip that chain. Re-running up.sh with a populated .env is safe; funding is idempotent.

Tearing down

This stops and removes all containers and volumes. The artifact cache in .artifacts/ is left in place so the next up.sh starts faster.

Pinning a contract build

The default bundle tag is latest (a rolling pointer to the most recent green build of main). To pin to a specific commit, set the tag to the short SHA:
Or inline:
Per-commit tags are immutable, so pinning gives you reproducible local deployments.

Using a local build

If you want to test unmerged contract changes, build the artifacts locally and pass --local:
--local skips the GitHub Release download and copies artifacts from your working tree into .artifacts/.

The scripts in scripts/

docker-local/

The primary dev bootstrap. Brings up the full stack (chains + db + relayer + deployed contracts) with up.sh and tears it down with down.sh.

build_circuits.sh

Builds Noir circuits and generates UltraHonk verification keys. Used when you need to rebuild proof artifacts from source.

start_chains.sh

Lightweight alternative to docker-local/ when you want host-side anvil + Stellar quickstart without the rest of the stack. Writes .chains.env with RPC URLs and admin keys.

stop_chains.sh

Tears down whatever start_chains.sh brought up.

relayer-e2e/

End-to-end tests that exercise the backend relayer over HTTP — deploy, seed, run ad/trade flows, tear down. Entry point: e2e.sh.

cross-chain-e2e/

Full cross-chain proof-relay tests that walk a deposit → proof → settlement flow against both chains. Entry point: run.ts.

Troubleshooting

The scripts were checked out with CRLF line endings. The repo ships a .gitattributes that forces LF on *.sh, so the cleanest fix is:
Then re-run up.sh. The deployer Dockerfile also strips \r defensively, so builds should succeed either way.
The contract bundle is incomplete in .artifacts/. Force a re-download by setting the bundle tag explicitly:
Or if you are iterating on local contract changes, clear .artifacts/ and use --local.
Your deployer image was built before libdbus-1-3 was added to the Dockerfile. Rebuild without cache:
The Stellar quickstart container can take 30–60 seconds after RPC becomes healthy before the friendbot HTTP endpoint serves traffic. The entrypoint script will poll friendbot for up to 3 minutes; if it still fails, check docker compose logs stellar for a startup error.
Make sure nothing else is bound to port 9545 on the host. Re-run docker compose -f scripts/docker-local/docker-compose.yaml logs anvil to see the chain’s startup log.
Postgres may not have been ready when migrations ran. The deployer retries internally, but you can also re-run the migration manually:

Next steps

Backend relayer

The service you are running locally. README and Prisma schema.

How it works

Understand what the stack does end-to-end before diving into the code.

API reference

Hit the relayer at http://localhost:2005 once the stack is up.

Smart contracts

Contract-level reference for the addresses the deployer writes to deployed.json.