Skip to content

Guide โ€” Local Setup

Run the Stack Locally

The full Stablecoin Stack reference implementation runs on your machine with two Docker Compose commands. By the end of this guide you will have a working local environment โ€” settlement contract on a local test network, payment gateway, event explorer, demo store โ€” and you will have completed a real end-to-end payment through it.

Time to complete: 15โ€“30 minutes depending on your internet connection and machine.


Prerequisites

Requirement Minimum version Check
Docker 24.x docker --version
Docker Compose (plugin) 2.20 docker compose version
Git Any recent git --version
Free RAM 4 GB available โ€”
Free disk 8 GB available โ€”

No Node.js, no language runtime, no database installation required. Everything runs inside containers.


Step 1 โ€” Clone the repository

git clone https://github.com/Stablecoin-Stack/reference-implementation
cd reference-implementation

The repository contains two Compose files that map to two independent layers:

File What it starts
docker-compose.infra.yml Local blockchain node ยท deployed Settlement Contract ยท PostgreSQL ยท Redis
docker-compose.apps.yml Payment gateway ยท Wallet-gateway ยท Event Explorer ยท Demo merchant store ยท Block explorer UI

Step 2 โ€” Copy environment config

cp .env.example .env

The defaults in .env.example are pre-configured for local development. You do not need to change anything to get started. The notable defaults:

# Network โ€” local test chain
CHAIN_ID=31337
RPC_URL=http://chain:8545

# Pre-funded relayer account (test key โ€” never use in production)
RELAYER_PRIVATE_KEY=0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

# Settlement contract base fee (in USDC units โ€” 6 decimals)
BASE_FEE_AMOUNT=2500000   # $2.50

# Gateway
GATEWAY_PORT=4000
EXPLORER_PORT=4001
STORE_PORT=3000

Step 3 โ€” Start the infrastructure layer

docker compose -f docker-compose.infra.yml up -d

This starts:

  • A local EVM-compatible test node (pre-funded with test accounts)
  • Deploys the Settlement Contract automatically on first start
  • Mints test USDC to a set of pre-configured wallet addresses
  • Starts PostgreSQL and Redis

Wait for the infrastructure to be ready:

docker compose -f docker-compose.infra.yml logs -f chain
# Ready when you see: "Listening on 0.0.0.0:8545"

Step 4 โ€” Start the application layer

docker compose -f docker-compose.apps.yml up -d

This starts:

  • Payment gateway โ€” receives and validates payment payloads
  • Wallet-gateway โ€” WebSocket interface for wallet clients (port 4000)
  • Broadcast submitter โ€” submits transactions using the local relayer account
  • Event Explorer โ€” REST API + WebSocket for settlement events (port 4001)
  • Demo merchant store โ€” a working checkout page (port 3000)
  • Transfer history โ€” indexes on-chain events and triggers reconciliation

Wait for all services to be healthy:

docker compose -f docker-compose.apps.yml ps
# All services should show "healthy" or "running"

Step 5 โ€” Verify everything is up

Open these URLs in your browser:

Service URL What you should see
Demo store http://localhost:3000 Product listing page
Event Explorer http://localhost:4001 API root with endpoint list
Gateway health http://localhost:4000/health {"status":"ok"}

You can also query the Event Explorer directly:

curl http://localhost:4001/events
# Returns an empty array [] โ€” no payments yet

Step 6 โ€” Install the browser wallet extension (local mode)

The browser wallet extension needs to point to your local gateway rather than the production endpoint.

  1. Download the unpacked extension from the releases page: https://github.com/Stablecoin-Stack/wallet-extension/releases
  2. In Chrome/Brave, go to chrome://extensions, enable Developer mode, click Load unpacked, and select the downloaded folder.
  3. Open the extension and go to Settings โ†’ Network โ†’ Custom.
  4. Set the gateway URL to ws://localhost:4000.
  5. Import one of the pre-funded test accounts using its private key (listed in .env.example under TEST_ACCOUNTS).

Your wallet now shows a test USDC balance. You are ready to pay.


Step 7 โ€” Complete a test payment

  1. Open the demo store at http://localhost:3000.
  2. Add any item to the cart and proceed to checkout.
  3. The checkout page displays a QR code and a "Pay with Wallet" button.
  4. Click Pay with Wallet โ€” the browser extension pops up showing the payment request.
  5. Review the details and click Confirm.
  6. The extension submits the payment. Within a few seconds the store shows "Payment confirmed."

Watch it settle in real time:

# Stream settlement events from the local explorer
curl -N http://localhost:4001/events/stream

# Or query after the payment
curl http://localhost:4001/events

Step 8 โ€” Explore what just happened

The settlement contract received the transaction:

# Get the contract address from the deployment output
cat ./deployments/local/settlement-contract.json

# Query the contract's event log via the explorer
curl "http://localhost:4001/events?limit=1&order=desc"

The gateway processed the payload:

docker compose -f docker-compose.apps.yml logs gateway --tail=50

The event indexer confirmed and reconciled:

docker compose -f docker-compose.apps.yml logs transfer-history --tail=30

Resetting the environment

To start fresh โ€” new chain state, new contract deployment, cleared database:

docker compose -f docker-compose.apps.yml down
docker compose -f docker-compose.infra.yml down -v   # -v removes volumes
docker compose -f docker-compose.infra.yml up -d
docker compose -f docker-compose.apps.yml up -d

Common issues

Port already in use

Another process is using port 3000, 4000, or 4001. Either stop that process or change the port in .env:

GATEWAY_PORT=4100
EXPLORER_PORT=4101
STORE_PORT=3100

Then restart: docker compose -f docker-compose.apps.yml up -d

Chain container exits immediately

Usually insufficient memory. Check docker stats and ensure Docker has at least 4 GB of RAM allocated in Docker Desktop โ†’ Settings โ†’ Resources.

Extension can't connect to local gateway

Browser extensions cannot connect to ws:// (non-TLS) WebSocket endpoints in some browsers by default. Use Brave or Chrome with the --allow-insecure-localhost flag, or use the local TLS option documented in docs/local-tls.md in the repository.

Test USDC balance shows 0

The chain may have started before the USDC funder script ran. Re-run the funder:

docker compose -f docker-compose.infra.yml run --rm funder

Next steps

You have a running local Stablecoin Stack. Where to go from here: