diff --git a/.github/workflows/docker-publish-bitcoin.yaml b/.github/workflows/docker-publish-bitcoin.yaml
index 6bbe9db19..c86adc23b 100644
--- a/.github/workflows/docker-publish-bitcoin.yaml
+++ b/.github/workflows/docker-publish-bitcoin.yaml
@@ -34,7 +34,7 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- - name: Build and push
+ - name: Build and push base image
uses: docker/build-push-action@v5
with:
context: .
diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml
index 81b8e6b73..33658c27f 100644
--- a/.github/workflows/docker.yaml
+++ b/.github/workflows/docker.yaml
@@ -22,9 +22,6 @@ jobs:
- name: Test taker
run: docker run --rm coinswap/coinswap:latest taker --help
- - name: Start Coinswap stack
- run: ./docker-setup start --default
-
- name: Wait for services to be healthy
run: |
echo "Waiting for services to start..."
diff --git a/docker-compose.yml b/docker-compose.yml
index e743b83ab..25c6a75a3 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,61 +1,137 @@
services:
+ bitcoind:
+ image: coinswap/${BITCOIN_IMAGE_NAME:-bitcoin-mutinynet}:${BITCOIN_TAG:-latest}
+ container_name: coinswap-bitcoind
+ profiles: ["internal-bitcoind"]
+ command: >
+ bitcoind
+ ${BITCOIN_NETWORK_ARG}
+ -rpcbind=0.0.0.0
+ -rpcallowip=0.0.0.0/0
+ ports:
+ - "${BITCOIN_RPC_PORT:-38332}:${BITCOIN_RPC_PORT:-38332}"
+ - "${BITCOIN_ZMQ_PORT:-28332}:${BITCOIN_ZMQ_PORT:-28332}"
+ volumes:
+ - bitcoin-data:/home/bitcoin/.bitcoin
+ - ./docs/bitcoin.conf:/home/bitcoin/.bitcoin/bitcoin.conf:ro
+ restart: unless-stopped
+ healthcheck:
+ test: ["CMD", "bitcoin-cli", "-rpcuser=${BITCOIN_RPC_USER:-user}", "-rpcpassword=${BITCOIN_RPC_PASSWORD:-password}", "-rpcport=${BITCOIN_RPC_PORT:-38332}", "getblockchaininfo"]
+ interval: 30s
+ timeout: 10s
+ retries: 5
tor:
image: osminogin/tor-simple
- container_name: tor
- restart: unless-stopped
- ports:
- - "${TOR_SOCKS_PORT:-19050}:${TOR_SOCKS_PORT:-19050}"
- - "${TOR_CONTROL_PORT:-19051}:${TOR_CONTROL_PORT:-19051}"
- - "${MAKER_RPC_PORT:-6113}:${MAKER_RPC_PORT:-6113}"
+ container_name: coinswap-tor
+ profiles: ["internal-tor"]
+ network_mode: "host"
+ entrypoint: /bin/sh
+ command:
+ - -c
+ - |
+ HASH=$$(tor --hash-password "$${TOR_AUTH_PASSWORD}" | grep "^16:")
+
+ # use /tmp/torrc because the container runs as non-root and cannot write to /etc/tor/
+ cat > /tmp/torrc << EOF
+ SocksPort 0.0.0.0:$${TOR_SOCKS_PORT:-9050}
+ ControlPort 0.0.0.0:$${TOR_CONTROL_PORT:-9051}
+ DataDirectory /var/lib/tor
+ HashedControlPassword $$HASH
+ EOF
+ echo "Starting Tor with the following configuration:"
+ cat /tmp/torrc
+ echo ""
+
+ exec tor -f /tmp/torrc
volumes:
- - ./torrc:/etc/tor/torrc:ro
- tor-data:/var/lib/tor
+ ports:
+ - "127.0.0.1:${TOR_SOCKS_PORT:-9050}:${TOR_SOCKS_PORT:-9050}"
+ - "127.0.0.1:${TOR_CONTROL_PORT:-9051}:${TOR_CONTROL_PORT:-9051}"
+ - "${MAKERD_RPC_PORT:-6103}:${MAKERD_RPC_PORT:-6103}"
+ environment:
+ - TOR_SOCKS_PORT=${TOR_SOCKS_PORT:-9050}
+ - TOR_CONTROL_PORT=${TOR_CONTROL_PORT:-9051}
+ - TOR_AUTH_PASSWORD=${TOR_AUTH_PASSWORD}
+ restart: unless-stopped
makerd:
- image: coinswap/coinswap:master
+ image: coinswap/${IMAGE_NAME:-coinswap}:latest
container_name: coinswap-makerd
- network_mode: "service:tor"
- command:
+ profiles: ["external-tor"]
+ network_mode: "host"
+ command: &makerd-command
- sh
- -c
- |
sleep 15
mkdir -p /home/coinswap/.coinswap/maker
- printf '%s\n' \
- "network_port = ${MAKER_NETWORK_PORT:-6112}" \
- "rpc_port = ${MAKER_RPC_PORT:-6113}" \
- "socks_port = ${TOR_SOCKS_PORT:-19050}" \
- "control_port = ${TOR_CONTROL_PORT:-19051}" \
- "tor_auth_password = ${TOR_AUTH_PASSWORD:-coinswap}" \
- "min_swap_amount = ${MIN_SWAP_AMOUNT:-10000}" \
- "fidelity_amount = ${FIDELITY_AMOUNT:-50000}" \
- "fidelity_timelock = ${FIDELITY_TIMELOCK:-13104}" \
- "connection_type = TOR" \
- "base_fee = ${BASE_FEE:-100}" \
- "amount_relative_fee_ppt = ${AMOUNT_RELATIVE_FEE_PPT:-1000}" \
- > /home/coinswap/.coinswap/maker/config.toml
- makerd -w ${WALLET_NAME} -r ${BITCOIN_RPC_HOST:-172.81.178.3:48332} -a ${BITCOIN_RPC_AUTH:-user:password} --taproot
+
+ cat > /home/coinswap/.coinswap/maker/config.toml << EOM
+ network_port = $${MAKER_NETWORK_PORT:-6102}
+ rpc_port = $${MAKER_RPC_PORT:-6103}
+ socks_port = $${TOR_SOCKS_PORT:-9050}
+ control_port = $${TOR_CONTROL_PORT:-9051}
+ tor_auth_password = "$${TOR_AUTH_PASSWORD}"
+ min_swap_amount = $${MIN_SWAP_AMOUNT:-10000}
+ fidelity_amount = $${FIDELITY_AMOUNT:-50000}
+ fidelity_timelock = $${FIDELITY_TIMELOCK:-13104}
+ connection_type = "TOR"
+ base_fee = $${BASE_FEE:-100}
+ amount_relative_fee_ppt = $${AMOUNT_RELATIVE_FEE_PPT:-1000}
+ EOM
+
+ WALLET_NAME="$${BITCOIN_WALLET_NAME:-coinswap-maker}"
+ echo "INFO: Using wallet: $$WALLET_NAME"
+
+ echo "[DEBUG] Running: makerd -t \"$${TOR_AUTH_PASSWORD}\" -r $${BITCOIN_RPC_HOST} -a $${BITCOIN_RPC_AUTH} $${MAKERD_EXTRA_ARGS} -w \"$$WALLET_NAME\""
+
+ makerd -t "$${TOR_AUTH_PASSWORD}" -r $${BITCOIN_RPC_HOST} -a $${BITCOIN_RPC_AUTH} $${MAKERD_EXTRA_ARGS} -w "$$WALLET_NAME"
+ ports:
+ - "${MAKERD_PORT:-6102}:${MAKERD_PORT:-6102}"
+ - "${MAKERD_RPC_PORT:-6103}:${MAKERD_RPC_PORT:-6103}"
volumes:
- maker-data:/home/coinswap/.coinswap
- environment:
+ environment: &makerd-env
- RUST_LOG=${RUST_LOG:-info}
- - TOR_SOCKS_PORT=${TOR_SOCKS_PORT:-19050}
- - TOR_CONTROL_PORT=${TOR_CONTROL_PORT:-19051}
- - TOR_AUTH_PASSWORD=${TOR_AUTH_PASSWORD:-coinswap}
- - MAKER_NETWORK_PORT=${MAKER_NETWORK_PORT:-6112}
- - MAKER_RPC_PORT=${MAKER_RPC_PORT:-6113}
+ - MAKER_NETWORK_PORT=${MAKERD_PORT:-6102}
+ - MAKER_RPC_PORT=${MAKERD_RPC_PORT:-6103}
+ - TOR_SOCKS_PORT=${TOR_SOCKS_PORT:-9050}
+ - TOR_CONTROL_PORT=${TOR_CONTROL_PORT:-9051}
+ - TOR_AUTH_PASSWORD=${TOR_AUTH_PASSWORD}
- MIN_SWAP_AMOUNT=${MIN_SWAP_AMOUNT:-10000}
- FIDELITY_AMOUNT=${FIDELITY_AMOUNT:-50000}
- FIDELITY_TIMELOCK=${FIDELITY_TIMELOCK:-13104}
- BASE_FEE=${BASE_FEE:-100}
- AMOUNT_RELATIVE_FEE_PPT=${AMOUNT_RELATIVE_FEE_PPT:-1000}
- - BITCOIN_RPC_HOST=${BITCOIN_RPC_HOST:-172.81.178.3:48332}
+ - BITCOIN_RPC_HOST=${BITCOIN_RPC_HOST}
- BITCOIN_RPC_AUTH=${BITCOIN_RPC_AUTH:-user:password}
+ - MAKERD_EXTRA_ARGS=${MAKERD_EXTRA_ARGS}
+ - BITCOIN_WALLET_NAME=${BITCOIN_WALLET_NAME:-coinswap-maker}
restart: unless-stopped
+ makerd-internal:
+ image: coinswap/${IMAGE_NAME:-coinswap}:latest
+ container_name: coinswap-makerd
+ profiles: ["internal-tor"]
+ network_mode: "host"
+ command: *makerd-command
+ volumes:
+ - maker-data:/home/coinswap/.coinswap
+ environment: *makerd-env
+ restart: unless-stopped
+ depends_on:
+ - tor
+
volumes:
+ bitcoin-data:
+ driver: local
tor-data:
driver: local
maker-data:
driver: local
+
+networks:
+ default:
+ name: coinswap-network
diff --git a/docker-setup b/docker-setup
index 0355e8011..679019947 100755
--- a/docker-setup
+++ b/docker-setup
@@ -12,10 +12,13 @@ DEFAULT_BITCOIN_DATADIR="/home/coinswap/.bitcoin"
DEFAULT_BITCOIN_NETWORK="signet"
DEFAULT_BITCOIN_RPC_PORT="38332"
DEFAULT_BITCOIN_ZMQ_PORT="28332"
-DEFAULT_MAKERD_PORT="6012"
-DEFAULT_MAKERD_RPC_PORT="6013"
+DEFAULT_MAKERD_PORT="6102"
+DEFAULT_MAKERD_RPC_PORT="6103"
DEFAULT_TOR_SOCKS_PORT="9050"
DEFAULT_TOR_CONTROL_PORT="9051"
+DEFAULT_RPC_USER="user"
+DEFAULT_RPC_PASSWORD="password"
+DEFAULT_TOR_AUTH=""
RED='\033[0;31m'
GREEN='\033[0;32m'
@@ -52,15 +55,19 @@ BITCOIN_DATADIR="$BITCOIN_DATADIR"
BITCOIN_NETWORK="$BITCOIN_NETWORK"
BITCOIN_RPC_PORT="$BITCOIN_RPC_PORT"
BITCOIN_ZMQ_PORT="$BITCOIN_ZMQ_PORT"
+BITCOIN_RPC_USER="$BITCOIN_RPC_USER"
+BITCOIN_RPC_PASSWORD="$BITCOIN_RPC_PASSWORD"
MAKERD_PORT="$MAKERD_PORT"
MAKERD_RPC_PORT="$MAKERD_RPC_PORT"
USE_TAPROOT="$USE_TAPROOT"
TOR_SOCKS_PORT="$TOR_SOCKS_PORT"
TOR_CONTROL_PORT="$TOR_CONTROL_PORT"
+TOR_AUTH_PASSWORD="$TOR_AUTH_PASSWORD"
USE_EXTERNAL_BITCOIND="$USE_EXTERNAL_BITCOIND"
USE_EXTERNAL_TOR="$USE_EXTERNAL_TOR"
EXTERNAL_BITCOIND_HOST="$EXTERNAL_BITCOIND_HOST"
EXTERNAL_TOR_HOST="$EXTERNAL_TOR_HOST"
+BITCOIN_WALLET_NAME="$BITCOIN_WALLET_NAME"
EOF
print_success "Configuration saved to $CONFIG_FILE"
}
@@ -91,6 +98,164 @@ check_bitcoind_running() {
fi
}
+setup_env() {
+ # load configuration
+ load_config
+
+ # set defaults for any unset variables
+ BITCOIN_DATADIR="${BITCOIN_DATADIR:-$DEFAULT_BITCOIN_DATADIR}"
+ BITCOIN_NETWORK="${BITCOIN_NETWORK:-$DEFAULT_BITCOIN_NETWORK}"
+ BITCOIN_RPC_PORT="${BITCOIN_RPC_PORT:-$DEFAULT_BITCOIN_RPC_PORT}"
+ BITCOIN_ZMQ_PORT="${BITCOIN_ZMQ_PORT:-$DEFAULT_BITCOIN_ZMQ_PORT}"
+ BITCOIN_RPC_USER="${BITCOIN_RPC_USER:-$DEFAULT_RPC_USER}"
+ BITCOIN_RPC_PASSWORD="${BITCOIN_RPC_PASSWORD:-$DEFAULT_RPC_PASSWORD}"
+ MAKERD_PORT="${MAKERD_PORT:-$DEFAULT_MAKERD_PORT}"
+ MAKERD_RPC_PORT="${MAKERD_RPC_PORT:-$DEFAULT_MAKERD_RPC_PORT}"
+ USE_TAPROOT="${USE_TAPROOT:-true}"
+ TOR_SOCKS_PORT="${TOR_SOCKS_PORT:-$DEFAULT_TOR_SOCKS_PORT}"
+ TOR_CONTROL_PORT="${TOR_CONTROL_PORT:-$DEFAULT_TOR_CONTROL_PORT}"
+ TOR_AUTH_PASSWORD="${TOR_AUTH_PASSWORD:-$DEFAULT_TOR_AUTH}"
+ USE_EXTERNAL_BITCOIND="${USE_EXTERNAL_BITCOIND:-false}"
+ USE_EXTERNAL_TOR="${USE_EXTERNAL_TOR:-false}"
+ BITCOIN_WALLET_NAME="${BITCOIN_WALLET_NAME:-coinswap-maker}"
+
+ # export variables for docker-compose
+ export IMAGE_NAME="${IMAGE_NAME}"
+ export BITCOIN_IMAGE_NAME="${BITCOIN_IMAGE_NAME}"
+
+ export BITCOIN_TAG="latest"
+ if [ -f "$VERSION_FILE" ]; then
+ export BITCOIN_TAG=$(grep "^TAG=" "$VERSION_FILE" | cut -d'=' -f2)
+ fi
+
+ export BITCOIN_RPC_PORT
+ export BITCOIN_ZMQ_PORT
+ export BITCOIN_RPC_USER
+ export BITCOIN_RPC_PASSWORD
+ export BITCOIN_RPC_AUTH="${BITCOIN_RPC_USER}:${BITCOIN_RPC_PASSWORD}"
+ export MAKERD_PORT
+ export MAKERD_RPC_PORT
+ export TOR_SOCKS_PORT
+ export TOR_CONTROL_PORT
+ export BITCOIN_WALLET_NAME
+
+ export BITCOIN_NETWORK_ARG=""
+ if [[ "$BITCOIN_NETWORK" == "signet" ]]; then
+ export BITCOIN_NETWORK_ARG="-signet=1"
+ else
+ export BITCOIN_NETWORK_ARG="-regtest=1"
+ fi
+
+ # makerd args
+ export MAKERD_EXTRA_ARGS=""
+ if [[ "$USE_TAPROOT" == "true" ]]; then
+ export MAKERD_EXTRA_ARGS="--taproot"
+ fi
+
+ # profiles and hosts
+ local profiles=""
+
+ if [[ "$USE_EXTERNAL_BITCOIND" == "true" ]]; then
+ export BITCOIN_RPC_HOST="$EXTERNAL_BITCOIND_HOST"
+ else
+ profiles="${profiles}internal-bitcoind,"
+ # use localhost since makerd runs with network_mode: host
+ export BITCOIN_RPC_HOST="localhost:$BITCOIN_RPC_PORT"
+ fi
+
+ if [[ "$USE_EXTERNAL_TOR" == "true" ]]; then
+ profiles="${profiles}external-tor"
+ else
+ profiles="${profiles}internal-tor"
+ TOR_AUTH_PASSWORD=$DEFAULT_TOR_AUTH
+ fi
+
+ export TOR_AUTH_PASSWORD
+ export COMPOSE_PROFILES="${profiles%,}"
+}
+
+# List wallets from a bitcoind instance
+list_bitcoin_wallets() {
+ local rpc_host="$1"
+ local rpc_user="$2"
+ local rpc_pass="$3"
+
+ local response=$(curl -s --user "${rpc_user}:${rpc_pass}" \
+ --data-binary '{"jsonrpc":"1.0","method":"listwalletdir","params":[]}' \
+ -H 'content-type:text/plain;' \
+ "http://${rpc_host}/" 2>/dev/null)
+
+ if [ $? -ne 0 ] || [ -z "$response" ]; then
+ return 1
+ fi
+
+ # Extract wallet names from JSON response
+ echo "$response" | grep -o '"name":"[^"]*"' | cut -d'"' -f4
+}
+
+# Prompt user to select or create a wallet
+select_bitcoin_wallet() {
+ local rpc_host="$1"
+ local rpc_user="$2"
+ local rpc_pass="$3"
+
+ echo ""
+ print_info "Bitcoin Wallet Configuration"
+ echo "----------------------------------------"
+
+ # Try to list existing wallets
+ print_info "Fetching existing wallets from bitcoind..."
+ local wallets=$(list_bitcoin_wallets "$rpc_host" "$rpc_user" "$rpc_pass")
+
+ if [ -n "$wallets" ]; then
+ echo ""
+ echo "Existing wallets found:"
+ echo "----------------------------------------"
+ local i=1
+ local wallet_array=()
+ while IFS= read -r wallet; do
+ if [ -n "$wallet" ]; then
+ echo " $i) $wallet"
+ wallet_array+=("$wallet")
+ ((i++))
+ fi
+ done <<< "$wallets"
+ echo ""
+ echo " $i) Create a new wallet"
+ echo ""
+
+ read -p "Select a wallet [1-$i]: " wallet_choice
+
+ if [ "$wallet_choice" -eq "$i" ] 2>/dev/null; then
+ # Create new wallet
+ read -p "Enter new wallet name: " new_wallet_name
+ while [ -z "$new_wallet_name" ]; do
+ print_error "Wallet name cannot be empty"
+ read -p "Enter new wallet name: " new_wallet_name
+ done
+ BITCOIN_WALLET_NAME="$new_wallet_name"
+ print_info "Will create new wallet: $BITCOIN_WALLET_NAME"
+ elif [ "$wallet_choice" -ge 1 ] && [ "$wallet_choice" -lt "$i" ] 2>/dev/null; then
+ BITCOIN_WALLET_NAME="${wallet_array[$((wallet_choice-1))]}"
+ print_info "Selected wallet: $BITCOIN_WALLET_NAME"
+ else
+ print_error "Invalid selection"
+ select_bitcoin_wallet "$rpc_host" "$rpc_user" "$rpc_pass"
+ return
+ fi
+ else
+ print_warning "Could not fetch wallet list from bitcoind."
+ print_info "This may be because bitcoind is not running or RPC is not accessible."
+ echo ""
+ read -p "Enter wallet name to use/create: " new_wallet_name
+ while [ -z "$new_wallet_name" ]; do
+ print_error "Wallet name cannot be empty"
+ read -p "Enter wallet name to use/create: " new_wallet_name
+ done
+ BITCOIN_WALLET_NAME="$new_wallet_name"
+ fi
+}
+
configure_setup() {
echo ""
print_info "Coinswap Docker Configuration"
@@ -117,75 +282,186 @@ configure_setup() {
echo ""
echo "Select Bitcoin Node Source:"
- echo "1) Run Local Node (Docker)"
+ echo ""
+ echo " 1) Connect to your existing bitcoind node (Recommended)"
+ echo " - Most sovereign option, requires your own node"
+ echo " - Must be configured per docs/bitcoind.md"
+ echo ""
+ echo " 2) Use pre-configured bitcoind Docker image"
+ echo " - Quick setup, runs locally in Docker"
+ echo ""
if [ "$BITCOIN_NETWORK" == "signet" ]; then
- echo "2) Use Coinswap Public Node"
+ echo " 3) Connect to Public Mutinynet Node (Dev testing only)"
+ echo " - WARNING: Leaks your transaction graph to a third party"
+ echo " - Only use for quick developer testing, never for real funds"
+ echo ""
fi
- echo "3) Connect to External Node"
- read -p "Source [1]: " source_choice
+ read -p "Select option [1]: " source_choice
+ source_choice=${source_choice:-1}
USE_EXTERNAL_BITCOIND="false"
-
- if [ "$BITCOIN_NETWORK" == "signet" ] && [ "${source_choice:-1}" == "2" ]; then
- USE_EXTERNAL_BITCOIND="true"
- EXTERNAL_BITCOIND_HOST="172.81.178.3:48332"
- BITCOIN_ZMQ_PORT="58332"
- print_info "Using Coinswap Public Node at $EXTERNAL_BITCOIND_HOST"
- elif [ "${source_choice:-1}" == "3" ] || ([ "$BITCOIN_NETWORK" != "signet" ] && [ "${source_choice:-1}" == "2" ]); then
- USE_EXTERNAL_BITCOIND="true"
- read -p "Bitcoin RPC host [localhost:$BITCOIN_RPC_PORT]: " btc_host
- EXTERNAL_BITCOIND_HOST="${btc_host:-localhost:$BITCOIN_RPC_PORT}"
- else
- if check_bitcoind_running "$BITCOIN_RPC_PORT"; then
- print_warning "Detected Bitcoin Core running on port $BITCOIN_RPC_PORT"
- read -p "Port is in use. Use this existing instance instead? [Y/n]: " use_existing
- if [[ "${use_existing:-Y}" =~ ^[Yy]$ ]]; then
+ configure_docker_node="false"
+ BITCOIN_WALLET_NAME=""
+
+ case "$source_choice" in
+ 1)
+ echo ""
+ print_warning "Your node must be configured correctly as per: docs/bitcoind.md"
+ print_warning "Refrence bitcoin configuration: docs/bitcoin.conf"
+ echo ""
+ read -p "Are you sure your node is configured properly? [y/N]: " confirm_existing
+ if [[ ! "${confirm_existing}" =~ ^[Yy]$ ]]; then
+ print_info "Falling back to Docker image..."
+ configure_docker_node="true"
+ else
USE_EXTERNAL_BITCOIND="true"
- EXTERNAL_BITCOIND_HOST="localhost:$BITCOIN_RPC_PORT"
+
+ read -p "Bitcoin RPC host [localhost:$BITCOIN_RPC_PORT]: " btc_host
+ EXTERNAL_BITCOIND_HOST="${btc_host:-localhost:$BITCOIN_RPC_PORT}"
+
+ read -p "Bitcoin RPC user [${DEFAULT_RPC_USER}]: " rpc_user
+ BITCOIN_RPC_USER="${rpc_user:-$DEFAULT_RPC_USER}"
+
+ read -p "Bitcoin RPC password [${DEFAULT_RPC_PASSWORD}]: " rpc_pass
+ BITCOIN_RPC_PASSWORD="${rpc_pass:-$DEFAULT_RPC_PASSWORD}"
+
+ read -p "Bitcoin ZMQ port [$BITCOIN_ZMQ_PORT]: " btc_zmq_port
+ BITCOIN_ZMQ_PORT="${btc_zmq_port:-$BITCOIN_ZMQ_PORT}"
+
+ select_bitcoin_wallet "$EXTERNAL_BITCOIND_HOST" "$BITCOIN_RPC_USER" "$BITCOIN_RPC_PASSWORD"
+ fi
+ ;;
+ 3)
+ if [ "$BITCOIN_NETWORK" == "signet" ]; then
+ echo ""
+ print_warning "============================================"
+ print_warning " PRIVACY WARNING"
+ print_warning "============================================"
+ print_warning "Using a public node exposes your transaction graph!"
+ print_warning "The node operator can see all your wallet activity."
+ print_warning "DO NOT use this for real funds or private swaps."
+ print_warning "This option is ONLY for quick developer testing."
+ echo ""
+ read -p "I understand the privacy risks and want to continue [y/N]: " confirm_public
+ if [[ ! "${confirm_public}" =~ ^[Yy]$ ]]; then
+ print_info "Falling back to Docker image..."
+ configure_docker_node="true"
+ else
+ USE_EXTERNAL_BITCOIND="true"
+ EXTERNAL_BITCOIND_HOST="172.81.178.3:48332"
+ BITCOIN_ZMQ_PORT="58332"
+ BITCOIN_RPC_USER="user"
+ BITCOIN_RPC_PASSWORD="password"
+ BITCOIN_WALLET_NAME="coinswap-$(head -c 8 /dev/urandom | xxd -p)"
+ print_info "Using Coinswap Public Node at $EXTERNAL_BITCOIND_HOST"
+ print_info "Auto-generated wallet name: $BITCOIN_WALLET_NAME"
+ fi
else
- print_warning "Continuing with local node configuration. Startup may fail if port is bound."
+ print_error "Public node only available for Mutinynet."
+ configure_docker_node="true"
fi
- fi
+ ;;
+ *)
+ configure_docker_node="true"
+ ;;
+ esac
+
+ if [ "$configure_docker_node" == "true" ]; then
+ USE_EXTERNAL_BITCOIND="false"
+ echo ""
+ print_info "Using Docker Bitcoin image (will sync from scratch)."
- if [[ "$USE_EXTERNAL_BITCOIND" == "false" ]]; then
- read -p "Bitcoin RPC port [$BITCOIN_RPC_PORT]: " btc_port
- BITCOIN_RPC_PORT="${btc_port:-$BITCOIN_RPC_PORT}"
- read -p "Bitcoin ZMQ port [$BITCOIN_ZMQ_PORT]: " btc_zmq_port
- BITCOIN_ZMQ_PORT="${btc_zmq_port:-$BITCOIN_ZMQ_PORT}"
- fi
+ read -p "Bitcoin RPC port [$BITCOIN_RPC_PORT]: " btc_port
+ BITCOIN_RPC_PORT="${btc_port:-$BITCOIN_RPC_PORT}"
+ read -p "Bitcoin ZMQ port [$BITCOIN_ZMQ_PORT]: " btc_zmq_port
+ BITCOIN_ZMQ_PORT="${btc_zmq_port:-$BITCOIN_ZMQ_PORT}"
+
+ read -p "Bitcoin RPC user [${DEFAULT_RPC_USER}]: " rpc_user
+ BITCOIN_RPC_USER="${rpc_user:-$DEFAULT_RPC_USER}"
+
+ read -p "Bitcoin RPC password [${DEFAULT_RPC_PASSWORD}]: " rpc_pass
+ BITCOIN_RPC_PASSWORD="${rpc_pass:-$DEFAULT_RPC_PASSWORD}"
+
+ echo ""
+ print_info "Wallet will be configured after bitcoind syncs."
+ read -p "Enter wallet name to create [coinswap-maker]: " wallet_name
+ BITCOIN_WALLET_NAME="${wallet_name:-coinswap-maker}"
fi
echo ""
print_info "Tor Configuration"
echo "----------------------------------------"
+ USE_EXTERNAL_TOR="false"
+ TOR_CONFIGURED="false"
+
if check_tor_running; then
print_info "Detected Tor running on port 9050"
- read -p "Use existing Tor instance? [Y/n]: " use_existing_tor
- if [[ "${use_existing_tor:-Y}" =~ ^[Yy]$ ]]; then
- USE_EXTERNAL_TOR="true"
- read -p "Tor SOCKS host [localhost:9050]: " tor_host
- EXTERNAL_TOR_HOST="${tor_host:-localhost:9050}"
- else
- USE_EXTERNAL_TOR="false"
- read -p "Tor SOCKS port [${DEFAULT_TOR_SOCKS_PORT}]: " tor_socks
- TOR_SOCKS_PORT="${tor_socks:-$DEFAULT_TOR_SOCKS_PORT}"
- read -p "Tor control port [${DEFAULT_TOR_CONTROL_PORT}]: " tor_control
- TOR_CONTROL_PORT="${tor_control:-$DEFAULT_TOR_CONTROL_PORT}"
+ echo ""
+ read -p "Do you want to use this existing Tor instance? [y/N]: " use_existing_tor
+ if [[ "${use_existing_tor}" =~ ^[Yy]$ ]]; then
+ echo ""
+ print_warning "============================================"
+ print_warning "Your Tor must be configured correctly for makerd!"
+ print_warning "Required: ControlPort enabled with authentication"
+ print_warning "See: docs/tor.md for configuration details"
+ print_warning "============================================"
+ echo ""
+ read -p "Are you sure your Tor is configured properly? [y/N]: " confirm_tor
+ if [[ "${confirm_tor}" =~ ^[Yy]$ ]]; then
+ USE_EXTERNAL_TOR="true"
+ TOR_CONFIGURED="true"
+
+ read -p "Tor SOCKS host [localhost:9050]: " tor_host
+ EXTERNAL_TOR_HOST="${tor_host:-localhost:9050}"
+
+ read -p "Tor Auth Password [${DEFAULT_TOR_AUTH}]: " tor_auth
+ TOR_AUTH_PASSWORD="${tor_auth:-$DEFAULT_TOR_AUTH}"
+ else
+ print_info "Using internal Tor container instead..."
+ fi
fi
- else
+ fi
+
+ if [ "$TOR_CONFIGURED" == "false" ]; then
USE_EXTERNAL_TOR="false"
- read -p "Tor SOCKS port [${DEFAULT_TOR_SOCKS_PORT}]: " tor_socks
- TOR_SOCKS_PORT="${tor_socks:-$DEFAULT_TOR_SOCKS_PORT}"
- read -p "Tor control port [${DEFAULT_TOR_CONTROL_PORT}]: " tor_control
- TOR_CONTROL_PORT="${tor_control:-$DEFAULT_TOR_CONTROL_PORT}"
+ echo ""
+
+ if check_tor_running; then
+ print_warning "Default Tor port 9050 is already in use."
+ print_info "You must specify custom ports for the internal Tor container."
+ echo ""
+
+ read -p "Tor SOCKS port (must not be 9050): " tor_socks
+ while [ -z "$tor_socks" ] || [ "$tor_socks" == "9050" ]; do
+ print_error "Please enter a valid port that is not 9050"
+ read -p "Tor SOCKS port: " tor_socks
+ done
+ TOR_SOCKS_PORT="$tor_socks"
+
+ read -p "Tor Control port (must not be 9051): " tor_control
+ while [ -z "$tor_control" ] || [ "$tor_control" == "9051" ]; do
+ print_error "Please enter a valid port that is not 9051"
+ read -p "Tor Control port: " tor_control
+ done
+ TOR_CONTROL_PORT="$tor_control"
+ else
+ TOR_SOCKS_PORT="$DEFAULT_TOR_SOCKS_PORT"
+ TOR_CONTROL_PORT="$DEFAULT_TOR_CONTROL_PORT"
+ fi
+
+ print_info "Using internal Tor container with configuration:"
+ echo " SOCKS Port: ${TOR_SOCKS_PORT}"
+ echo " Control Port: ${TOR_CONTROL_PORT}"
+ echo " Auth Password: (empty)"
+ TOR_AUTH_PASSWORD=$DEFAULT_TOR_AUTH
fi
echo ""
print_info "Coinswap Maker Ports"
echo "----------------------------------------"
-
+
read -p "Makerd RPC port [${DEFAULT_MAKERD_RPC_PORT}]: " makerd_rpc
MAKERD_RPC_PORT="${makerd_rpc:-$DEFAULT_MAKERD_RPC_PORT}"
@@ -203,6 +479,8 @@ configure_setup() {
echo "Bitcoin Data Dir: $BITCOIN_DATADIR"
echo "Bitcoin RPC Port: $BITCOIN_RPC_PORT"
echo "Bitcoin ZMQ Port: $BITCOIN_ZMQ_PORT"
+ echo "Bitcoin RPC User: $BITCOIN_RPC_USER"
+ echo "Bitcoin Wallet: $BITCOIN_WALLET_NAME"
echo "Use External Bitcoin: $USE_EXTERNAL_BITCOIND"
if [[ "$USE_EXTERNAL_BITCOIND" == "true" ]]; then
echo "External Bitcoin Host: $EXTERNAL_BITCOIND_HOST"
@@ -214,6 +492,7 @@ configure_setup() {
echo "Tor SOCKS Port: $TOR_SOCKS_PORT"
echo "Tor Control Port: $TOR_CONTROL_PORT"
fi
+ echo "Tor Auth Password: $TOR_AUTH_PASSWORD"
echo "Makerd Port: $MAKERD_PORT"
echo "Makerd RPC Port: $MAKERD_RPC_PORT"
echo "Use Taproot: $USE_TAPROOT"
@@ -239,189 +518,6 @@ check_docker() {
print_success "Docker is available and running"
}
-generate_torrc() {
- local torrc_file="$SCRIPT_DIR/torrc.generated"
- print_info "Generating torrc configuration..."
-
- cat > "$torrc_file" << EOF
-SocksPort 0.0.0.0:${TOR_SOCKS_PORT}
-ControlPort 0.0.0.0:${TOR_CONTROL_PORT}
-HashedControlPassword 16:16E946B27E1A526E60A2B64061EC3F140ACA991F1B705ACD35374D6730
-DataDirectory /var/lib/tor
-EOF
- print_success "Generated torrc: $torrc_file"
-}
-
-generate_compose_file() {
- local compose_file="$SCRIPT_DIR/docker-compose.generated.yml"
-
- # Generate torrc first if using internal Tor
- if [[ "$USE_EXTERNAL_TOR" != "true" ]]; then
- generate_torrc
- fi
-
- # Read Bitcoin version tag
- local bitcoin_tag="latest"
- if [ -f "$VERSION_FILE" ]; then
- # Extract TAG value
- bitcoin_tag=$(grep "^TAG=" "$VERSION_FILE" | cut -d'=' -f2)
- fi
-
- print_info "Generating docker-compose configuration..."
-
- local rpc_host="bitcoind:$BITCOIN_RPC_PORT"
- if [[ "$USE_EXTERNAL_BITCOIND" == "true" ]]; then
- rpc_host="$EXTERNAL_BITCOIND_HOST"
- fi
-
- local makerd_args_cmd="makerd -r \${BITCOIN_RPC_HOST:-$rpc_host} -a \${BITCOIN_RPC_AUTH:-user:password}"
- if [[ "$USE_TAPROOT" == "true" ]]; then
- makerd_args_cmd="$makerd_args_cmd --taproot"
- fi
-
- cat > "$compose_file" << EOF
-services:
-EOF
-
- if [[ "$USE_EXTERNAL_BITCOIND" != "true" ]]; then
- # construct bitcoind command
- local btc_cmd="bitcoind -datadir=/home/bitcoin/.bitcoin -server=1 -rpcuser=user -rpcpassword=password -rpcallowip=0.0.0.0/0 -txindex=1 -blockfilterindex=1"
-
- if [[ "$BITCOIN_NETWORK" == "signet" ]]; then
- btc_cmd="$btc_cmd -signet=1 -signetchallenge=512102f7561d208dd9ae99bf497273e16f389bdbd6c4742ddb8e6b216e64fa2928ad8f51ae -addnode=45.79.52.207:38333 -dnsseed=0 -signetblocktime=30"
- else
- btc_cmd="$btc_cmd -regtest=1 -fallbackfee=0.00001000"
- fi
-
- btc_cmd="$btc_cmd -rpcbind=0.0.0.0 -rpcport=$BITCOIN_RPC_PORT -zmqpubrawblock=tcp://0.0.0.0:$BITCOIN_ZMQ_PORT -zmqpubrawtx=tcp://0.0.0.0:$BITCOIN_ZMQ_PORT"
-
- cat >> "$compose_file" << EOF
- bitcoind:
- image: coinswap/${BITCOIN_IMAGE_NAME}:${bitcoin_tag}
- container_name: coinswap-bitcoind
- user: "0:0"
- command: $btc_cmd
- ports:
- - "$BITCOIN_RPC_PORT:$BITCOIN_RPC_PORT"
- - "$BITCOIN_ZMQ_PORT:$BITCOIN_ZMQ_PORT"
- volumes:
- - bitcoin-data:/home/bitcoin/.bitcoin
- restart: unless-stopped
- healthcheck:
- test: ["CMD", "bitcoin-cli", "-rpcuser=user", "-rpcpassword=password", "getblockchaininfo"]
- interval: 30s
- timeout: 10s
- retries: 5
-
-EOF
- fi
-
- if [[ "$USE_EXTERNAL_TOR" != "true" ]]; then
- cat >> "$compose_file" << EOF
- tor:
- image: osminogin/tor-simple
- container_name: coinswap-tor
- volumes:
- - tor-data:/var/lib/tor
- - ./torrc.generated:/etc/tor/torrc:ro
- ports:
- - "\${TOR_SOCKS_PORT:-$TOR_SOCKS_PORT}:\${TOR_SOCKS_PORT:-$TOR_SOCKS_PORT}"
- - "\${TOR_CONTROL_PORT:-$TOR_CONTROL_PORT}:\${TOR_CONTROL_PORT:-$TOR_CONTROL_PORT}"
- - "\${MAKER_RPC_PORT:-$MAKERD_RPC_PORT}:\${MAKER_RPC_PORT:-$MAKERD_RPC_PORT}"
- restart: unless-stopped
-
-EOF
- fi
-
- cat >> "$compose_file" << EOF
- makerd:
- image: coinswap/${IMAGE_NAME}:master
- container_name: coinswap-makerd
-EOF
-
- if [[ "$USE_EXTERNAL_TOR" != "true" ]]; then
- echo " network_mode: \"service:tor\"" >> "$compose_file"
- else
- cat >> "$compose_file" << EOF
- ports:
- - "$MAKERD_RPC_PORT:$MAKERD_RPC_PORT"
-EOF
- fi
-
- cat >> "$compose_file" << EOF
- command:
- - sh
- - -c
- - |
- sleep 15
- mkdir -p /home/coinswap/.coinswap/maker
-
- RAND_SUFFIX=\$\$(date +%s)
- WALLET_NAME="maker-wallet-\$\$RAND_SUFFIX"
-
- echo "Wallet Name: \$\$WALLET_NAME"
-
- printf '%s\n' \\
- "network_port = \${MAKER_NETWORK_PORT:-$MAKERD_PORT}" \\
- "rpc_port = \${MAKER_RPC_PORT:-$MAKERD_RPC_PORT}" \\
- "socks_port = \${TOR_SOCKS_PORT:-$TOR_SOCKS_PORT}" \\
- "control_port = \${TOR_CONTROL_PORT:-$TOR_CONTROL_PORT}" \\
- "tor_auth_password = \${TOR_AUTH_PASSWORD:-coinswap}" \\
- "min_swap_amount = \${MIN_SWAP_AMOUNT:-10000}" \\
- "fidelity_amount = \${FIDELITY_AMOUNT:-50000}" \\
- "fidelity_timelock = \${FIDELITY_TIMELOCK:-13104}" \\
- "connection_type = TOR" \\
- "base_fee = \${BASE_FEE:-100}" \\
- "amount_relative_fee_ppt = \${AMOUNT_RELATIVE_FEE_PPT:-1000}" \\
- > /home/coinswap/.coinswap/maker/config.toml
- $makerd_args_cmd -w "\$\$WALLET_NAME"
- volumes:
- - maker-data:/home/coinswap/.coinswap
- environment:
- - RUST_LOG=\${RUST_LOG:-info}
- - TOR_SOCKS_PORT=\${TOR_SOCKS_PORT:-${DEFAULT_TOR_SOCKS_PORT}}
- - TOR_CONTROL_PORT=\${TOR_CONTROL_PORT:-${DEFAULT_TOR_CONTROL_PORT}}
- - MAKER_NETWORK_PORT=\${MAKER_NETWORK_PORT:-${DEFAULT_MAKERD_PORT}}
- - MAKER_RPC_PORT=\${MAKER_RPC_PORT:-${DEFAULT_MAKERD_RPC_PORT}}
- - TOR_AUTH_PASSWORD=\${TOR_AUTH_PASSWORD:-coinswap}
- - MIN_SWAP_AMOUNT=\${MIN_SWAP_AMOUNT:-10000}
- - FIDELITY_AMOUNT=\${FIDELITY_AMOUNT:-50000}
- - FIDELITY_TIMELOCK=\${FIDELITY_TIMELOCK:-13104}
- - BASE_FEE=\${BASE_FEE:-100}
- - AMOUNT_RELATIVE_FEE_PPT=\${AMOUNT_RELATIVE_FEE_PPT:-1000}
- - BITCOIN_RPC_HOST=\${BITCOIN_RPC_HOST:-172.81.178.3:48332}
- - BITCOIN_RPC_AUTH=\${BITCOIN_RPC_AUTH:-user:password}
- restart: unless-stopped
-
-volumes:
-EOF
-
- if [[ "$USE_EXTERNAL_BITCOIND" != "true" ]]; then
- cat >> "$compose_file" << EOF
- bitcoin-data:
- driver: local
-EOF
- fi
-
- if [[ "$USE_EXTERNAL_TOR" != "true" ]]; then
- cat >> "$compose_file" << EOF
- tor-data:
- driver: local
-EOF
- fi
-
- cat >> "$compose_file" << EOF
- maker-data:
- driver: local
-
-networks:
- default:
- name: coinswap-network
-EOF
-
- print_success "Generated docker-compose configuration: $compose_file"
-}
-
# Build the Docker image
build_image() {
print_info "Building Coinswap Docker image..."
@@ -448,14 +544,14 @@ build_bitcoin_image() {
local s_arm64=$(grep "^SHA256_ARM64=" "$VERSION_FILE" | cut -d'=' -f2)
if docker build \
- --build-arg TAG="$tag" \
- --build-arg FILENAME_AMD64="$f_amd64" \
- --build-arg SHA256_AMD64="$s_amd64" \
- --build-arg FILENAME_ARM64="$f_arm64" \
- --build-arg SHA256_ARM64="$s_arm64" \
- -f docker/Dockerfile.bitcoin-mutinynet \
- -t "${BITCOIN_IMAGE_NAME}:${tag}" \
- -t "${BITCOIN_IMAGE_NAME}:latest" .; then
+ --build-arg TAG="$tag" \
+ --build-arg FILENAME_AMD64="$f_amd64" \
+ --build-arg SHA256_AMD64="$s_amd64" \
+ --build-arg FILENAME_ARM64="$f_arm64" \
+ --build-arg SHA256_ARM64="$s_arm64" \
+ -f docker/Dockerfile.bitcoin-mutinynet \
+ -t "${BITCOIN_IMAGE_NAME}:${tag}" \
+ -t "${BITCOIN_IMAGE_NAME}:latest" .; then
print_success "Bitcoin Mutinynet image built successfully"
else
print_error "Failed to build Bitcoin Mutinynet image"
@@ -480,7 +576,7 @@ publish_image() {
print_error "Username required to publish"
exit 1
fi
-
+
local repo="${username}/${IMAGE_NAME}"
# Ensure image is built
@@ -514,24 +610,23 @@ publish_bitcoin_image() {
print_error "Username required to publish"
exit 1
fi
-
+
# Extract repo name if it contains a slash (e.g. coinswap/bitcoin-mutinynet -> bitcoin-mutinynet)
local repo_name=$(echo "$BITCOIN_IMAGE_NAME" | awk -F/ '{print $NF}')
local target_repo="${username}/${repo_name}"
- # Ensure image is built
- build_bitcoin_image
+ local tag="latest"
+ if [ -f "$VERSION_FILE" ]; then
+ tag=$(grep "^TAG=" "$VERSION_FILE" | cut -d'=' -f2)
+ fi
- # Get tag from version file
- local tag=$(grep "^TAG=" "$VERSION_FILE" | cut -d'=' -f2)
+ build_bitcoin_image
print_info "Tagging and pushing image to $target_repo..."
- # Tag and push latest
docker tag "${BITCOIN_IMAGE_NAME}:latest" "${target_repo}:latest"
docker push "${target_repo}:latest"
- # Tag and push version
if [ -n "$tag" ]; then
docker tag "${BITCOIN_IMAGE_NAME}:${tag}" "${target_repo}:${tag}"
docker push "${target_repo}:${tag}"
@@ -544,19 +639,19 @@ publish_bitcoin_image() {
# Start the full stack using docker-compose
start_stack() {
local use_defaults="false"
-
+
while [[ $# -gt 0 ]]; do
case $1 in
-d|--default)
use_defaults="true"
shift
- ;;
+ ;;
*)
shift
- ;;
+ ;;
esac
done
-
+
# Load existing configuration or prompt for new one
load_config
@@ -569,67 +664,160 @@ start_stack() {
fi
fi
- # Set defaults for any unset variables
- BITCOIN_DATADIR="${BITCOIN_DATADIR:-$DEFAULT_BITCOIN_DATADIR}"
- BITCOIN_NETWORK="${BITCOIN_NETWORK:-$DEFAULT_BITCOIN_NETWORK}"
- BITCOIN_RPC_PORT="${BITCOIN_RPC_PORT:-$DEFAULT_BITCOIN_RPC_PORT}"
- BITCOIN_ZMQ_PORT="${BITCOIN_ZMQ_PORT:-$DEFAULT_BITCOIN_ZMQ_PORT}"
- MAKERD_PORT="${MAKERD_PORT:-$DEFAULT_MAKERD_PORT}"
- MAKERD_RPC_PORT="${MAKERD_RPC_PORT:-$DEFAULT_MAKERD_RPC_PORT}"
- USE_TAPROOT="${USE_TAPROOT:-true}"
- TOR_SOCKS_PORT="${TOR_SOCKS_PORT:-$DEFAULT_TOR_SOCKS_PORT}"
- TOR_CONTROL_PORT="${TOR_CONTROL_PORT:-$DEFAULT_TOR_CONTROL_PORT}"
- USE_EXTERNAL_BITCOIND="${USE_EXTERNAL_BITCOIND:-false}"
- USE_EXTERNAL_TOR="${USE_EXTERNAL_TOR:-false}"
-
- # Generate dynamic docker-compose file
- generate_compose_file
+ setup_env
print_info "Starting Coinswap stack with docker-compose..."
+ print_info "Active Profiles: $COMPOSE_PROFILES"
cd "$SCRIPT_DIR"
- if docker compose -f docker-compose.generated.yml up -d; then
- print_success "Coinswap stack started successfully"
+ if [[ "$USE_EXTERNAL_BITCOIND" != "true" ]]; then
+ print_info "Starting bitcoind and tor services..."
+
+ if [[ "$COMPOSE_PROFILES" == *"internal-tor"* ]]; then
+ docker compose up -d bitcoind tor
+ else
+ docker compose up -d bitcoind
+ fi
+
+ if [ $? -ne 0 ]; then
+ print_error "Failed to start Coinswap stack"
+ exit 1
+ fi
+
+ print_success "Bitcoin and Tor services started"
print_info "Services running:"
- docker compose -f docker-compose.generated.yml ps
+ docker compose ps
+ echo ""
+
+ wait_for_ibd_complete
+
+ start_makerd
else
- print_error "Failed to start Coinswap stack"
- exit 1
+ if docker compose up -d; then
+ start_makerd
+ else
+ print_error "Failed to start Coinswap stack"
+ exit 1
+ fi
fi
}
stop_stack() {
print_info "Stopping Coinswap stack..."
cd "$SCRIPT_DIR"
+ setup_env
- # Use generated compose file if it exists, otherwise fall back to default
- if [ -f "docker-compose.generated.yml" ]; then
- docker compose -f docker-compose.generated.yml down
- else
- docker compose down
- fi
+ docker compose down
print_success "Coinswap stack stopped"
}
show_logs() {
cd "$SCRIPT_DIR"
+ setup_env
- local compose_file="docker-compose.generated.yml"
- if [ ! -f "$compose_file" ]; then
- compose_file="docker-compose.yml"
+ if [ -n "$1" ]; then
+ docker compose logs -f "$1"
+ else
+ docker compose logs -f
fi
+}
+
+# Wait for Bitcoin IBD to complete
+wait_for_ibd_complete() {
+ print_info "Waiting for Bitcoin node to sync (Initial Block Download)..."
+ print_warning "This may take approximately 1 hour or more depending on your connection."
+ echo ""
+ print_info "Showing bitcoind logs (press Ctrl+C to stop watching, sync will continue in background):"
+ echo "============================================"
- if [ -n "$1" ]; then
- docker compose -f "$compose_file" logs -f "$1"
+ docker compose logs -f bitcoind &
+ local logs_pid=$!
+
+ cleanup_logs() {
+ print_info "Killing bitcoind logs process (PID: $logs_pid)..."
+ if [ -n "$logs_pid" ]; then
+ kill -KILL "$logs_pid" 2>/dev/null || true
+ kill -KILL -"$logs_pid" 2>/dev/null || true
+ wait "$logs_pid" 2>/dev/null || true
+ logs_pid=""
+ print_info "Bitcoind logs was killed."
+ fi
+ }
+
+ trap 'cleanup_logs; trap - EXIT INT TERM; exit 1' INT TERM
+ trap 'cleanup_logs' EXIT
+
+ while true; do
+ sleep 30
+
+ if ! docker compose ps 2>/dev/null | grep -q "bitcoind"; then
+ cleanup_logs
+ trap - EXIT INT TERM
+ print_error "bitcoind container stopped unexpectedly"
+ exit 1
+ fi
+
+ local ibd_status=$(docker compose exec -T bitcoind bitcoin-cli \
+ -rpcuser="${BITCOIN_RPC_USER}" \
+ -rpcpassword="${BITCOIN_RPC_PASSWORD}" \
+ -rpcport="${BITCOIN_RPC_PORT}" \
+ getblockchaininfo 2>/dev/null | grep -o '"initialblockdownload":[^,]*' | cut -d':' -f2 | tr -d ' ')
+
+ print_info "Initial Block Download status: '$ibd_status'"
+
+ if [ "$ibd_status" == "false" ]; then
+ print_success "Bitcoin Initial Block Download complete!"
+ cleanup_logs
+ trap - EXIT INT TERM
+ return 0
+ fi
+ done
+}
+
+# Start makerd service
+start_makerd() {
+ setup_env
+ print_info "Starting makerd service..."
+
+ if docker compose up -d; then
+ print_success "makerd started successfully!"
+ sleep 3
+
+ echo -e "${YELLOW}==============================================================${NC}"
+ echo -e "${YELLOW}CHECK LOGS below for the FIDELITY FUNDING ADDRESS! !${NC}"
+ echo -e "${YELLOW}--------------------------------------------------------------${NC}"
+ echo -e "${YELLOW}Fund the displayed wallet address with at least the mentioned amount of BTC."
+ echo -e "If you fund extra, that will be used for swap liquidity."
+ echo -e "Ensure you have enough Swap Liquidity to participate in the market."
+ echo -e ""
+ echo -e "If the maker server starts successfully, you will see a log like below:"
+ echo -e " [6102] Taproot maker setup completed"
+ echo -e " [6102] Taproot swap liquidity: 49540 sats, 0 ongoing swaps"
+ echo -e " [6102] RPC socket binding successful at 127.0.0.1:6103"
+ echo -e ""
+ echo -e "Press Ctrl+C to stop watching logs (this will keep the maker server running in the background)."
+ echo -e "To restart makerd later, run: ./docker-setup.sh restart"
+ echo -e "To view logs later, run: ./docker-setup.sh logs [service] or docker compose logs -f [service]"
+ echo -e "To show all logs, run: ./docker-setup.sh logs"
+ echo -e "To stop the stack, run: ./docker-setup.sh stop"
+ echo -e "Show all available commands: ./docker-setup.sh help"
+ echo -e "${YELLOW}==============================================================${NC}"
+ echo ""
+
+ docker compose logs -f makerd-internal makerd 2>/dev/null
else
- docker compose -f "$compose_file" logs -f
+ print_error "Failed to start makerd service"
+ print_info "Closing all services..."
+ stop_stack
+ exit 1
fi
}
run_command() {
local cmd="$1"
shift
+ setup_env
docker run --rm -it --network coinswap-network "${IMAGE_NAME}:latest" "$cmd" "$@"
}
@@ -673,59 +861,58 @@ show_help() {
case "${1:-}" in
"configure")
configure_setup
- ;;
+ ;;
"build")
check_docker
build_image
- ;;
+ ;;
"build-bitcoin")
check_docker
build_bitcoin_image
- ;;
+ ;;
"publish")
check_docker
publish_image "$2"
- ;;
+ ;;
"publish-bitcoin")
check_docker
publish_bitcoin_image
- ;;
+ ;;
"start")
check_docker
start_stack "${@:2}"
- ;;
+ ;;
"stop")
stop_stack
- ;;
+ ;;
"restart")
stop_stack
sleep 2
start_stack
- ;;
+ ;;
"logs")
show_logs "$2"
- ;;
+ ;;
"status")
cd "$SCRIPT_DIR"
- compose_file="docker-compose.generated.yml"
- if [ ! -f "$compose_file" ]; then
- compose_file="docker-compose.yml"
- fi
- docker compose -f "$compose_file" ps
- ;;
+ setup_env
+ docker compose ps
+ ;;
"shell")
+ setup_env
docker run --rm -it --network coinswap-network "coinswap/${IMAGE_NAME}:latest" /bin/sh
- ;;
+ ;;
"makerd"|"maker-cli"|"taker"|"bitcoin-cli")
run_command "$@"
- ;;
+ ;;
"help"|"--help"|"-h"|"")
show_help
- ;;
+ ;;
*)
print_error "Unknown command: $1"
echo ""
show_help
exit 1
- ;;
+ ;;
esac
+
diff --git a/docs/docker.md b/docs/docker.md
index c594d4c97..f84ab9992 100644
--- a/docs/docker.md
+++ b/docs/docker.md
@@ -14,8 +14,9 @@ The Docker setup provides a complete environment for running any Coinswap applic
- **Alpine Linux 3.20** base image for minimal size
- **Rust 1.90.0** for building the applications
- **Custom Bitcoin Mutinynet image** for Signet testing
-- **External Tor image** (`leplusorg/tor`)
+- **External Tor image** (`osminogin/tor-simple`)
- **Interactive configuration** with automatic service detection
+- **Docker Compose Profiles** for flexible deployment
- **Coinswap binaries:** `makerd`, `maker-cli`, `taker`
## Architecture
@@ -24,7 +25,7 @@ This is an overview for the docker stack with default settings for all nodes:
```mermaid
graph TD
- bitcoind["Bitcoind
Bitcoin Node
RPC Port (Default: 18332)
ZMQ Port (Default: 28332)"]
+ bitcoind["Bitcoind
Bitcoin Node
RPC Port (Default: 38332)
ZMQ Port (Default: 28332)"]
tor["Tor
Tor Proxy
SOCKS Port (Default: 9050)
Control Port (Default: 9051)"]
makerd["Makerd
Network Port (Default: 6102)
RPC Port (Default: 6103)"]
@@ -59,7 +60,8 @@ The Docker setup uses:
- `docker/Dockerfile` - Unified image containing `makerd`, `maker-cli`, and `taker`
- `docker/Dockerfile.bitcoin-mutinynet` - Custom Bitcoin Core image for Mutinynet
-- External images: `leplusorg/tor` for Tor
+- `docker-compose.yml` - Single parameterized compose file
+- External images: `osminogin/tor-simple` for Tor
## Quick Start
@@ -191,14 +193,14 @@ docker run --rm -it \
## Docker Compose Setup
-The setup script automatically generates `docker-compose.generated.yml` based on your configuration. For a complete setup with all services:
+The setup script uses a standard `docker-compose.yml` with environment variables and profiles. For a complete setup with all services:
```bash
# Start all services (Bitcoin Core, Tor, Makerd)
./docker-setup start
-# Or use docker-compose directly
-docker compose -f docker-compose.generated.yml up -d
+# Note: Running docker compose directly requires setting environment variables.
+# It is recommended to use the setup script which handles this for you.
# Check status
./docker-setup status
@@ -223,8 +225,8 @@ All application data is stored in Docker volumes:
# using setup script
./docker-setup logs makerd
-# or directly with docker-compose
-docker compose -f docker-compose.generated.yml logs -f makerd
+# or directly with docker-compose (requires env vars)
+docker compose logs -f makerd
```
### Interactive debugging