A web dashboard for managing Coinswap maker nodes.
Before deploying: read SECURITY.md. The dashboard manages hot wallets holding real Bitcoin. Make sure you understand the access-control model, wallet storage, and fidelity bond requirements before exposing it to real funds.
Maker Dashboard is a full-stack app with:
- A Rust/Axum backend that exposes a localhost-first REST API
- A React frontend for onboarding, maker management, wallet actions, logs, and swap history
- Production static-file serving from the same backend process
- Swagger UI at
/swagger-ui/for interactive API exploration
The dashboard keeps maker registrations on disk, lets you start and stop makers from the browser, and surfaces operational state such as balances, Tor address, logs, swap reports, and fidelity bond status.
In Coinswap, a maker is a liquidity provider. Makers listen for swap requests from takers, route Bitcoin through their wallets to improve privacy, and earn fees in return. To participate, a maker needs to stay online and maintain a fidelity bond, which is a time-locked Bitcoin deposit used to signal long-term commitment and resist Sybil attacks.
Coinswap's makerd daemon is usually operated through maker-cli. Maker Dashboard provides a browser-based interface on top of the same underlying coinswap library.
For protocol background, see the Coinswap documentation.
- A working Bitcoin Core node
- RPC enabled on your Bitcoin node
- REST enabled on your Bitcoin node (
rest=1) - ZMQ enabled on your Bitcoin node for real-time block and transaction updates
- A local Tor daemon with SOCKS and control ports reachable by the maker
- Rust and
cargofor the backend - Node.js and
npmfor the frontend
Typical local defaults used by the onboarding checks:
- Bitcoin RPC:
127.0.0.1:38332 - Bitcoin ZMQ:
tcp://127.0.0.1:28332 - Tor SOCKS:
127.0.0.1:9050 - Tor control:
127.0.0.1:9051
Build everything:
make buildRun the full app:
make runUseful individual commands:
# Backend
cargo build --release
cargo run
# Frontend
cd frontend && npm install
cd frontend && npm run dev
cd frontend && npm run buildBy default the server listens on http://127.0.0.1:3000. Open that in your browser to use the dashboard. Swagger UI is available at http://127.0.0.1:3000/swagger-ui/.
On first start (no auth.json present), visit /setup in your browser and choose a
password. The password is hashed with argon2id and stored in
~/.config/maker-dashboard/auth.json, and maker configs are encrypted at rest with an
AES-256-GCM key derived from it.
On subsequent starts the dashboard goes straight to the login screen. After a successful login the browser holds a session cookie valid for 24 hours.
See SECURITY.md for the full security model, including the threat model around the unauthenticated setup window.
On first launch the server logs:
First-run setup required. Visit http://127.0.0.1:3000/setup to initialize.
Open the URL, choose a password, and you'll be logged in.
If there are no registered makers, the home page opens a guided onboarding flow. The onboarding wizard helps you:
- Verify Bitcoin Core RPC connectivity
- Verify Bitcoin Core REST availability
- Verify the configured ZMQ endpoint
- Verify local Tor SOCKS and control ports
- Create your first maker from the browser
After a maker is created, the UI takes you to a setup screen that tails live logs while the maker initializes and waits for the fidelity bond flow to complete.
From the web UI you can:
- Add multiple makers
- Start, stop, and restart makers
- View per-maker balances and UTXOs
- Generate deposit addresses and send funds
- Watch live logs or download log files
- Inspect swap history and swap reports
- Update maker configuration
- Remove a maker registration from the dashboard without deleting its wallet data
Registered makers are restored on dashboard restart, but they are not auto-started. They come back in the stopped state until you start them again.
Runtime options can be set with CLI flags or environment variables:
| Flag | Env var | Default | Description |
|---|---|---|---|
--host |
DASHBOARD_HOST |
127.0.0.1 |
IP address to bind to |
--port |
DASHBOARD_PORT |
3000 |
Port to listen on |
--frontend-path |
DASHBOARD_FRONTEND_PATH |
frontend/build/client |
Directory containing built frontend assets |
--spa-index |
DASHBOARD_SPA_INDEX |
frontend/build/client/index.html |
SPA fallback file |
--allow-remote |
DASHBOARD_ALLOW_REMOTE |
false |
Allow non-localhost requests |
--log-filter |
DASHBOARD_LOG_FILTER |
tower_http=debug,info |
Tracing filter directive |
--no-color |
DASHBOARD_NO_COLOR |
false |
Disable ANSI colors in logs |
--config-dir |
DASHBOARD_CONFIG_DIR |
platform default | Dashboard config directory |
By default the dashboard only accepts connections from the local machine. If you enable --allow-remote, place a TLS-terminating reverse proxy in front. the built-in password auth is the only protection on the wire.
Dashboard-managed files:
- Auth config (argon2id hash + salts):
~/.config/maker-dashboard/auth.json - Encrypted maker configs:
~/.config/maker-dashboard/makers.json - Per-maker logs:
~/.coinswap/{id}/debug.log
Maker wallet and data directories are configured per maker and may differ from the dashboard config directory.
The UI will ask for:
- A unique maker ID
- Bitcoin Core RPC address and credentials
- Bitcoin ZMQ address
- Optional wallet password and wallet name
- Optional custom data directory
- Maker network and RPC ports
- Optional Tor SOCKS and control ports
- Fee and fidelity-bond settings
- Optional Nostr relays
If you run multiple makers on one machine, make sure each maker uses unique network and RPC ports.
On first setup, the maker may need funds to create a fidelity bond. You can use the wallet screen to generate an address, fund it, and then continue setup once the wallet has enough coins.
Run the full stack (bitcoind, tor, dashboard) with Docker Compose:
cd docker
docker compose up --build -dThis starts a custom signet bitcoind, a Tor daemon, and the maker dashboard, all sharing the same network namespace. The dashboard is available at http://localhost:3000.
On first run, visit http://localhost:3000/setup and choose a password. On subsequent runs, log in normally.
When creating a maker, use:
- RPC:
127.0.0.1:38332, ZMQ:tcp://127.0.0.1:28332 - RPC credentials:
user/password - Tor auth:
coinswap - SOCKS port:
9050, Control port:9051
Other useful commands:
docker compose ps # status
docker compose logs -f web # dashboard logs
docker compose down -v # stop and wipe all dataHost-exposed ports: 3000 (dashboard), 38332 (RPC), 28332 (ZMQ), 19050 (Tor SOCKS), 19051 (Tor control).
Backend:
cargo test
cargo test --test apiFrontend:
cd frontend && npm run lint
cd frontend && npm run typecheck
cd frontend && npm run buildFull-stack helpers:
make help
make cleanLocal integration test:
cargo test --test integration_test --features integration-test -- --nocaptureDocker-based integration test:
make test-integration-dockerThe Docker integration target uses docker/Dockerfile.integration-test to run the test in a self-contained container with the required services.
Packaging assets for Umbrel, myNode, Docker, and related deployment targets live in packaging/.