Frontend in @gashboard/web (Vue 3 + Vite + Pinia + TS, ~1.2k LoC):
Auth flow:
- Two signing paths: NIP-07 browser extension (Alby/nos2x/Primal
extension via window.nostr) and NIP-46 remote signer (Primal
app, Amber, nsecbunker via bunker:// URI).
- applesauce-signers lazy-loaded only on bunker login so users
with NIP-07 don't pay the cost.
- NIP-98 event built client-side, posted to /api/auth/login,
JWT persisted in localStorage. Pinia auth store handles
login/logout/state restore on reload.
Dashboard (composes the live /api/datum/stats poll, 5s):
- PoolHero — combined hashrate as the headline number,
block height, subscribed count, accepted/rejected shares.
- LotteryWidget — rotating self-deprecating odds copy
("you're 0.3× as likely to find a block as get hit by
lightning today"). Uses ~720 EH/s as the network-hashrate
constant (TODO: fetch live).
- ShareTicker — SVG sparkline of the last 60 polls.
- MinerCard ×N — nickname (QU4CK/P1XEL/N4N0/M1N1), live
hashrate, last share, lifetime tickets, reject %, status
glow (green hashing / amber stale / red idle), affectionate
roast subtitle per ASIC type.
- BlockCelebration — full-screen overlay with celebration
copy. Dormant for now (Datum's lastBlockFoundAt isn't
surfaced yet); preview via window.gashboardCelebrate().
Cyberpunk theme:
- Pure CSS vars, no Tailwind. Dark bg, neon cyan/magenta
accents, monospace, glow shadows.
- Optional CRT scanlines toggle (persists to localStorage).
- Mobile-aware grid breakpoints.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
gashboard
a custom dashboard for the datum gateway running on umbrel. for the four little boards that probably won't find a block, but are trying their best.
Polls a local Datum gateway (OCEAN's open-source mining gateway), shows live per-miner hashrate, share counts, lottery odds, and a tongue-in-cheek read on how unlikely it all is. Designed for a small fleet of solo-style hobby miners (Bitaxe, NerdQAxe, Avalon Nano 3, Avalon Mini 3) hashing into one Datum on Umbrel.
What it shows
- Pool hero — combined hashrate, current block height being templated, mempool fee snapshot, datum connection status.
- Per-miner cards — nickname, ASIC type, location, live hashrate, accepted/rejected shares, last-share age, status light, firmware string from
useragent. - Lottery widget — P(block in 24h) at current network difficulty, with rotating self-deprecating commentary.
- Live share ticker — sparkline + scrolling feed of recent accepted shares.
- Sats-today counter — earnings projection from current hashrate × network reward.
- Map panel — pins for each location (split by remote IP from Datum's
/clients), pulse-per-share. - Block celebration — confetti + sound the day it finally happens.
Auth
Nostr-only login (NIP-98 over HTTP). Two signers supported:
- Remote signer (NIP-46) — covers Primal app, Amber, nsecbunker.
- Browser extension (NIP-07) — Alby, nos2x, etc.
Allowlist of npubs is set via NOSTR_ALLOWED_NPUBS. Anything else is rejected before a session token is issued.
Stack
- Frontend — Vue 3 + Vite + Pinia + TypeScript
- Backend — Express + TypeScript
- Auth —
nostr-tools(NIP-98 verify),applesauce-*(signer abstraction, lifted from indeehub) - Container — multi-stage
node:22.12.0-alpine(pinned by SHA256 in Dockerfile)
Deploy on Portainer (the way it'll actually run)
-
Enable Datum admin API on your Umbrel — edit
~/umbrel/app-data/datum-gateway/data/datum_gateway/datum_gateway_config.jsonand add"admin_password": "<openssl rand -hex 32>"inside the"api"block. Restart the Datum app. -
Push this repo to your gitea/whatever:
git push -u origin main -
In Portainer → Stacks → Add stack → Repository:
- Repository URL:
https://git.tx1138.com/lfg2025/gashboard - Compose path:
docker-compose.yml - Add env vars (see
.env.example) - Set the
externalnetwork in the compose file to match your Datum app's docker network (find withdocker network lson the Umbrel)
- Repository URL:
-
Open the dashboard, log in with one of the allowed npubs, watch your boards lose at hashing in style.
Local dev
pnpm install
pnpm dev # runs api + web concurrently
License
MIT.