Skip to content

helhindi/openclaw-gpu

Repository files navigation

OpenClaw GPU β€” Bittensor Mining on RunPod

GPU-accelerated Bittensor mining on RunPod Docker containers. Optional Shariah-compliant subnet screening (enabled by default). Standalone β€” no VPS dependency.

Architecture

graph TB
    subgraph RunPod["RunPod Pod (GPU Docker Container)"]
        direction TB
        START["start.sh<br/>Entrypoint"]
        MGR["bt_subnet_manager.py<br/>Interactive Dashboard"]
        ANA["subnet_analyzer.py<br/>Profitability + Shariah"]
        MON["miner_monitor.py<br/>Performance Snapshots"]
        PM2["pm2<br/>Process Manager"]
        MINERS["Bittensor Miners<br/>miner-sn4, miner-sn18..."]
    end

    subgraph Storage["/workspace/ (Network Volume)"]
        CONF["mining.conf"]
        WAL["wallets/<br/>coldkey + hotkeys"]
        DATA["data/<br/>snapshots + reports"]
        LOGS["logs/"]
        CODE["miners/<br/>sn4/, sn18/..."]
    end

    subgraph Chain["Bittensor Network (finney)"]
        SUB["Subtensor<br/>Chain Data"]
        VAL["Validators"]
    end

    START -->|boot| PM2
    START -->|creates| WAL
    MGR -->|fetches live data| ANA
    MGR -->|collects snapshots| MON
    MGR -->|deploys/stops| PM2
    ANA -->|queries| SUB
    MON -->|queries| SUB
    PM2 -->|manages| MINERS
    MINERS <-->|axon ports| VAL
    MGR -->|reads/writes| DATA
    MON -->|reads/writes| DATA
    MGR -->|reads| CONF
    MGR -->|creates keys| WAL
Loading

User Journey

flowchart LR
    A["Deploy Pod"] --> B["SSH In"]
    B --> C["Launch Dashboard"]
    C --> D{"Choose Action"}
    D -->|P| E["Prepare Hotkeys<br/>(free)"]
    D -->|D or type number| F["Deploy Subnet<br/>(burns TAO)"]
    D -->|W| G["Start 24/7 Watch"]
    D -->|O| H["Optimize<br/>(replace worst)"]
    E --> C
    F --> C
    G --> I["Background Monitoring<br/>every 30 min"]
    H --> C
    I -.->|alerts| C
Loading

Quick Start

1. Build and push the Docker image

docker build --platform linux/amd64 -t bt-miner-gpu:latest .
docker tag bt-miner-gpu:latest ghcr.io/helhindi/bt-miner-gpu:latest
docker push ghcr.io/helhindi/bt-miner-gpu:latest

2. Create RunPod template

Setting Value
Docker Image ghcr.io/helhindi/bt-miner-gpu:latest
Container Disk 40 GB
Volume Mount /workspace
HTTP Ports 8888
TCP Ports 22 70000 70001 70002 70003 70004

TCP ports >=70000 are RunPod's "symmetrical" ports β€” identity-mapped so Bittensor validators can reach your miner's axon externally. These high ports are configured in the RunPod template (not via Docker EXPOSE, which only supports ports ≀65535).

3. Deploy a pod (On-Demand, NOT Spot)

Attach a Network Volume (10 GB+). The analyzer auto-selects the cheapest GPU meeting each subnet's VRAM requirement:

GPU VRAM $/hr $/day $/month Subnets
RTX 3090 24 GB $0.22 $5.28 $158 SN1, SN4, SN6, SN18, SN24, SN25, SN27, SN33, SN47
RTX 4090 24 GB $0.34 $8.16 $245 (alt for 24GB subnets)
A40 48 GB $0.39 $9.36 $281 SN12, SN17, SN28
A100 80GB 80 GB $1.19 $28.56 $857 SN3, SN9, SN37
H100 80GB 80 GB $2.49 $59.76 $1,793 SN56

Storage: Network Volume at $0.07/GB/month (included in cost analysis).

4. SSH in and use the interactive manager

ssh root@ssh.runpod.io -i ~/.ssh/id_ed25519

# Launch the interactive dashboard (recommended)
python3 /opt/openclaw/bt_subnet_manager.py

# The dashboard shows:
#   - Top 5 GPU + CPU subnets with live profitability data
#   - Running miner performance (TAO/day, TAO/hour, rank, incentive)
#   - Optimization suggestions (replace underperformers)
#   - One-keypress deploy, optimize, or start 24/7 watch mode

5. Create a local pool wallet (receives all miner earnings)

# Run from repo root β€” only requires Docker, nothing else installed locally
./scripts/setup-local-wallet.sh

