Watch your Ethereum validators from a tiny self-hosted CLI. It talks to your beacon node (no third-party telemetry) and pushes alerts straight to your phone via ntfy.
![]() |
![]() |
![]() |
| operational alert — missed attestations | your push history in the ntfy app | ✓ proposed block (positive event) |
# Auto-detects .deb / .rpm / pipx and installs the right one (Linux & macOS).
curl -fsSL https://raw.githubusercontent.com/Workharu/eth-validator-stats/main/scripts/install.sh | sudo bash
# Interactive wizard: probes your beacon node, generates an ntfy topic, scans a QR for your phone.
sudo eth-validator-stats init
# Sanity-check the last snapshot
eth-validator-stats statusThat's it. On .deb / .rpm installs, init also starts a systemd service that polls every 60 seconds.
evsis a 3-character alias foreth-validator-stats—evs status,evs check --missed 3, etc.
Your phone subscribes to a private ntfy.sh topic that only you know. The CLI POSTs to that topic; ntfy pushes to your phone. The init wizard generates a random topic name, prints a QR you scan with the ntfy mobile app (iOS / Android), and you're done.
Verify the pipe before you trust it:
eth-validator-stats simulate slashed # urgent push (bypasses Do-Not-Disturb)
eth-validator-stats simulate missed # normal-priority pushYou should see them on your phone within a second.
- Health —
OFFLINE,MISSED ATTESTATIONS,withdrawal,MONITOR BLIND/MONITOR RECOVERED - Proposals —
proposing soon,✓ proposed,✗ missed proposal - Lifecycle —
ACTIVATED,SLASHED(urgent),EXIT INITIATED,EXITED,WITHDRAWAL READY - Liveness — daily
MONITOR ALIVEso silence means something. Want sub-5-minute detection? Setalerts.heartbeat_urlto a free healthchecks.io URL.
One push per event, deduplicated per-validator with a configurable cooldown. Full reference (thresholds, env vars, every flag) is in docs/USAGE.md.
And a status table you can pull on-demand:
Validators
┏━━━━━━━━┳━━━━━━━━┳════════════════┳━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━┓
┃ idx ┃ label ┃ status ┃ balance (ETH) ┃ last 5 atts ┃
┡━━━━━━━━╇━━━━━━━━╇════════════════╇━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━┩
│ 123456 │ home-1 │ active_ongoing │ 32.0182 │ ● ● ● ● ● │
│ 234567 │ home-2 │ active_ongoing │ 32.0177 │ ● · ● ● ● │
└────────┴────────┴────────────────┴───────────────┴─────────────┘
● attested, · missed, ? not yet observed.
evs status # last snapshot (read-only; --refresh to poll first)
evs watch # loop forever (what the systemd service runs)
evs check --missed 3 # one-shot for cron — exits 2 if any alert fires
evs validators add 12345 --label home-1
evs validators list --status
evs validators rm home-1
evs simulate <event> # test the push pipe end-to-end
evs info # probe your beacon node's APIinit writes a config.yml. Edit it directly anytime — validators add/list/rm is a convenience for skipping YAML.
beacon_node_url: http://localhost:3500
validators:
- { index: 123456, label: home-1 }
- { pubkey: "0xb1d2...", label: home-2 }
alerts:
ntfy_topic: https://ntfy.sh/eth-vstats-9f8e7d6c5b4a
cooldown_minutes: 30
missed_attestations_threshold: 2Full annotated example: config.yml.example. Lookup order: $ETH_VALIDATOR_STATS_CONFIG → /etc/eth-validator-stats/config.yml → ~/.config/eth-validator-stats/config.yml. First match wins.
When you upgrade and the schema grows, the CLI appends new keys (commented out, with defaults) to your existing config.yml so you can see what's available. Drop # config-sync: off anywhere in the file to opt out.
The curl one-liner above covers most setups. Pick a path explicitly if you prefer:
Debian / Ubuntu — .deb
Debian 12+ / Ubuntu 22.04+ (also 24.04). The .deb bundles its own Python — no PPAs.
# Latest .deb at https://github.com/Workharu/eth-validator-stats/releases/latest
sudo apt install -y ./eth-validator-stats_0.6.1-1_amd64.deb
sudo eth-validator-stats init --system
sudo systemctl status eth-validator-statsUse apt install ./path.deb (not dpkg -i) so deps like adduser resolve. Files: /opt/eth-validator-stats/, symlinks in /usr/bin/, config + state at /etc/eth-validator-stats/ and /var/lib/eth-validator-stats/. apt remove keeps user data; apt purge wipes everything.
Fedora / RHEL / Rocky / Alma 9+ — .rpm
sudo dnf install ./eth-validator-stats-0.6.1-1.fc40.x86_64.rpm
sudo eth-validator-stats init --system
sudo systemctl status eth-validator-statsSame paths and semantics as the .deb. dnf remove keeps config + state.
macOS / hosts without .deb or .rpm — pipx
# Install pipx first if needed: apt|dnf install pipx, or `brew install pipx` on macOS.
pipx install eth-validator-stats
eth-validator-stats init # per-user config at ~/.config/eth-validator-stats/For systemd integration on Linux without the distro packages:
sudo eth-validator-stats install-service # system-scope unit
eth-validator-stats install-service --user # or per-user, no sudo
sudo eth-validator-stats init --system # writes config + starts serviceUpgrade: pipx install --force eth-validator-stats. Uninstall: sudo eth-validator-stats uninstall-service --purge && pipx uninstall eth-validator-stats.
From source (development)
git clone https://github.com/Workharu/eth-validator-stats
cd eth-validator-stats
uv sync
uv run eth-validator-stats status
uv run pytest -qSee packaging/linux/README.md for running the source build as a systemd unit.
COMPATIBILITY.md— beacon clients tested (Prysm / Lighthouse / Teku / Nimbus / Lodestar)docs/USAGE.md— every flag, env var, and alert option in fullCHANGELOG.md— releasesSECURITY.md— report a vulnerabilityCONTRIBUTING.md— dev setup and PR workflow
Push notifications are delivered by ntfy.sh — a free, open-source, Apache-2.0-licensed pub-sub system. This project wouldn't be the same without it.
MIT — see LICENSE.


