c104c1eefa46b1d2ce943f73cbe2bf83773990ac
Block-reward tile was cached for 60s, so users saw it sit still even as bitcoind's CreateNewBlock fired every few seconds with updated fee totals. Drop the template cache TTL to 15s — bitcoind caches the template internally, so the extra RPC cost is trivial. Hashrate chart was rendering 1440 raw per-minute points across a ~780px plot, which collapsed into a noisy smear. Bucket-average to ~96 points so the chart actually communicates a trend. Raw samples under the target pass through unchanged (early process lifetime). Layout: Blocks found is now full-width, with the Best shares leaderboard stacked below it. The previous side-by-side was squeezing both tables on typical displays. New user-detail modal. Clicking a BTC address in the Miners table opens a focused view: per-user aggregate hashrate (1m/5m/1h/24h), best round / best ever, and a worker-level breakdown with the same columns as the main table. Driven by a small selection store so any component in the tree can open it. Closes on backdrop click or Esc. New block-found animation. When the network tip advances, a brief full-screen overlay plays: a radial Hinokami Kagura ember burst above the header, a faint sun-ray sweep, and ~22 falling sakura petals with randomised drift / rotation / delay so no two blocks look identical. The existing block-height tile flash still fires alongside; the overlay is pointer-events: none so nothing in the UI becomes unreachable during the ~3.6s animation.
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%