# Creates wallet "pool" at ~/.bittensor/wallets, saves mnemonic securely,
# and writes the SS58 address to mining.conf as BT_LOCAL_WALLET.
# All miner earnings consolidate here via dashboard [K] β†’ [A].

6. Back up your wallet

/opt/openclaw/scripts/backup-wallets.sh
# Then download: scp <pod>:/workspace/wallet-backup-*.tar.gz ~/

Commands

Action Command
Dashboard python3 /opt/openclaw/bt_subnet_manager.py
24/7 watch python3 /opt/openclaw/bt_subnet_manager.py --watch
Miner status pm2 list
Logs pm2 logs miner-sn<N>
Restart pm2 restart all
Add subnet /opt/openclaw/scripts/setup-subnet.sh <N>
Start miner /opt/openclaw/scripts/start-miners.sh <N>
Analyze subnets python3 /opt/openclaw/subnet_analyzer.py
Analyze (no filter) python3 /opt/openclaw/subnet_analyzer.py --no-shariah
Analyze (custom TAO) python3 /opt/openclaw/subnet_analyzer.py --tao-price 350
Compare subnet python3 /opt/openclaw/test_subnet_comparison.py 71
Monitor miners python3 /opt/openclaw/miner_monitor.py --recommend
Edit config nano /workspace/mining.conf
Setup local wallet ./scripts/setup-local-wallet.sh (run locally, uses Docker)
Backup wallets /opt/openclaw/scripts/backup-wallets.sh

Interactive Dashboard

The bt_subnet_manager.py is the primary interface. One command, one screen:

══════════════════════════════════════════════════════════════════
  BT Subnet Manager  |  2026-03-16 14:30 UTC  |  Wallet: min  |  Data: LIVE
══════════════════════════════════════════════════════════════════
  SYS  CPU: β–°β–°β–°β–°β–°β–°β–±β–±β–±β–±β–±β–± 42% (8 cores)  RAM: β–°β–°β–°β–°β–°β–°β–°β–±β–±β–±β–±β–± 12.3/32 GB  IO: R:120MB W:450MB
       Load: 3.36 (1m)  2.80 (5m)  2.15 (15m)  | 8 cores β†’ green < 8, amber < 16
  GPU 0 RTX 3090  CUDA 12.4  Driver 535.129.03  Cost: $0.22/hr ($5.28/day)
    VRAM: β–°β–°β–°β–°β–°β–°β–°β–°β–°β–°β–°β–±β–±β–±β–± 18.0/24 GB  Util: β–°β–°β–°β–°β–°β–°β–°β–°β–°β–°β–°β–°β–°β–±β–±  Temp: 72Β°C  Power: β–°β–°β–°β–°β–°β–°β–°β–°β–±β–± 280W

  RUNNING MINERS  (3 active | Total: 0.024510 TAO/day)
  ─────────────────────────────────────────────────────
  SN4  Targon     online   inc:0.00312  rank: 42/180  0.009200t/d  [OK]
  SN18 Cortex.t   online   inc:0.00198  rank: 88/200  0.008100t/d  [OK]
  SN25 Protein    online   inc:0.00001  rank:190/195  0.007210t/d  [REPLACE]

  TOP 5 GPU SUBNETS (RunPod)
  ─────────────────────────────────────────────────────
   1) SN4  Targon        GPU    8.2100t  0.009200t/d  ROI: 12d  [LIVE]
   2) SN18 Cortex.t      GPU    6.5000t  0.008100t/d  ROI: 15d  [LIVE]
  ...

  [D] Deploy  [P] Prepare hotkeys  [O] Optimize  [G] GPU test  [K] Wallet  [W] Watch  [R] Refresh  [Q] Quit
  or type SN number to quick-deploy
══════════════════════════════════════════════════════════════════

Menu options:

  • [D] Deploy β€” Select subnets by number, auto-creates wallet/hotkey/registers/starts
  • [P] Prepare β€” Batch-create hotkeys for top subnets (free, no TAO burn, ready to deploy instantly)
  • [O] Optimize β€” Review underperformers, swap with better subnets (with cost warnings)
  • [G] GPU test β€” Full system + GPU diagnostics: CPU, RAM, load averages, VRAM, temperature, power, RunPod cost ($/hr, $/day, $/month), CUDA test
  • [I] Infrastructure β€” RunPod pod management: launch, start, stop, terminate pods with cost visibility
  • [K] Wallet β€” Wallet operations: balance report, TAO transfers, consolidation, backup, create keys, permissions
  • [W] Watch β€” Start 24/7 background monitoring via pm2
  • [R] Refresh β€” Re-fetch live chain data
  • [J] JSON β€” Export full report to /workspace/data/
  • Type a number β€” Quick-deploy any subnet (e.g., type 4 to deploy SN4 immediately)

