Skip to content

Run an Electrum server

An Electrum server is a thin index over a full node that lets Electrum (and ElectrumG) wallets sync instantly without downloading the blockchain. It's the right layer to operate if you want users to be able to use Bitcoin Gold (BTG) on phones and lightweight wallets without trusting a third-party server.

This page covers standing up ElectrumX for Bitcoin Gold (BTG). ElectrumX is the most widely deployed Electrum server family on Bitcoin-fork networks and is what electrumx-eu.btgofficial.org:50002 / electrumx-us.btgofficial.org:50002 run.

Who this is for

You already have a synced full node and you want to expose a public Electrum endpoint, or a private one for your own wallet(s).

What you'll build

  • A cloned ElectrumX repository with the BTCGPU-specific patches applied.
  • A systemd unit running ElectrumX as a dedicated electrumx user.
  • A self-signed or Let's Encrypt TLS certificate on TCP/50002.
  • TCP/50001 (plaintext) and TCP/50003 (WebSocket) optionally exposed.
  • Verification with electrumx_rpc.py and the official ElectrumG client.

Requirements

Resource Minimum Recommended (public server)
OS Ubuntu 22.04 LTS Ubuntu 22.04 / 24.04 LTS
CPU 2 cores 4+ cores
RAM 4 GB 8 GB
Disk 50 GB (leveldb) + chain 100 GB SSD
Backend A synced bgoldd (v0.17.3) Same host as your node, or LAN-local
Ports 50001 (tcp), 50002 (ssl) 50001, 50002, 50003 (ws) inbound

Backend compatibility

ElectrumX expects a Bitcoin Core-compatible RPC. The BTCGPU fork of bgoldd (v0.17.3) is fully compatible at the RPC level — the relevant calls (getblock, getblockhash, getblockheader, getrawtransaction, getmempool, decoderawtransaction) are unchanged.

1. Install dependencies

ElectrumX is Python 3.

sudo apt update
sudo apt install -y python3 python3-pip python3-venv libssl-dev

2. Create a dedicated user

sudo useradd --system --home /var/lib/electrumx --shell /usr/sbin/nologin electrumx
sudo mkdir -p /var/lib/electrumx /var/log/electrumx
sudo chown -R electrumx:electrumx /var/lib/electrumx /var/log/electrumx

3. Set up Python venv

sudo -u electrumx -H bash -c '
  cd /var/lib/electrumx
  python3 -m venv venv
  source venv/bin/activate
  pip install --upgrade pip
  pip install aiohttp pylru
  git clone https://github.com/Electrum-Coin/ElectrumX-Bitcoin Gold (BTG).git
  cd ElectrumX-Bitcoin Gold (BTG)
  pip install -e .
'

The ElectrumX-Bitcoin Gold (BTG) repository is a community-maintained fork of ElectrumX with the Bitcoin Gold (BTG)-specific constants pre-configured (genesis hash, address prefix, default ports, coincurve-based address verification). Pin the commit in your deployment notes.

