Releases: GNP1-dev/PoolTerminal
Release list
PoolTerminal v0.3.0 (beta)
PoolTerminal v0.3.0 is a focused correctness release for delegator figures. A delegator's Movements now shows the ADA that actually moved in and out per transaction, and per-epoch active stake stops presenting the next epoch's snapshot as though it were today's.
Both came out of chasing a single reported inconsistency to the bottom. Still a beta, still read-only, still in daily use against a live block producer.
Movements: the ADA that actually moved
A notification would say a delegator had added 510 ₳, and nothing anywhere in the app could show you that payment. The tab was called Intra-epoch movements, but it only ever listed rewards and withdrawals — read from db-sync's reward, reward_rest and withdrawal tables. A plain ADA transfer is none of those, so it appeared nowhere. Two epochs later the same money turned up as an unexplained step in the active-stake series.
- Per-transaction transfers, from a UTxO walk over the account's own outputs: what came in, what went out, with the transaction hash and timestamp behind each
- Rewards, withdrawals and treasury / reserves payouts still listed alongside, so the reward account and the spendable balance are visible in one place
- Any reward withdrawal inside a transaction is subtracted from that transaction's transfer figure. Without this, a withdrawal reads as free money arriving instead of a fee being paid, and gets counted twice — once as a withdrawal, once as a receipt
- A net for the epoch, naming the epoch that stake becomes active in, which is the line that ties a balance-change notification to the active-stake table
- The tab states its coverage instead of implying completeness, and says plainly when transfers are unavailable (Koios and Blockfrost setups — this one needs db-sync)
Spend detection reads both sources. db-sync records a spend in tx_in, or as tx_out.consumed_by_tx_id when consumed-tx-out mode is on, and an installation can sit part-way between the two — measured on a live 15.50.6 node: 339M tx_in rows against consumed_by_tx_id on only 39.8M of 353M tx_out rows. Picking the wrong one does not raise an error; it silently under-reports spends, which is the worst failure a balance view can have. Both are read and de-duplicated on the output id, which is correct whichever mode a node runs.
Active stake no longer calls next epoch "now"
The per-epoch table showed a row for an epoch that had not started — epoch 648 while the chain was in 647 — and treated it as the current figure.
That row is real. Every source labels a stake snapshot with the epoch it becomes active in, and a snapshot is fixed a whole epoch before it takes effect, so the newest row a source can serve is normally tip+1. It was the presentation that was wrong: the app took "newest row" to mean "now", reconciled the live balance against a future epoch, and described it in the past tense.
- The series is split at the chain tip: the snapshot in force drives the reconciliation and the deep-dive stat, and the not-yet-started one is labelled next with an explanation of when it takes effect
- Applied across all three sources — db-sync, Koios and Blockfrost — so the reading does not depend on which one answers
- Self-corrects when the local epoch cache lags a boundary, rather than mislabelling the current epoch for a refresh cycle
- An account whose first snapshot has not taken effect yet reads as such, instead of showing a blank
Verification
Checked against a live db-sync at schema 15.50.6 and cross-checked to the lovelace against an independent reconstruction of the same transactions from Koios, including the deliberate difference where a withdrawal is netted out of its transaction.
The transfer query is bounded by the stake_address_id index alone — 48 ms for a 1,178-output account, 310 ms for the slowest of a sampled set. Two shapes that read as tidier were measured and rejected: an epoch-derived transaction-id floor cost 11 s on its own, and a LEFT JOIN … COALESCE hash-joined the whole of tx_in and ran past two minutes. Both are recorded in the source so they don't get "cleaned up" back in.
Install
AppImage (any distro, no install):
chmod +x PoolTerminal_0.3.0_amd64.AppImage
./PoolTerminal_0.3.0_amd64.AppImageMissing FUSE? Either sudo apt install libfuse2, or run with --appimage-extract-and-run.
.deb (Debian / Ubuntu):
sudo dpkg -i PoolTerminal_0.3.0_amd64.debLinux x86_64. Windows and macOS builds are planned, and will ship unsigned.
No node to hand? Open Demo mode from the LIVE/DEMO badge and the whole interface runs on synthetic data.
Feedback
Bugs, wrong numbers, confusing screens, setup steps that didn't work — open an issue. Rough reports are fine. It's read-only, so the worst a bug can do is show you something wrong; your pool is never at risk from it.
PoolTerminal v0.2.0 (beta)
PoolTerminal v0.2.0 is a substantial feature release: a new LOGS diagnostics workspace, ALERTS (Telegram, with nothing installed on your block producer), the KES hourglass, and delegator balances that now reconcile against live account state.
Still a beta, still read-only, still in daily use against a live block producer. If you're an SPO, the most useful thing you can do is run it and tell me what broke.
New: ALERTS — Telegram alerting, no agent on your BP
Every other SPO alerting setup wants an agent, a cron job, or a monitoring stack running next to your node. PoolTerminal already receives this data every poll cycle, so it just sends it on.
- Guided three-step setup: create a bot with @Botfather → paste the token → your chat ID is detected automatically
- Six alerts, each independently toggled with its own threshold: KES expiry, node stall, block minted, slow propagation, mempool full, low peers
- A Test button on every alert, so you can see exactly what it looks like on your phone before relying on it
- Global cooldown and optional quiet hours, so a flapping condition doesn't become a night of buzzing
- The bot token goes to Telegram as an HTTPS header from the Rust backend — never on a command line on your node, never in a process list
Alerts fire while PoolTerminal is open. That's deliberate: no agent, no extra attack surface, nothing new to patch on the block producer.
New: LOGS — a read-only diagnostics workspace
No shell, no writes. Every query is bounded and runs at low CPU/IO priority so it can never compete with block production.
- Curated one-click journal queries: errors & warnings, meaningful activity (with routine per-slot churn filtered out), KES status, restarts, rollbacks, upcoming leader slots
- Blocks minted from two switchable sources — the local CNCLI blocklog (confirmed / ghosted / stolen) or db-sync (every block your pool has ever forged)
- Propagation history persists every block's delay locally and surfaces the slowest for review, with a trend sparkline and median / p95 / worst stats, plus a 1h–7d time-window selector. Where db-sync is configured, each slow block shows which pool forged it
- Epoch transition renders the run-up to an epoch or hard-fork boundary as a stem chart, shading production gaps and marking the first, often-late block after one. A persisted liveness beat distinguishes a real chain production gap (amber) from PoolTerminal simply having been closed (grey) — two very different events that look identical on a plain strip
New: KES hourglass
KES expiry as an hourglass whose sand drains as the key ages — volume-correct to the glass shape, warming in colour as expiry nears, with exact days and periods remaining, plus the on-disk vs on-chain operational certificate counter and health check.
Delegator figures now reconcile against live account state
If you ever compared a delegator's balance here against Cardanoscan and found it slightly under, this is why — and it's now explained rather than left looking like a bug.
The per-epoch series is active stake, frozen at the epoch boundary. An explorer shows the live balance: spendable UTxO plus undrawn rewards. Both are correct; only one was being shown, unlabelled.
- Both figures are now shown, from db-sync, Koios or Blockfrost, with the arithmetic spelled out
- The stake column names the snapshot epoch it came from
- db-sync correctness fix: rewards live in both
rewardandreward_restsince schema 13.2. Summing onlyrewardwhilewithdrawalcovers both drove rewards−withdrawals negative for any account that had ever received a treasury or reserves payout. Reward rows are now filtered onspendable_epoch, and the UTxO anti-join works with or without db-sync pruning enabled - Treasury, reserves and proposal-refund payouts now appear in intra-epoch stake history
Notifications: the epoch boundary no longer swallows real payments
The old 20-minute post-boundary pause was blind — it suppressed events and re-baselined in the same breath, so a genuine payment landing in that window (an operator returning fees, say) was lost for good rather than delayed.
Where db-sync is available, PoolTerminal now reads what each delegator was actually credited at the roll and subtracts it. The reward bump nets to nothing; anything on top still fires, labelled excl. epoch reward. Accounts mid-move are held rather than re-baselined, so nothing is silently swallowed. Koios-only setups fall back to the previous behaviour.
Security disclosure — please read if you use Alerts or Blockfrost
The README previously stated flatly that "secrets are never persisted". That was no longer true, and it has been corrected.
Still never written to disk, in any mode: SSH passwords, OTP/2FA codes, and SSH key passphrases. These are the credentials that could reach your node.
Written to disk unencrypted, in PoolTerminal's own app-data directory (~/.local/share/com.gnp1.poolterminal/), because these features cannot survive a restart otherwise:
| Credential | Stored when | What it can reach |
|---|---|---|
| Koios API key | you use the keyed tier | public chain data |
| Blockfrost project key | you add one | public chain data |
| Telegram bot token | you set up Alerts | only the bot you created |
| db-sync password | only if you ticked "save password" | your own local database |
None can reach your node, your keys, or your funds. If you would rather store none of them: use the free Koios tier, leave Blockfrost and Alerts unconfigured, and use pg_hba.conf loopback trust for db-sync — the app is fully functional that way.
SECURITY.md now documents this in full. Note that the published independent security review (8 July) predates Alerts and does not cover it.
Also in this release
- Per-panel loading spinners on the Dashboard; fixed a transient "LOST" flash on cold start
- Per-peer latency trend sparklines, auto-scaled per peer so millisecond drift is visible
- Propagation strip rescaled to the sub-second range with a 1s reference line
- Propagation capture deduplicated on block number, fixing phantom blocks logged during production gaps
- Issue templates, so bug reports arrive with version, install method, transport and data sources already filled in
Install
AppImage (any distro, no install):
chmod +x PoolTerminal_0.2.0_amd64.AppImage
./PoolTerminal_0.2.0_amd64.AppImageMissing FUSE? Either sudo apt install libfuse2, or run with --appimage-extract-and-run.
.deb (Debian / Ubuntu):
sudo dpkg -i PoolTerminal_0.2.0_amd64.debLinux x86_64. Windows and macOS builds are planned, and will ship unsigned.
No node to hand? Open Demo mode from the LIVE/DEMO badge and the whole interface runs on synthetic data.
Feedback
Bugs, wrong numbers, confusing screens, setup steps that didn't work — open an issue. Rough reports are fine. It's read-only, so the worst a bug can do is show you something wrong; your pool is never at risk from it.
PoolTerminal v0.1.0 (beta)
First public build of PoolTerminal - a read-only operational dashboard for Cardano stake pool operators.
This is a beta. I need your help testing it.
PoolTerminal runs every day against a live block producer, but it is early software and I do not expect it to be working 100% yet. There will be bugs and rough edges, and it has only really been exercised on one operator's setup - mine.
That's where you come in. Every pool is different: distro, node layout, db-sync setup, pool size. If you're an SPO, the most useful thing you can do is run it, try to break it, and tell me what went wrong.
Report a bug - include what you were doing, your setup, and any error text. Rough reports are fine.
It is read-only - it cannot sign, spend, or change anything on your node - so the worst a bug can do is show you something wrong or fail to load. Your pool is never at risk from it.
Install (Linux)
AppImage - recommended, any distro, no install:
chmod +x PoolTerminal_0.1.0_amd64.AppImage
./PoolTerminal_0.1.0_amd64.AppImage
If it won't start, install FUSE (sudo apt install libfuse2) or run it with --appimage-extract-and-run.
.deb - Debian / Ubuntu:
sudo dpkg -i PoolTerminal_0.1.0_amd64.deb
What you get
Live DASHBOARD (chain pulse, KES with op-cert health, mempool flow, block propagation, upcoming leader slots, live chain metadata feed), full per-epoch HISTORY with reward splits, a DELEGATORS table with loyalty ranking and deep-dives, live delegation NOTIFICATIONS, NODE HEALTH, a peer MAP, and isolated RELAY 1 / RELAY 2 dashboards.
Needs only your node plus an internet connection. Optional db-sync and Blockfrost sources unlock more.
Not ready to connect? Demo mode lets you explore the whole interface with no node.
Known rough edges
- The setup wizard is still being refined.
- On first connect, the leadership-schedule query can take up to two minutes on a block producer. That's the node, not the app - it's signposted in the UI.
Apache 2.0. Audit it before you trust it - that's the whole point.
Windows and macOS builds are planned (unsigned).