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.