468111a52a
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
300 lines
7.0 KiB
Markdown
300 lines
7.0 KiB
Markdown
# Online Wallet Bot
|
|
|
|
A self-hosted Telegram bot for managing Bitcoin wallets using Electrum. Designed for watch-only (xpub) wallets with air-gapped signing support.
|
|
|
|
## Features
|
|
|
|
- Per-user isolated wallets
|
|
- Watch-only wallet restore from xpub
|
|
- Balance display (Confirmed / Unconfirmed)
|
|
- Receive address generation
|
|
- Unsigned transaction (PSBT) creation with fee options
|
|
- Unit switching: BTC / mBTC / sats
|
|
- Persian (Farsi) and English language support
|
|
- Persistent bottom keyboard
|
|
- Optional Tor support (connect via .onion to a public server or your own node)
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
- A Linux server with Docker and Docker Compose installed
|
|
- A Telegram bot token (from [@BotFather](https://t.me/BotFather))
|
|
- Your Telegram user ID (from [@userinfobot](https://t.me/userinfobot))
|
|
|
|
---
|
|
|
|
## Server Setup (Step by Step)
|
|
|
|
### 1. Clone the repository
|
|
|
|
```bash
|
|
git clone https://git.goyban.com/goyban/telegtrum_bot.git
|
|
cd telegtrum_bot
|
|
```
|
|
|
|
### 2. Create your `.env` file
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
nano .env
|
|
```
|
|
|
|
Fill in:
|
|
|
|
```
|
|
ELECTRUM_VERSION=4.7.2
|
|
TELEGRAM_BOT_TOKEN=your_bot_token_here
|
|
```
|
|
|
|
### 3. Add your Telegram user ID to the allowed users list
|
|
|
|
```bash
|
|
cp allowed_users.txt.example allowed_users.txt
|
|
nano allowed_users.txt
|
|
```
|
|
|
|
Add a line in the format `userid, Name`:
|
|
|
|
```
|
|
123456789, Alice
|
|
```
|
|
|
|
You can find your user ID by messaging [@userinfobot](https://t.me/userinfobot) on Telegram.
|
|
|
|
### 4. Build and start the container
|
|
|
|
```bash
|
|
docker compose up -d --build
|
|
```
|
|
|
|
This will:
|
|
- Build the Docker image with Electrum installed
|
|
- Start the Electrum daemon
|
|
- Launch the Telegram bot
|
|
|
|
### 5. Check logs
|
|
|
|
```bash
|
|
docker compose logs -f
|
|
```
|
|
|
|
You should see `Electrum daemon started. Launching bot...` followed by the bot starting up.
|
|
|
|
---
|
|
|
|
## Local / Umbrel Mode
|
|
|
|
Use this mode to connect to your own Electrum server running on Umbrel (or any local node) on your home network.
|
|
|
|
> **Note:** `umbrel.local` does not resolve inside Docker containers — mDNS is host-only. Use the actual **IP address** of your Umbrel device (e.g. `192.168.1.100`).
|
|
|
|
### Setup
|
|
|
|
```bash
|
|
cp .env.example .env
|
|
nano .env
|
|
```
|
|
|
|
Fill in `TELEGRAM_BOT_TOKEN` and set your Umbrel's IP:
|
|
|
|
```
|
|
UMBREL_IP=192.168.1.100
|
|
```
|
|
|
|
```bash
|
|
cp allowed_users.txt.example allowed_users.txt
|
|
nano allowed_users.txt
|
|
```
|
|
|
|
### Start
|
|
|
|
```bash
|
|
docker compose -f docker-compose.local.yml up -d --build
|
|
```
|
|
|
|
### How it works
|
|
|
|
On first start, the entrypoint writes `./electrum-data/config` with:
|
|
|
|
```json
|
|
{
|
|
"auto_connect": false,
|
|
"enable_proxy": false,
|
|
"oneserver": true,
|
|
"server": "192.168.1.100:50001:t"
|
|
}
|
|
```
|
|
|
|
If the config file already exists it is left untouched, so manual edits survive restarts.
|
|
|
|
> **If the connection doesn't work:** check `./electrum-data/config` after the first run and make sure the server string still ends in `:t` (TCP). Electrum may rewrite it to `:s` (SSL) on first connect. If it did, stop the container, change it back to `:t`, and restart.
|
|
|
|
### Check logs
|
|
|
|
```bash
|
|
docker compose -f docker-compose.local.yml logs -f
|
|
```
|
|
|
|
---
|
|
|
|
## Tor Mode
|
|
|
|
Tor mode runs Electrum through the Tor network. It uses a separate Docker Compose file and Dockerfile so the standard setup is not affected.
|
|
|
|
### Setup
|
|
|
|
```bash
|
|
cp .env.tor.example .env
|
|
nano .env
|
|
```
|
|
|
|
Fill in `TELEGRAM_BOT_TOKEN` and choose a connection mode:
|
|
|
|
**Option A — your own Electrum server over Tor:**
|
|
|
|
```
|
|
ELECTRUM_SERVER=yournode123.onion:50001:t
|
|
```
|
|
|
|
**Option B — public .onion server (default, no extra config needed):**
|
|
|
|
Leave `ELECTRUM_SERVER` unset. The bot will connect to `electrums3lojbuj.onion:50001:t` by default. Override with `ELECTRUM_ONION_SERVER` if needed.
|
|
|
|
### Start
|
|
|
|
```bash
|
|
docker compose -f docker-compose.tor.yml up -d --build
|
|
```
|
|
|
|
### Notes
|
|
|
|
- Tor runs inside the same container — no sidecar needed.
|
|
- The container waits for the Tor SOCKS proxy to be ready before starting Electrum.
|
|
- Wallet data is stored in a separate volume (`electrum-tor-data`) so it does not mix with the standard setup.
|
|
- `t` in the server string means TCP — encryption is handled by the Tor layer, not SSL.
|
|
|
|
---
|
|
|
|
## Updating the Bot
|
|
|
|
The `bot.py` file is mounted as a volume, so you can update it without rebuilding the image:
|
|
|
|
```bash
|
|
# Edit bot.py, then:
|
|
docker compose restart
|
|
# or for Tor mode:
|
|
docker compose -f docker-compose.tor.yml restart
|
|
```
|
|
|
|
To update Electrum itself or system packages:
|
|
|
|
```bash
|
|
docker compose up -d --build
|
|
# or for Tor mode:
|
|
docker compose -f docker-compose.tor.yml up -d --build
|
|
```
|
|
|
|
---
|
|
|
|
## Adding or Removing Allowed Users
|
|
|
|
Edit `allowed_users.txt` and restart:
|
|
|
|
```bash
|
|
nano allowed_users.txt
|
|
docker compose restart
|
|
```
|
|
|
|
---
|
|
|
|
## Data Persistence
|
|
|
|
Wallet data is stored in a named Docker volume at `/root/.electrum` inside the container. This persists across restarts and rebuilds.
|
|
|
|
| Mode | Volume name |
|
|
|---|---|
|
|
| Standard | `electrum-data` |
|
|
| Tor | `electrum-tor-data` |
|
|
|
|
To back up wallet data (standard mode):
|
|
|
|
```bash
|
|
docker run --rm -v electrum-data:/data -v $(pwd):/backup debian:bookworm-slim \
|
|
tar czf /backup/electrum-backup.tar.gz -C /data .
|
|
```
|
|
|
|
---
|
|
|
|
## Bot Usage Guide
|
|
|
|
### Starting the bot
|
|
|
|
Open the bot in Telegram and send any message. You'll see a persistent keyboard at the bottom with all available actions.
|
|
|
|
### Add Wallet
|
|
|
|
Import a watch-only wallet from an xpub (extended public key):
|
|
|
|
1. Press **Add Wallet**
|
|
2. Enter a wallet name
|
|
3. Paste your xpub
|
|
4. Set a password (min 8 chars, must include upper, lower, and digit)
|
|
|
|
### List
|
|
|
|
Shows all your wallets.
|
|
|
|
### Load
|
|
|
|
Load a wallet to make it active:
|
|
|
|
1. Press **Load**
|
|
2. Select a wallet (auto-selects if you only have one)
|
|
3. Enter the wallet password
|
|
|
|
### Balance
|
|
|
|
Shows the confirmed and unconfirmed balance of the loaded wallet.
|
|
|
|
Use the inline buttons below the balance to switch between **BTC**, **mBTC**, and **sats**.
|
|
|
|
### Receive
|
|
|
|
Shows a fresh receiving address for the loaded wallet.
|
|
|
|
### Send
|
|
|
|
Creates an unsigned transaction (PSBT) for air-gapped signing:
|
|
|
|
1. Press **Send**
|
|
2. Choose a fee source: **Electrum** (recommended) or **mempool.space** (live)
|
|
3. Enter fee rate in sat/vB
|
|
4. Enter the wallet password
|
|
5. Enter the recipient address
|
|
6. Enter the amount (in your selected unit)
|
|
7. Receive the unsigned TX as both a code block and a `.txt` file for offline signing
|
|
8. Sign it with your offline wallet, then use **Broadcast**
|
|
|
|
### Close
|
|
|
|
Unloads the active wallet from the Electrum daemon.
|
|
|
|
### Language
|
|
|
|
Press **🌐 Language** to switch between English and Persian (Farsi).
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
**Bot not responding:** Check logs with `docker compose logs -f`. Make sure your bot token is correct and the container is running.
|
|
|
|
**"You are not authorized":** Your Telegram user ID is not in `allowed_users.txt`. Add it and restart.
|
|
|
|
**Wallet not loaded error:** Use **Load** before checking balance, receiving, or sending.
|
|
|
|
**Daemon not starting:** The container removes the lockfile on startup automatically. If issues persist, try `docker compose restart`.
|
|
|
|
**Tor mode — Electrum not connecting:** Tor bootstrap can take up to ~30 seconds on first run. Check logs with `docker compose -f docker-compose.tor.yml logs -f`.
|