Hotkey indicators on subnet rows: * = running, K = hotkey ready (can deploy instantly).

Registration Costs

Registration burns TAO and newly registered miners need ~3 days to warm up. The manager always shows:

  • Registration burn cost per subnet
  • ROI including warmup penalty
  • Requires typing yes to confirm any registration
  • Only suggests replacements after 24h+ of sustained underperformance

Deployment Pipeline

flowchart TD
    SELECT["User selects subnet<br/>(e.g. SN4)"] --> CK{"Coldkey<br/>exists?"}
    CK -->|No| CK_CREATE["btcli wallet create<br/>Mnemonic β†’ wallet_creation.log"]
    CK -->|Yes| HK
    CK_CREATE --> HK{"Hotkey<br/>hotkey-sn4<br/>exists?"}
    HK -->|No| HK_CREATE["btcli wallet new_hotkey<br/>Secret β†’ wallet_creation.log"]
    HK -->|Yes| CLONE
    HK_CREATE --> CLONE{"Miner code<br/>exists?"}
    CLONE -->|No| SETUP["setup-subnet.sh 4<br/>Clone repo + pip install"]
    CLONE -->|Yes| REG
    SETUP --> REG["btcli subnet register<br/>⚠ Burns TAO"]
    REG --> START["start-miners.sh 4<br/>pm2 start miner-sn4"]
    START --> PERM["chmod 0700 wallet dirs"]
    PERM --> LIVE["Miner live<br/>~3 day warmup"]
Loading

Configuration

All config is centralized through config.py. Priority: environment variable > mining.conf > built-in default.

To add any config key, just add it to mining.conf or set it as an env var β€” no code changes needed:

# In /workspace/mining.conf:
BT_COLDKEY="min"
BT_NETWORK="finney"
SHARIAH_FILTER="true"
TAO_PRICE_USD="400"
RUNPOD_API_KEY="your-key-here"
MY_CUSTOM_KEY="any-value"       # Available as CFG["MY_CUSTOM_KEY"]
# Or as environment variables (override mining.conf):
export RUNPOD_API_KEY="your-key-here"
export TAO_PRICE_USD="350"
Key Default Purpose
BT_COLDKEY min Wallet coldkey name
BT_NETWORK finney Bittensor network
SHARIAH_FILTER true Enable/disable Shariah screening
TAO_PRICE_USD (live fetch) Override TAO/USD price
RUNPOD_API_KEY (none) RunPod API key for pod management
BT_LOCAL_WALLET (none) Destination SS58 address for TAO transfers/consolidation
BT_DATA_DIR /workspace/data Data directory
BT_WALLET_PATH /workspace/wallets Wallet storage path

Persistence

Everything under /workspace/ lives on the Network Volume:

/workspace/
β”œβ”€β”€ mining.conf          # Configuration (never committed)
β”œβ”€β”€ wallets/             # Coldkey + hotkeys (symlinked to ~/.bittensor/wallets)
β”œβ”€β”€ miners/              # Cloned subnet repos (sn4/, sn18/, ...)
β”œβ”€β”€ data/                # Monitor snapshots + manager reports
└── logs/                # pm2 logs + watch daemon logs

Wallet & Hotkey Conventions

  • Coldkey name: configurable via BT_COLDKEY (default: min)
  • Hotkey naming: hotkey-sn{netuid} (e.g., hotkey-sn4, hotkey-sn18)
  • Wallet path: /workspace/wallets/ (Network Volume)
  • Symlink: ~/.bittensor/wallets -> /workspace/wallets/
  • Permissions: 0700 (owner-only) on all wallet directories

Wallet Management

Access via dashboard [K]:

  • [B] Balance report β€” On-chain balance query for all wallets: free TAO, staked TAO, active/idle status. Uses bittensor SDK (fast) with btcli fallback. Non-zero filter option
  • [T] Transfer TAO β€” Transfer from any hotkey to a destination SS58 address. Fee < 0.0003 TAO. Requires yes confirmation
  • [A] Consolidate all β€” Transfer all non-zero hotkey balances to a single destination. Shows dry-run plan first, then executes after confirmation. Leaves 0.001 TAO dust per hotkey
  • [K] Backup β€” Creates tar.gz archive of all wallets with scp download instructions
  • [C] Create coldkey β€” Idempotent (checks coldkeypub.txt before creating)
  • [H] Create hotkeys β€” Batch create for multiple subnets at once
  • [S] Secure permissions β€” Sets 0700 on all wallet directories
  • Auto-created on deploy β€” [D] Deploy automatically handles wallet setup

Set BT_LOCAL_WALLET in mining.conf to your local/cold wallet SS58 address for one-click consolidation.