4. Generate a self-signed TLS cert (or use Let's Encrypt)

For private use, a self-signed cert is fine.

sudo openssl req -x509 -nodes -newkey ec -pkeyopt ec_paramgen_curve:secp256k1 \
  -keyout /var/lib/electrumx/electrumx.key \
  -out /var/lib/electrumx/electrumx.crt \
  -days 3650 \
  -subj "/CN=electrum.example.com" \
  -addext "subjectAltName=DNS:electrum.example.com"
sudo chown electrumx:electrumx /var/lib/electrumx/electrumx.{key,crt}
sudo chmod 600 /var/lib/electrumx/electrumx.key

For public use, get a real cert from Let's Encrypt. Certbot needs a port-80 open challenge or DNS-01 challenge.

DNS-01 challenge is cleaner for a server with only 50001/50002 open

sudo certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini \
  -d electrum.example.com

5. Configure ElectrumX

sudo tee /etc/electrumx.conf > /dev/null <<'EOF'
# /etc/electrumx.conf
# ----------------------------------------
# Network identity
COIN = BitcoinGold
NET = mainnet

# Backend RPC (your local bgoldd)
DAEMON_URL = http://explorer:SWbeR6SkQ4cP3BVPNetr@127.0.0.1:8332/
#  ^ replace explorer / SWbeR6SkQ4cP3BVPNetr with your real rpcuser / rpcpassword

# DB
DB_DIRECTORY = /var/lib/electrumx/db
DB_ENGINE = leveldb

# Services
SERVICES = tcp://0.0.0.0:50001,ssl://0.0.0.0:50002,wss://0.0.0.0:50003

# TLS
SSL_CERTFILE = /var/lib/electrumx/electrumx.crt
SSL_KEYFILE = /var/lib/electrumx/electrumx.key

# Cost
PEER_ANNOUNCE = self
REPORT_SERVICES = tcp://50001,ssl://50002
EOF

sudo chmod 600 /etc/electrumx.conf
sudo chown electrumx:electrumx /etc/electrumx.conf

Lock down the RPC password

The DAEMON_URL contains the bgoldd RPC password. Anyone who can read /etc/electrumx.conf can drain the wallet if disablewallet=0. Set chmod 600 and run the service as the dedicated user.

6. systemd unit

sudo tee /etc/systemd/system/electrumx.service > /dev/null <<'EOF'
[Unit]
Description=ElectrumX server (Bitcoin Gold)
After=network-online.target btgd.service
Wants=network-online.target btgd.service

[Service]
User=electrumx
Group=electrumx
EnvironmentFile=/etc/electrumx.conf
ExecStart=/var/lib/electrumx/venv/bin/electrumx_server
Restart=on-failure
RestartSec=10

# Hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
ReadWritePaths=/var/lib/electrumx /var/log/electrumx
LimitNOFILE=65536

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable --now electrumx.service
sudo journalctl -u electrumx.service -f

7. Firewall

Open the three ports you advertised in SERVICES.

sudo ufw allow 50001/tcp comment "ElectrumX TCP"
sudo ufw allow 50002/tcp comment "ElectrumX SSL"
sudo ufw allow 50003/tcp comment "ElectrumX WebSocket"

8. Verification

Local

# Is the process up?
systemctl status electrumx.service

# Are the ports listening?
ss -lntp | grep -E '50001|50002|50003'

# Banner (always returns the same JSON on first connect)
echo '{"id":1,"method":"server.version","params":["electrum-test","1.4"]}' | \
  timeout 5 nc -q1 127.0.0.1 50001

With ElectrumG

In ElectrumG, Tools → Network → Server, add a new server:

  • Name: my-electrum
  • Host: electrum.example.com
  • Port: 50002 (SSL) or 50001 (TCP)
  • Protocol: SSL or TCP

Then right-click the server in the network dialog → "Check connection". A green light + version banner confirms the server is reachable and the TLS chain is valid.

With curl over SSL

curl --cacert /var/lib/electrumx/electrumx.crt --resolve electrum.example.com:50002:127.0.0.1 \
  -s https://electrum.example.com:50002 \
  -H 'Content-Type: application/json' \
  -d '{"id":1,"method":"server.ping","params":[]}'

The ElectrumX 1.16.0 JSON-RPC over TCP/SSL is the same protocol regardless of coin.

9. Operating

Initial sync

ElectrumX's first run builds the leveldb index. On 165 GB of blocks, expect 12–24 hours of catch-up.

watch -n 60 'ls -la /var/lib/electrumx/db && du -sh /var/lib/electrumx/db'

The db/ size grows monotonically until the node catches up to the tip.

Monitoring

Add a healthcheck (e.g. on a 60-second cron) that hits server.ping over TCP. If it fails three times in a row, restart:

#!/bin/bash
# /usr/local/bin/electrumx-healthcheck
if ! timeout 5 bash -c 'echo > /dev/tcp/127.0.0.1/50001' ; then
    systemctl restart electrumx.service
fi

Logrotate

/var/log/electrumx/*.log is verbose. Cap it.

sudo tee /etc/logrotate.d/electrumx > /dev/null <<'EOF'
/var/log/electrumx/*.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
    copytruncate
}
EOF

Troubleshooting

"Cannot connect to daemon" at startup

The DAEMON_URL is wrong, the bgoldd isn't running, or its bitcoingold.conf doesn't permit the connection. Test with curl:

curl -u explorer:SWbeR6SkQ4cP3BVPNetr http://127.0.0.1:8332 \
  -H 'Content-Type: application/json' \
  -d '{"id":1,"method":"getblockchaininfo","params":[]}' | jq .

"Address version byte mismatch"

The NET = mainnet and COIN = BitcoinGold constants are wrong. Confirm the address prefix in /var/lib/electrumx/venv/lib/python3.10/site-packages/electrumx_btg/lib/coins.py (or wherever the fork defines them) matches Bitcoin Gold (BTG)'s G (P2PKH) / A (P2SH).

"DB_LOCK: Another instance is using the DB"

Two ElectrumX instances pointing at the same DB_DIRECTORY. Check ps -ef | grep electrumx_server.

"Mempool is full" / "Too many mempool txs"

bgoldd's mempool is filling up. ElectrumX asks for the full mempool on every poll. Either:

  • Increase maxmempool in bitcoingold.conf (default 300 MB).
  • Set MAX_SEND=1000000 in electrumx.conf to limit what ElectrumX forwards.

"SSL handshake error" from clients

Self-signed cert needs to be added to the client's trust store, OR replace with a Let's Encrypt cert. Don't ship a self-signed cert on a public server.

What to do next

  • Expose a public banner so the official ElectrumG client can auto-discover you. See the BTCGPU ElectrumG docs.
  • Stand up a second instance in a different region (e.g. electrum-eu.example.com and electrum-us.example.com) so wallets can pick the closer one.
  • Combine with Blockbook for a full explorer + Electrum stack.
  • Harden the host following Hardening.