BTX Start is a competitive onboarding frontend and installer fork for BTX, the post-quantum Bitcoin Knots fork with matmul proof-of-work.
- BTX Start site: https://drinknile.com/
- Installer URL: https://drinknile.com/install.sh
- Default stratum target:
stratum.drinknile.com:3333 - Stats API target:
https://api.drinknile.com/stats - BTX Start platform fee: 0.00% for 7 days per payout address, then 0.50% after backend launch
- Revenue model: REVENUE_MODEL.md
- GPU rentals: VAST_AI.md
- Apple Silicon setup: MAC_SETUP.md
- Backend scaffold: backend/README.md
Smoother earnings vs. solo variance. At BTX's current network hashrate a single 5070-class card finds a block roughly every 4-7 days on average solo — but variance is high; you can go 3 weeks without one. PPLNS pays you continuously based on the shares you submit, so income tracks your actual hashrate rather than your luck. The pool eats the variance.
Block propagation as a first-party requirement. BTX's P2P mesh is small and slow, so the owned backend needs a dedicated block-forwarder, curated peer mesh, and monitoring before the pool is marked live. New miners are pointed at the BTX Start hostnames from launch so there is no later pool migration.
Peer management belongs in the backend. Solo miners spend the first week
hunting for non-stalling peers. The owned backend should maintain a curated
peer list and expose it through https://api.drinknile.com/peer_list.
Built-in fallbacks for the things that actually break. A year of running this fleet uncovered roughly a dozen silent-failure modes — shielded-state corruption after reorg storms, btxd hanging on slow peer block-body delivery, tailscaled crashes in userspace containers, CUDA buffer pool exhaustion at batch=256. The miner ships with reconnect backoff, daemon respawn, and a hard CUDA-engagement smoke test in the installer. You won't silently mine on CPU for three weeks like we did.
Simplicity. Solo mining requires running your own btxd (full node,
600 GB chainstate, manual peer wrangling, manual restart after every
reorg storm). BTX Start keeps the miner path to curl | bash | mine.
One binary, one YAML, one tmux session. No node admin.
Fee transparency. The public site shows BTX Start's 7-day fee-free trial, 0.50% post-trial platform fee, first-party backend readiness, and the public fee/treasury addresses once the backend wallet is connected.
Near-zero friction. The default path requires no account, no email, no chat app, no wallet connection, and no custody. A miner pastes a payout address, copies one command, and mines to their own wallet.
Linux + any NVIDIA GPU from Pascal (GTX 10-series) through Blackwell (RTX 50-series):
Check the host first without installing anything:
curl -fsSL https://drinknile.com/install.sh | bash -s -- --preflight --address 'btx1z...YOUR_BTX_ADDRESS...'Then install:
curl -fsSL https://drinknile.com/install.sh | bash -s -- --address 'btx1z...YOUR_BTX_ADDRESS...'What this does:
- Detects your GPU and writes a tuned
~/.dexbtx-miner/config.yamlwith per-card workers / threads / batch size (measured profiles for all major NVIDIA gens — see docs/TUNING.md) - Downloads the
btx-gbt-solvesolver binary from the GitHub release for your chosenPREBUILDS_TAG, SHA256-verifies it against the value pinned inpyproject.toml, and refuses to install on mismatch - Runs a hard GPU-acceleration smoke test that fails loudly if CUDA didn't actually engage — catches the silent-CPU-fallback class of bug that would otherwise mine at 1/1000th the throughput without you ever noticing
- Installs the
dexbtx-minerPython orchestrator (this repo) viapip install --user
When the install finishes:
dexbtx-miner --config ~/.dexbtx-miner/config.yaml
# or, persistent in tmux:
tmux new -d -s dexbtx 'dexbtx-miner --config ~/.dexbtx-miner/config.yaml 2>&1 | tee -a ~/.dexbtx-miner/miner.log'Within a minute you should see share OK lines in the log. Use the BTX Start
site to track local miner signals, expected GPU yield, and aggregate network
stats.
MacBook Pro, Mac Studio, Mac Pro, Max, and Ultra machines use the dedicated Metal path instead of the Linux/NVIDIA CUDA path:
curl -fsSL https://drinknile.com/install.sh | bash -s -- \
--preflight \
--solver-backend metal \
--local-solver "$HOME/.dexbtx-miner/bin/btx-gbt-solve" \
--trust-local-solver \
--address 'btx1z...YOUR_BTX_ADDRESS...' \
--worker 'mac-ultra'The current pinned release artifact is still the Linux/NVIDIA solver. Mac
users need a local Apple Silicon btx-gbt-solve binary until a Mac artifact is
published and hash-pinned. See MAC_SETUP.md.
The package also installs btxstart, a website helper CLI. It is not a
replacement for the real BTX node btx-cli; it never creates wallets, signs
transactions, exports keys, or talks to private node RPC. Use it for BTX Start
commands and public status:
btxstart preflight-command --address 'btx1z...YOUR_BTX_ADDRESS...' --worker 'default'
btxstart install-command --address 'btx1z...YOUR_BTX_ADDRESS...' --worker 'default'
btxstart status
btxstart fee-preview --first-share-at 2026-05-26T09:15:00Z --gross-sat 100000000Use the real btx-cli only on a backend or personal wallet machine that runs
btxd. The website-specific helper exists so users can inspect BTX Start
commands without touching wallet custody.
The repo includes a first-party backend scaffold under backend:
backend/app.pyservesapi.drinknile.comwith health, stats, policy, dashboard, and optional billing endpoints.backend/stratum_server.pyis the guarded TCP stratum entrypoint forstratum.drinknile.com:3333.backend/repository.py+backend/schema.sqlstore miners, workers, shares, balances, payouts, fee ledger, accounts, and subscriptions.backend/payout_worker.pycreates dry-run payout plans and can execute reviewed payouts through private BTX RPC.backend/billing.pyverifies Stripe webhooks and creates optional Pro membership checkout sessions.
The stratum scaffold deliberately rejects submitted shares until real BTX matmul share validation is wired in. Do not set the backend live just because the service starts.
Recommended naming pattern: <alias>-<gpu>-<country2>-<color>
(four dash-separated parts, all lowercase) — e.g. kappa-5060ti-us-blue,
bravo-1070-de-red, tango-4060ti-ca-green.
Parts:
<alias>— your handle for this rig (any nickname; avoid your real name)<gpu>— short GPU model (1070,2080ti,3060ti,4060ti,5070, …)<country2>— ISO 3166-1 alpha-2 country code (us,de,ca,gb,jp, …)<color>— short, unique-to-you suffix to disambiguate multiple identical rigs
Why the country + color suffix? Two miners both running 5060 Tis in the US
would otherwise collide on home-5060ti. The country + color tail keeps
your worker rows unique in logs and future dashboard views.
Stick with one name per rig once chosen — renaming creates a new worker row and earned shares stay with the old name.
.
├── install.sh # one-line installer (curl | bash entry point)
├── pyproject.toml # Python package definition + pinned solver SHA256
├── config.example.yaml # config template (copy + edit address)
├── src/dexbtx_miner/ # the Python client
│ ├── __main__.py # CLI entry: `dexbtx-miner --config <yaml>`
│ ├── stratum_client.py # stratum/2.0-matmul protocol client
│ ├── gbt_solve_wrapper.py # async daemon-mode wrapper around btx-gbt-solve
│ ├── benchmark.py # `dexbtx-miner benchmark` — sweep + tune
│ └── config.py # YAML config loader + SolverEnv plumbing
├── tests/
│ └── test_gbt_solve_wrapper.py # smoke test for the wrapper
├── docs/
│ ├── ONBOARDING.md # fresh starters / converters / self-hosters — pick your path
│ └── TUNING.md # per-GPU env-var reference + sweep methodology
└── release-tooling/
├── README.md # about the binary release assets
├── SHA256SUMS # hashes pinned to current release tag
└── publish-release.sh # `gh release create` helper for new versions
The btx-gbt-solve binary itself isn't committed to the repo — it's
published as a GitHub Release asset. The
installer fetches it and SHA-verifies against pyproject.toml.
The installer auto-picks these based on the detected GPU. Every entry
in this table was measured on real hardware via the
dexbtx-miner benchmark sweep methodology in docs/TUNING.md.
| GPU | workers | threads | batch | Measured util / power |
|---|---|---|---|---|
| GTX 1070 (Pascal sm_61) | 16 | 8 | 128 | 83% / 113W (memory-bound — Pascal's ceiling) |
| RTX 2080 Ti (Turing sm_75) | 12 | 8 | 128 | 100% / 296W |
| RTX 3060 Ti (Ampere sm_86) | 12 | 8 | 128 | 100% / 190W |
| RTX 4060 Ti (Ada Lovelace sm_89) | 12 | 8 | 128 | 100% / 164W |
| RTX 5060 Ti (Blackwell sm_120) | 16 | 8 | 128 | 99% / 150W |
| RTX 5070 (Blackwell sm_120) | 16 | 8 | 128 | 100% / 223W |
| RTX 5070 Ti (Blackwell sm_120) | 16 | 8 | 128 | (avoid batch=256 — broke CUDA on this card historically) |
Universal default: workers=16 threads=8 batch=128 prefetch=8
works on every NVIDIA generation from Pascal through Blackwell. The
installer writes this for any unknown card.
The dominant levers are solver_prepare_workers + solver_threads,
working together — the matmul backend is CPU-input-prep-bound on every
modern card we've tested. Raising the pair from workers=8/threads=4
to workers=16/threads=8 took an RTX 5070 from 70% → 100% util. Bump
them as a unit; they go hand in hand. Batch size has no effect on
steady-state throughput once prep is sized correctly.
The shipped btx-gbt-solve binary embeds native cubins for sm_61
(Pascal), sm_89 (Ada Lovelace), sm_90 (Hopper), and sm_120 (Blackwell)
— plus PTX so the driver can JIT to any newer-or-compatible arch:
| Card | Path |
|---|---|
| GTX 1070 / Pascal sm_61 | Native sm_61 cubin |
| Volta / Turing / Ampere (sm_70–sm_86) | sm_61 PTX → JIT to your arch |
| RTX 40-series / Ada (sm_89) | Native sm_89 cubin |
| Hopper (sm_90, H100) | Native sm_90 cubin |
| RTX 50-series / Blackwell (sm_120) | Native sm_120 cubin |
If install.sh's smoke test fails with "binary lacks compatible
kernel image", the binary needs rebuilding for your GPU — don't
downgrade your driver. Open an issue and we'll ship a build that
covers your hardware.
CPU-side input prep can't keep the matmul kernel fed. Bump
solver_prepare_workers to 16 (and solver_threads to 8) in your
config. Batch size, prefetch depth, and pipeline_async are NOT the
dominant levers — workers and threads are.
Right after a stratum reconnect (or after the pool restarts), your miner replays old work — that produces:
- code 21 (
job stale) — slice ran past the 180s freshness window - code 22 (
duplicate share) — same nonce already submitted - code 23 (
digest >= share_target) — pool difficulty changed during reconnect
All three are normal post-reconnect noise. Wait 1–2 minutes; new jobs arrive and accepted shares start flowing.
Silent CPU fallback. The solver binary doesn't have a CUDA kernel image compatible with your driver. The installer's smoke test catches this — if you skipped it, run:
nvidia-smi --query-compute-apps=pid,process_name --format=csv,noheaderIf btx-gbt-solve isn't listed while the miner is running, the
binary fell back to CPU silently. File an issue with your nvidia-smi -q output; do not downgrade your driver.
# Sweep batch sizes (default: 32, 64, 128, 256 for 30 seconds each):
dexbtx-miner benchmark
# Custom sweep over multiple dimensions:
dexbtx-miner benchmark --batches 64,128,256 --prefetches 4,8,16 --workers 8,12,16
# Write the winning config straight to your config.yaml:
dexbtx-miner benchmark --write-configSee docs/TUNING.md for the canonical env-var
reference and why tries_used / nonce64 are misleading per-card
performance counters (the only honest absolute measure is btxprice.com's
network-derived metric).
dexbtx-miner is pool-only. If you want to mine solo against your own
btxd, use the upstream btx-gbt-miner.py from the BTX source tree
(linked in release-tooling/SHA256SUMS) —
it speaks GBT directly to a local node and skips stratum entirely.
We don't ship a solo path here because (a) the pool's block-forwarder, peer-mesh tuning, and PPLNS smoothing are the entire value proposition, and (b) running your own btxd well (peers, dbcache, reorg recovery) is more work than most miners want to take on.
git clone https://github.com/pythonoptic-sketch/minebtx-start
cd minebtx-start
# Run the Python wrapper directly:
pip install --user -e .
dexbtx-miner --config config.example.yaml
# Run tests (requires btx-gbt-solve in $PATH or BTX_GBT_SOLVE env):
python3 tests/test_gbt_solve_wrapper.pyThe solver binary itself is built from
Bitcoin Knots fork BTX source with
the --share-target and daemon-mode patches applied (see
release-tooling/README.md for the build
recipe + portability requirements).
MIT — fork it, ship it, modify it, sell it. We just ask that you don't strip the copyright notice from your distribution.
- GitHub Issues: https://github.com/pythonoptic-sketch/minebtx-start/issues
- Network info: btxprice.com