81227cb90f4e7d53e9e3579058d18ea59749b071
isOpenSource was matching things like Braiins OS, cgminer, bfgminer,
and a generic "esp32" — software that's open but runs on closed
hardware (Antminer, unknown rigs). public-pool's UI reserves the
star for open-source HARDWARE, with open firmware on top, and that's
the convention to match. New regex covers the family verbatim from
public-pool-ui's user-agent-link switch table:
bitaxe, bitaxeHex, NerdMiner, NerdNOS, NerdAxe, NerdAxeGamma,
NerdOCTAXE, NerdEKO, NerdQAxe+, NerdQAxe++, PiAxe, QAxe, QAxe+,
0xAxe, LeafMiner
Also extend detectHardware so all those user-agents get a recognised
label instead of "esp32" / raw token.
Replace the squished "TLS" pill with an inline-flex badge: 0.78em
text, 5px corners, padlock SVG, generous left/right padding so it
reads at a glance instead of looking like a typo.
Custom block explorer: new optional union under StartOS Advanced
config ("Block Explorer" — defaults to "mempool.space"). Picking
"Custom URL" surfaces the value as MEMPOOL_BASE_URL on the
container env. config.Config picks it up, the aggregator copies
it into every Snapshot (mempool_base_url field), and the UI's
shared explorerBaseFor() helper trusts the custom URL verbatim
when present (no /testnet4 / /signet path appended — a self-hosted
instance is presumably single-network already). Falls back to the
public mempool.space mirrors per chain when unset, which is the
default behaviour.
Kamado Pool
A modern, feature-complete solo Bitcoin mining pool built on a patched fork of CKPool, with a real-time web dashboard and a Go-based API middleware that surfaces everything CKPool knows.
Why Kamado?
Existing CKPool-based solutions (like Bassin for Umbrel) read only a handful of periodic stats files and miss most of CKPool's rich data. Kamado talks directly to CKPool's Unix socket API to expose:
- Real-time per-client data: hashrate, difficulty, user agent, hardware detection
- Full block-found history with height, hash, reward, and solving worker
- Per-worker and per-client best share tracking (current + all-time)
- Network difficulty, pool efficiency, expected time to block
- Live dashboard updates via WebSocket (no 60-second file polls)
Architecture
┌────────────────────────────────────────────────────┐
│ ckpool-solo (C) ──Unix socket──► kamado-api (Go) │
│ ports: 3333 ports: 80 │
│ │
│ ▲ stratum ▲ HTTP/WS │
│ │ │ │
│ Miners Browser │
│ │
│ bitcoind ◄──── RPC + ZMQ ────── ckpool + kamado-api│
└────────────────────────────────────────────────────┘
Three main components:
| Component | Language | Purpose |
|---|---|---|
ckpool/ |
C | Stratum server, share validation, block submission |
api/ |
Go | Socket client, REST/WebSocket API, persistence |
ui/ |
Svelte | Real-time dashboard |
Phases
- Phase 1 — Fork & fix CKPool, build infrastructure
- [~] Phase 2 — Go API middleware
- Phase 2a: CKPool socket client, bitcoind RPC, state aggregator, REST API
- Phase 2b: CKPool log tailer, block history, stdlib WebSocket push
- Phase 2b.5: ZMQ block notifier, SQLite persistence (deferred until s9pk repo exists — need real Go build env for new deps)
- ckpool patch 0001: expose
besteverin runtime socket JSON so the UI can show "this round" and "all-time" best share side by side - [~] Phase 3 — Svelte UI dashboard (skeleton: header, pool overview, miners table, blocks, best shares leaderboard; live WS updates)
- Phase 4 — Monorepo Docker build:
kamado-apiembedsui/distvia//go:embedand serves it at/. The api Dockerfile has a node stage that builds the UI before the Go stage embeds and builds the binary; docker-compose uses the repo root as build context so bothapi/andui/are visible. - Phase 5 — Testing (regtest, testnet4), polish
Quick start (dev)
cp .env.example .env # set POOL_BTCADDRESS and bitcoind creds
make up # build + start ckpool + api
curl localhost:8080/api/health
curl localhost:8080/api/pool
REST endpoints:
| Route | Returns |
|---|---|
GET /api/health |
CKPool + bitcoind health |
GET /api/pool |
Pool stats + derived hashrate windows + chain info |
GET /api/users |
All users from users socket command |
GET /api/workers |
All workers from workers socket command |
GET /api/clients |
All connected stratum sessions (useragent, IP, diff) |
GET /api/blocks |
Recent solved blocks (in-memory ring, SQLite in Phase 2b.5) |
GET /api/snapshot |
Full merged snapshot (everything) |
GET /api/ws |
WebSocket push: full snapshot on every refresh + on solve |
StartOS packaging lives in a separate repository.
Upstream
CKPool by Con Kolivas: https://bitbucket.org/ckolivas/ckpool
Pinned commit: see ckpool/CKPOOL_COMMIT
License
GPL-3.0. CKPool itself is distributed under GPL-3.
Languages
Go
46.7%
Svelte
36.4%
Shell
9.2%
TypeScript
4.7%
Dockerfile
1.4%
Other
1.5%