Secret Key Safety

Mnemonics and private key output are never displayed on the console. All wallet creation output is written to /workspace/data/wallet_creation.log with 0600 permissions (owner read/write only). Back up this file securely and delete after recording your recovery phrases.

Shariah Compliance

Shariah screening is enabled by default but fully configurable for a wider audience:

# Default: Shariah filter ON β€” non-compliant excluded, cost comparison shown
python3 /opt/openclaw/subnet_analyzer.py

# Disable filter β€” all subnets included (flagged but not excluded)
python3 /opt/openclaw/subnet_analyzer.py --no-shariah

# Or set in mining.conf:
SHARIAH_FILTER="false"

When the filter is active, subnet_analyzer.py screens all subnets and shows the top 3 excluded subnets for comparison so you can see the opportunity cost:

  • SN8 (Taoshi) β€” leveraged prop trading (maisir + gharar + riba)
  • SN11, SN19, SN23 β€” pending scholarly review (unfiltered content)

28 of 32 cataloged subnets pass screening.

RunPod Cost Analysis

The analyzer shows RunPod running costs and NET daily profit per miner. TAO/USD price is fetched live from CoinGecko on every run (stdlib urllib, no extra deps):

# Full analysis β€” TAO price auto-fetched from CoinGecko
python3 /opt/openclaw/subnet_analyzer.py --gpu-only

# Override TAO price manually
python3 /opt/openclaw/subnet_analyzer.py --tao-price 350

# Or pin via env var in mining.conf (skips live fetch):
TAO_PRICE_USD="350"

Price resolution order: --tao-price CLI flag > TAO_PRICE_USD env var > CoinGecko live API > $400 fallback.

For each GPU subnet the analyzer shows:

  • Best GPU β€” cheapest RunPod GPU meeting the subnet's VRAM requirement
  • GPU$/d β€” daily GPU rental cost
  • Stor$/d β€” daily Network Volume storage cost
  • Cost$/d β€” total daily RunPod cost (GPU + storage)
  • NET$/d β€” daily profit after subtracting RunPod costs (green = profit, red = loss)

Local Testing

Compare any subnet against the top 5 most profitable with full cost analysis:

# Build test container (no GPU needed)
docker build -f Dockerfile.test -t openclaw-test .

# Compare SN71 against top 5 (live chain data)
docker run --rm openclaw-test test_subnet_comparison.py 71

# Disable Shariah filter
docker run --rm openclaw-test test_subnet_comparison.py 71 --no-shariah

# Custom TAO price
docker run --rm -e TAO_PRICE_USD=350 openclaw-test test_subnet_comparison.py 4

# List all live subnets with Shariah status
docker run --rm openclaw-test test_subnet_comparison.py --list

# Create a local pool wallet (no local btcli needed)
./scripts/setup-local-wallet.sh

RunPod API β€” Pod Management

The dashboard [I] Infrastructure menu manages RunPod GPU pods directly via the REST API (stdlib urllib, no extra deps).

Setup

# Set API key (get from https://www.runpod.io/console/user/settings)
export RUNPOD_API_KEY="your-api-key"

# Or add to mining.conf:
RUNPOD_API_KEY="your-api-key"

Capabilities

Action Description
List pods Shows all pods with status, GPU, cost/hr, cost/day
Launch pod Select GPU from pricing table, name pod, attach network volume
Start pod Resume a stopped pod
Stop pod Pause a running pod (preserves state)
Terminate pod Permanently delete a pod (requires "yes terminate" confirmation)

Total running cost across all pods is shown at the top of the infrastructure view.

VPS + RunPod Portability

The same Python code runs on both VPS (systemd) and RunPod (pm2). Runtime is auto-detected:

Setting VPS (systemd) RunPod (pm2)
Process mgmt systemctl start/stop pm2 start/delete
Base dir /opt/bittensor /workspace
Wallet path /opt/bittensor/wallets /workspace/wallets
Config /opt/bittensor/mining.conf /workspace/mining.conf
GPU monitoring Graceful skip (no nvidia-smi) Full GPU stats
Watch daemon systemd timer pm2 cron

All paths overridable via env vars: BT_DATA_DIR, BT_WALLET_PATH, BT_MINERS_DIR, BT_LOG_DIR, BT_CONFIG, BT_RUNTIME.

Syncing with VPS Repo

# Pull shared files from openclaw-ansible:
./copy-from-vps-repo.sh /path/to/openclaw-ansible

Branching Strategy

  • dev β€” Default branch. All work merges here via PRs.
  • feature/* β€” New features branch off dev.
  • bugfix/* β€” Bug fixes branch off dev.
  • PRs are the only method to commit changes.

License

TBD

About

Bittensor GPU mining on RunPod

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors