diff --git a/.gitignore b/.gitignore index c6696df..d534014 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ /deploy/certbot/www /monero-wallet-rpc/wallet +/electrum-daemon/wallet /backend/node_modules /backend/dist diff --git a/deploy/DEPLOYMENT_GUIDE.md b/deploy/DEPLOYMENT_GUIDE.md index 798af3a..d929aa7 100644 --- a/deploy/DEPLOYMENT_GUIDE.md +++ b/deploy/DEPLOYMENT_GUIDE.md @@ -54,6 +54,10 @@ Edit `.env.prod`. Mandatory configuration: | `MONERO_WALLET_RPC_USERNAME` | strong random username | | `MONERO_WALLET_RPC_PASSWORD` | strong random password | | `MONERO_WALLET_PASSWORD` | strong wallet password | +| `ELECTRUM_NETWORK` | `mainnet` | +| `ELECTRUM_SERVER` | Electrum peer as `host:port:s` (SSL) or `host:port:t` (TCP), e.g. `electrum.blockstream.info:50002:s` | +| `ELECTRUM_WALLET_PASSWORD` | strong wallet password | +| `ELECTRUM_DAEMON_RPC_PASSWORD` | strong random password | | `VITE_API_BASE_URL` | `/api` | | `VITE_SHOP_FIAT_CURRENCY` | same as `SHOP_FIAT_CURRENCY` | diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index c3e6689..886da56 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -53,6 +53,28 @@ services: retries: 10 start_period: 300s + electrum-daemon: + build: + context: ./electrum-daemon + args: + ELECTRUM_VERSION: ${ELECTRUM_VERSION} + container_name: ${COMPOSE_PROJECT_NAME}_electrum_daemon + restart: unless-stopped + env_file: + - .env.dev + volumes: + - ${ELECTRUM_WALLET_DIR}:/electrum/wallet + healthcheck: + test: + [ + 'CMD-SHELL', + 'curl -sf -u "$$ELECTRUM_DAEMON_RPC_USER:$$ELECTRUM_DAEMON_RPC_PASSWORD" -H ''Content-Type: application/json'' -d ''{"jsonrpc":"2.0","id":"health","method":"version","params":[]}'' http://127.0.0.1:$$ELECTRUM_DAEMON_PORT/' + ] + interval: 10s + timeout: 5s + retries: 5 + start_period: 90s + simplex-cli: build: context: ./simplex-cli @@ -83,6 +105,8 @@ services: condition: service_healthy monero-wallet-rpc: condition: service_healthy + electrum-daemon: + condition: service_healthy simplex-cli: condition: service_healthy env_file: diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index bdd8a2c..c549a5a 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -50,6 +50,28 @@ services: retries: 10 start_period: 300s + electrum-daemon: + build: + context: ./electrum-daemon + args: + ELECTRUM_VERSION: ${ELECTRUM_VERSION} + container_name: ${COMPOSE_PROJECT_NAME}_electrum_daemon + restart: unless-stopped + env_file: + - .env.prod + volumes: + - ${ELECTRUM_WALLET_DIR}:/electrum/wallet + healthcheck: + test: + [ + 'CMD-SHELL', + 'curl -sf -u "$$ELECTRUM_DAEMON_RPC_USER:$$ELECTRUM_DAEMON_RPC_PASSWORD" -H ''Content-Type: application/json'' -d ''{"jsonrpc":"2.0","id":"health","method":"version","params":[]}'' http://127.0.0.1:$$ELECTRUM_DAEMON_PORT/' + ] + interval: 10s + timeout: 5s + retries: 5 + start_period: 90s + simplex-cli: build: context: ./simplex-cli @@ -80,6 +102,8 @@ services: condition: service_healthy monero-wallet-rpc: condition: service_healthy + electrum-daemon: + condition: service_healthy simplex-cli: condition: service_healthy env_file: diff --git a/electrum-daemon/Dockerfile b/electrum-daemon/Dockerfile new file mode 100644 index 0000000..93dd302 --- /dev/null +++ b/electrum-daemon/Dockerfile @@ -0,0 +1,16 @@ +FROM debian:bookworm-slim + +ARG ELECTRUM_VERSION + +RUN apt-get update \ + && apt-get install -y --no-install-recommends \ + ca-certificates curl libsecp256k1-1 python3 python3-cryptography \ + && curl -fsSL "https://download.electrum.org/${ELECTRUM_VERSION}/Electrum-${ELECTRUM_VERSION}.tar.gz" \ + | tar -xz -C /opt \ + && chmod +x "/opt/Electrum-${ELECTRUM_VERSION}/run_electrum" \ + && ln -s "/opt/Electrum-${ELECTRUM_VERSION}/run_electrum" /usr/local/bin/electrum \ + && rm -rf /var/lib/apt/lists/* + +COPY --chmod=755 docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh + +ENTRYPOINT ["docker-entrypoint.sh"] diff --git a/electrum-daemon/docker-entrypoint.sh b/electrum-daemon/docker-entrypoint.sh new file mode 100755 index 0000000..f96ec27 --- /dev/null +++ b/electrum-daemon/docker-entrypoint.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +set -euo pipefail + +NETWORK_FLAG="--${ELECTRUM_NETWORK}" +WALLET_PATH="/electrum/wallet/${ELECTRUM_WALLET_NAME}" +DATA_DIR="/electrum/data" + +run_electrum() { electrum "${NETWORK_FLAG}" --dir "${DATA_DIR}" "$@"; } +run_electrum_offline() { electrum --offline "${NETWORK_FLAG}" --dir "${DATA_DIR}" "$@"; } + +mkdir -p /electrum/wallet "${DATA_DIR}" +chmod 700 /electrum/wallet + +if [[ ! -f "${WALLET_PATH}" ]]; then + echo "Creating ${ELECTRUM_NETWORK} wallet at ${WALLET_PATH}..." + + run_electrum_offline create -w "${WALLET_PATH}" --password "${ELECTRUM_WALLET_PASSWORD}" + chmod 600 "${WALLET_PATH}" 2>/dev/null || true + + echo "Wallet created at ${WALLET_PATH}" +fi + +run_electrum_offline setconfig rpcuser "${ELECTRUM_DAEMON_RPC_USER}" +run_electrum_offline setconfig rpcpassword "${ELECTRUM_DAEMON_RPC_PASSWORD}" +run_electrum_offline setconfig rpchost 0.0.0.0 +run_electrum_offline setconfig rpcport "${ELECTRUM_DAEMON_PORT}" +run_electrum_offline setconfig server "${ELECTRUM_SERVER}" + +trap 'run_electrum daemon stop || true; exit 0' SIGTERM SIGINT + +run_electrum daemon -d +run_electrum load_wallet -w "${WALLET_PATH}" --password "${ELECTRUM_WALLET_PASSWORD}" + +sleep infinity