An Overview of Becoming a Maker
Makers run an automated swap backend (asb), which users can connect to and swap with.
The asb accepts Bitcoin and sells Monero, for a fee.
The asb needs to communicate with the Bitcoin and Monero blockchains.
For this, it uses direct FFI wallet access via monero-sys for Monero and electrs for Bitcoin.
It's also strongly recommended to run your own Monero and Bitcoin nodes.
Orchestrator setup
We ship an orchestrator binary that builds a production ready Docker Compose environment for the ASB.
The orchestrator walks you through a wizard, creates the ASB configuration and pins a Docker Compose file with all required services:
asb(the maker service, with built-in wallet functionality connecting directly tomonerodandelectrs)asb-controller(a REPL for issuing JSON-RPC commands to the ASB)asb-tracing-logger(high verbosity ASB logs)electrs(Bitcoin blockchain indexer, connecting tobitcoind)monerod(Monero node)bitcoind(Bitcoin node)
To run this setup you'll need Docker and Docker Compose installed.
Getting started
Download the latest orchestrator release (opens in a new tab) for your platform (or build it from source) and make it executable. If you're on Linux x86_64 you can use the quick install snippet documented in the orchestrator README (opens in a new tab) to fetch the newest binary.
Place the binary in an empty directory and run the wizard:
./orchestratorAnswer the prompts to configure the Bitcoin/Monero networks, exposed ports and ASB options.
When the wizard finishes you'll have a docker-compose.yml, a matching config.toml, and Docker volumes ready to store blockchain data and ASB state.
The README also covers the generated directory layout and additional management commands if you want to dive deeper into the tool's capabilities.
Usage and commands
All Docker commands below are executed from the directory that contains the generated docker-compose.yml file:
cd /path/to/orchestrator-outputIf you aren't familiar with docker compose, here are the most important commands:
| Command | Description |
|---|---|
docker compose up -d --build | Build images (if requested) and start all services. |
docker compose up -d | Start all services using the existing images. |
docker compose down | Stop all services. |
docker compose ps | List all currently running services. |
docker compose pull | Pull the latest images for all services. You need to run docker compose up -d after this to actually update the services. |
docker compose logs -f --tail 100 | Follow logs for all services. Append a service name (for example asb or asb-tracing-logger) to scope the output. |
Once docker compose up reports the containers as healthy you can attach to the ASB controller shell:
docker compose attach asb-controllerThe controller exposes commands such as bitcoin-balance, monero-balance, monero-address, multiaddresses, and get-swaps.
Type help inside the shell to see the full list. Use quit to exit the REPL when you're done.
For more verbose ASB logs, stream the asb-tracing-logger output:
docker compose logs -f --tail 100 asb-tracing-loggerRunning asb commands directly
Some maintenance tasks still require invoking the asb binary instead of going through the JSON-RPC controller. The orchestrator mounts your configuration file at /asb-data/config.toml inside the container, so you can execute commands like history or export-bitcoin-wallet straight from the host:
docker compose exec asb asb --config=/asb-data/config.toml historyIf you generated a testnet/stagenet environment, include the --testnet flag right after the binary name:
docker compose exec asb asb --testnet --config=/asb-data/config.toml historyCommands that modify internal wallets (for example withdraw-btc or export-bitcoin-wallet) work the same way—just replace history with the subcommand you need.
If you need to stop the environment temporarily:
docker compose down
docker compose up -dThe ASB configuration lives in config.toml next to the compose file. You can edit it between runs and reapply the changes by restarting the ASB container (docker compose restart asb).
Asb Configuration
Let's have a look at the asb configuration file. It is used to configure the behaviour of the asb. It uses the TOML language (docs (opens in a new tab)).
The file has different sections, each with different configuration options:
maker: specifies the core behaviour of the asbbitcoin: specifies the Bitcoin configurationmonero: specifies the Monero configurationtor: specifies the Tor configurationdata: specifies the data directorynetwork: specifies the networking configuration
Maker Section
The most important section is the [maker] section, which specifies the core behaviour of the asb.
This is what a standard maker section looks like:
[maker]
min_buy_btc = 0.001
max_buy_btc = 0.1
ask_spread = 0.02
price_ticker_ws_url = "wss://ws.kraken.com/"
external_bitcoin_address = "bc1..."
developer_tip = 0.02
# ...Below an explanation of what each option does:
| Option | Description |
|---|---|
min_buy_btc | The minimum amount of Bitcoin the asb will buy from takers, in BTC. |
max_buy_btc | The maximum amount of Bitcoin the asb will buy from takers, in BTC. |
ask_spread | The markup the asb will charge compared to the market price, as a factor. The market price is fetched via the price_ticker_ws_url. A value of 0.02 means the asb will charge 2% more than the market price. |
price_ticker_ws_url | The URL of a websocket that provides the market price. The default is the Kraken API, but you can build your own websocket server which mimics the Kraken API. |
external_bitcoin_address | Bitcoin address used by the asb when redeeming or punishing swaps. If omitted, a new internal address is generated for each swap. |
developer_tip | Optional donation as a fraction between 0 and 1 (e.g. 0.02 = 2%). Disabled by default. Sent in Monero by adding an extra output to the Monero lock transaction, so no extra transaction and no impact on unlocked UTXOs; privacy preserved. |
Bitcoin Section
The bitcoin section specifies a few details about the asb's interaction with the Bitcoin blockchain.
We do not recommend changing these settings, however we document them for completeness sake.
# ...
[bitcoin]
target_block = 1
electrum_rpc_urls = ["tcp://mainnet_electrs:50001"]
use_mempool_space_fee_estimation = true
network = "Mainnet"
# ...| Option | Description |
|---|---|
target_block | This determines the block height that the asb will try to get it's Bitcoin transactions confirmed at. The default value of 1 means the asb will try to get it's transactions confirmed in the next block. |
electrum_rpc_urls | A list of Electrum servers used to interact with the Bitcoin blockchain. If multiple servers are specified they are tried in order. The default contains the docker-hosted electrs server. |
use_mempool_space_fee_estimation | Whether the asb should fall back to the mempool.space API when fee estimation from Electrum fails. Defaults to true. |
network | The Bitcoin network the asb will connect to. |
Monero Section
The monero section specifies a few details about the asb's interaction with the Monero blockchain.
The asb uses direct FFI wallet access via monero-sys, eliminating the need for monero-wallet-rpc.
We do not recommend changing these settings, however we document them for completeness sake.
# ...
[monero]
daemon_url = "http://your.monero-daemon.org:18081"
network = "Mainnet"
# ...| Option | Description |
|---|---|
daemon_url | The URL of the Monero daemon (monerod) that the asb will connect to directly. The asb manages wallets internally using FFI bindings. Optional: if not specified, the asb will connect to a known public Monero node at random. |
network | The Monero network the asb will connect to. Either "Mainnet" or "Stagenet". |
Tor Section
The tor section specifies the asb's onion service (hidden service) configuration.
An onion service can be used to make the asb publicly accessible without exposing the server's IP address or requiring an opened port (further reading (opens in a new tab)).
# ...
[tor]
register_hidden_service = true
hidden_service_num_intro_points = 5
# ...| Option | Description |
|---|---|
register_hidden_service | Whether the asb should register an onion service. |
hidden_service_num_intro_points | If the asb registers an onion service, this specifies the number of introduction points the asb will use. |
Network Section
The network section specifies the asb's networking configuration.
This includes:
- which rendezvous points the asb will connect to,
- on which port, and
- external addresses the asb will advertise to the rendezvous points.
These addresses are specified using the multiaddr format (link (opens in a new tab)). A multiaddr combines all necessary information into a single string.
For example, the first rendezvous point's multiaddr specifies the rendezvous point at the DNS address discover.unstoppableswap.net, on port 8888 with the peer ID 12D3KooWA6cnqJpVnreBVnoro8midDL9Lpzmg8oJPoAGi7YYaamE.
# ...
[network]
# the ip and port the asb will listen on
listen = ["/ip4/0.0.0.0/tcp/9939"]
# the rendezvous points the asb will connect to (address, port and peer id)
rendezvous_point = [
"/dns4/discover.unstoppableswap.net/tcp/8888/p2p/12D3KooWA6cnqJpVnreBVnoro8midDL9Lpzmg8oJPoAGi7YYaamE",
"/dns4/discover2.unstoppableswap.net/tcp/8888/p2p/12D3KooWGRvf7qVQDrNR5nfYD6rKrbgeTi9x8RrbdxbmsPvxL4mw",
"/dns4/darkness.su/tcp/8888/p2p/12D3KooWFQAgVVS9t9UgL6v1sLprJVM7am5hFK7vy9iBCCoCBYmU",
"/dns4/eigen.center/tcp/8888/p2p/12D3KooWS5RaYJt4ANKMH4zczGVhNcw5W214e2DDYXnjs5Mx5zAT",
"/dns4/swapanarchy.cfd/tcp/8888/p2p/12D3KooWRtyVpmyvwzPYXuWyakFbRKhyXGrjhq6tP7RrBofpgQGp",
"/dns4/rendezvous.observer/tcp/8888/p2p/12D3KooWMjceGXrYuGuDMGrfmJxALnSDbK4km6s1i1sJEgDTgGQa"
]
# the external addresses the asb will advertise to the rendezvous points (only address)
external_addresses = [
# e.g. "/dns4/your.domain.com/tcp/9939/p2p/your1peer2id"
]| Option | Description | Format |
|---|---|---|
listen | The ip and port the asb will listen on. The IP address 0.0.0.0 means the asb will listen on all IP addresses. Remember that the asb service is running in a docker container. Make sure the port is the same as in the .env file. | This multiaddr should only include an IP address and a port number. |
rendezvous_point | A list of rendezvous points the asb will connect to. | These multiaddrs should include an address (e.g. IPv4, IPv6, DNS), a port number and a peer ID. |
external_addresses | A list of external addresses the asb will advertise to the rendezvous points. If you registered a domain, you can add it here. If you enabled the onion service, it will be included automatically, so you don't need to specify the onion address. | These multiaddrs should only include an address (e.g. IPv4, IPv6, DNS). |
Et, voilà! You've successfully configured your asb.
Default Configuration
This is what the default configuration might look like.
[maker]
min_buy_btc = 0.001
max_buy_btc = 0.1
ask_spread = 0.02
price_ticker_ws_url = "wss://ws.kraken.com/"
external_bitcoin_address = "bc1..."
[bitcoin]
electrum_rpc_urls = ["tcp://mainnet_electrs:50001"]
target_block = 1
use_mempool_space_fee_estimation = true
network = "Mainnet"
[monero]
daemon_url = "http://mainnet_monerod:18081"
network = "Mainnet"
[tor]
register_hidden_service = true
hidden_service_num_intro_points = 5
[data]
dir = "/asb-data/"
[network]
listen = ["/ip4/0.0.0.0/tcp/9939"]
rendezvous_point = [
"/dns4/discover.unstoppableswap.net/tcp/8888/p2p/12D3KooWA6cnqJpVnreBVnoro8midDL9Lpzmg8oJPoAGi7YYaamE",
"/dns4/discover2.unstoppableswap.net/tcp/8888/p2p/12D3KooWGRvf7qVQDrNR5nfYD6rKrbgeTi9x8RrbdxbmsPvxL4mw",
"/dns4/darkness.su/tcp/8888/p2p/12D3KooWFQAgVVS9t9UgL6v1sLprJVM7am5hFK7vy9iBCCoCBYmU",
"/dns4/eigen.center/tcp/8888/p2p/12D3KooWS5RaYJt4ANKMH4zczGVhNcw5W214e2DDYXnjs5Mx5zAT",
"/dns4/swapanarchy.cfd/tcp/8888/p2p/12D3KooWRtyVpmyvwzPYXuWyakFbRKhyXGrjhq6tP7RrBofpgQGp",
"/dns4/rendezvous.observer/tcp/8888/p2p/12D3KooWMjceGXrYuGuDMGrfmJxALnSDbK4km6s1i1sJEgDTgGQa",
"/dns4/aswap.click/tcp/8888/p2p/12D3KooWQzW52mdsLHTMu1EPiz3APumG6vGwpCuyy494MAQoEa5X",
"/dns4/getxmr.st/tcp/8888/p2p/12D3KooWHHwiz6WDThPT8cEurstomg3kDSxzL2L8pwxfyX2fpxVk"
]
external_addresses = []