mirror of
https://github.com/comit-network/xmr-btc-swap.git
synced 2025-12-17 17:44:02 -05:00
301 lines
13 KiB
Text
301 lines
13 KiB
Text
import { Callout } from 'nextra/components'
|
|
|
|
## 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 to `monerod` and `electrs`)
|
|
- `asb-controller` (a REPL for issuing JSON-RPC commands to the ASB)
|
|
- `asb-tracing-logger` (high verbosity ASB logs)
|
|
- `electrs` (Bitcoin blockchain indexer, connecting to `bitcoind`)
|
|
- `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](https://github.com/eigenwallet/core/releases) 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](https://github.com/eigenwallet/core/blob/main/swap-orchestrator/README.md#quick-install) to fetch the newest binary.
|
|
|
|
Place the binary in an empty directory and run the wizard:
|
|
|
|
```bash
|
|
./orchestrator
|
|
```
|
|
|
|
Answer 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:
|
|
|
|
```bash copy
|
|
cd /path/to/orchestrator-output
|
|
```
|
|
|
|
If 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:
|
|
|
|
```bash copy
|
|
docker compose attach asb-controller
|
|
```
|
|
|
|
The 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:
|
|
|
|
```bash copy
|
|
docker compose logs -f --tail 100 asb-tracing-logger
|
|
```
|
|
|
|
### Running `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:
|
|
|
|
```bash copy
|
|
docker compose exec asb asb --config=/asb-data/config.toml history
|
|
```
|
|
|
|
If you generated a testnet/stagenet environment, include the `--testnet` flag right after the binary name:
|
|
|
|
```bash copy
|
|
docker compose exec asb asb --testnet --config=/asb-data/config.toml history
|
|
```
|
|
|
|
Commands 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:
|
|
|
|
```bash copy
|
|
docker compose down
|
|
docker compose up -d
|
|
```
|
|
|
|
The 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](https://toml.io/)).
|
|
|
|
The file has different sections, each with different configuration options:
|
|
|
|
- `maker`: specifies the core behaviour of the asb
|
|
- `bitcoin`: specifies the Bitcoin configuration
|
|
- `monero`: specifies the Monero configuration
|
|
- `tor`: specifies the Tor configuration
|
|
- `data`: specifies the data directory
|
|
- `network`: 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:
|
|
|
|
```toml filename="config_mainnet.toml"
|
|
[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.
|
|
|
|
```toml filename="config_mainnet.toml"
|
|
# ...
|
|
|
|
[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.
|
|
|
|
```toml filename="config_mainnet.toml"
|
|
# ...
|
|
|
|
[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](https://community.torproject.org/onion-services/overview/)).
|
|
|
|
```toml filename="config_mainnet.toml"
|
|
# ...
|
|
|
|
[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.
|
|
|
|
<Callout type="info">
|
|
These addresses are specified using the multiaddr format ([link](https://multiformats.io/multiaddr)).
|
|
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`.
|
|
</Callout>
|
|
|
|
```toml filename="config_mainnet.toml"
|
|
# ...
|
|
|
|
[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.
|
|
|
|
```toml filename="config_mainnet.toml" copy
|
|
[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 = []
|
|
```
|