Notifications
dvb-WarpPool can notify the operator over several independent channels when
relevant pool events occur — most importantly block found. Configuration
lives in config.toml under [notifier]; secrets (API tokens, webhook URLs,
SMTP passwords) are always referenced via env var, never inline.
Currently active (Phase 15):
| Sink | Protocol | Config key | Secret via env |
|---|---|---|---|
| ntfy | HTTP POST | [notifier.ntfy] | (none — public topic URL suffices) |
| Telegram | Bot API | [notifier.telegram] | bot_token_env |
| Discord | Webhook | [notifier.discord] | webhook_url_env |
| Slack | Incoming Webhook | [notifier.slack] | webhook_url_env |
| SMTP via lettre/TLS | [notifier.email] | password_env (optional) |
Events
The daemon emits five event types:
| Event | When | Priority |
|---|---|---|
block-found | After a successful submitblock in the daemon | high |
miner-disconnect | An authenticated worker closes the Stratum connection; per-worker debounce 30s | medium |
rpc-down | Health check first hits RPC=fail | medium |
rpc-recovered | Health check first hits RPC=ok again after a down state | low |
test | Operator clicks the test button in the admin UI | low |
Each sink can toggle which events it cares about (on_block_found,
on_miner_disconnect, on_rpc_down — all bool). The default everywhere is
on_block_found = true, others off; for Slack/Email all three are toggleable.
Retry: 3 attempts with exponential backoff (2s / 10s / 30s). If everything fails, it gets logged but the daemon keeps running — a notifier failure must never disrupt mining.
ntfy.sh
Simple and account-free. A single topic URL is enough.
[notifier.ntfy]
topic_url = "https://ntfy.sh/my-secret-pool-topic-abc123"
on_block_found = true
on_miner_disconnect = false
on_rpc_down = true
On your phone, install the ntfy app, subscribe to the same topic name, done. Topic names are effectively a shared secret — choose a hard-to-guess string.
For self-hosted ntfy, just use topic_url = "https://ntfy.your-domain.com/topic".
Telegram
Create a bot via @BotFather → note the token. You get a chat_id by sending
the bot a message and then fetching
https://api.telegram.org/bot<TOKEN>/getUpdates (look for "chat":{"id":…}).
[notifier.telegram]
bot_token_env = "TELEGRAM_BOT_TOKEN"
chat_id = "123456789"
on_block_found = true
Then in the daemon environment:
TELEGRAM_BOT_TOKEN="123:abc..." dvb-warppool-daemon
With systemd: Environment="TELEGRAM_BOT_TOKEN=…" in the unit file, or
better an EnvironmentFile=/etc/default/dvb-warppool with chmod 600.
Discord
In the server settings under Integrations → Webhooks, create a new webhook and copy the URL. The URL is effectively the auth token — anyone who has it can post.
[notifier.discord]
webhook_url_env = "DISCORD_WEBHOOK_URL"
on_block_found = true
DISCORD_WEBHOOK_URL="https://discord.com/api/webhooks/…" dvb-warppool-daemon
Slack
Create a Slack app in your workspace → enable Incoming Webhooks → generate a webhook for a channel. The payload uses Block Kit (header + section with mrkdwn) for clean layout.
[notifier.slack]
webhook_url_env = "SLACK_WEBHOOK_URL"
on_block_found = true
on_miner_disconnect = false
on_rpc_down = true
Email (SMTP)
lettre-based, with rustls — no openssl-sys. Two URL schemes:
smtps://user@host:465— implicit TLS (common with providers like Posteo, Migadu, Fastmail, Hetzner)smtp://user@host:587— STARTTLS (gmail, many mail servers)
[notifier.email]
smtp_url = "smtps://pool@mail.example.com:465"
from = "pool@example.com"
to = ["operator@example.com", "monitoring@example.com"]
password_env = "POOL_SMTP_PASSWORD"
on_block_found = true
on_miner_disconnect = false
on_rpc_down = true
POOL_SMTP_PASSWORD="…" dvb-warppool-daemon
password_env is optional — if omitted, no SMTP AUTH is attempted (useful
for a local MTA like Postfix on localhost:25 that relays internally).
With multiple recipients, each one gets their own letter — also a simple way to notify the whole team at once.
Test workflow
After configuration:
- Restart the daemon — logs show
notifier sink readyfor each working sink. If an env var is missing or a required config field is empty, you'll seenotifier sink skippedwith a reason; the daemon starts anyway. - In the admin UI under
/admin/notifications→ "Server-Side Sinks (Daemon)" lists all active sinks. - Per sink, a Test button → POST
/api/admin/notifier/test?sink=<name>fires atestevent at just that one. The badge switches to ok/err. - Test all sinks button → POST
/api/admin/notifier/testwith no param.
The same via CLI:
curl -X POST \
-H "Authorization: Bearer wpat_…" \
http://pool.local:18334/api/admin/notifier/test?sink=ntfy
Web Push (PWA, VAPID — Phase 21)
In addition to the 5 server-side sinks above, there's background push straight to your phone via VAPID Web Push. Works even when the PWA is closed (iOS 16.4+, Android, desktop). No 3rd-party service required — push goes directly from the pool daemon to the browser push service (FCM/Mozilla/Apple).
Operator setup
# 1. Generate VAPID keys
dvb-warppool-cli gen-vapid-keys >> /etc/dvb-warppool/secrets.toml
# 2. Optional: set contact mailto (otherwise defaults to mailto:operator@localhost)
echo 'vapid_contact = "mailto:operator@example.org"' >> /etc/dvb-warppool/secrets.toml
# 3. Restart the daemon
systemctl restart dvb-warppool
Daemon log shows web-push sender ready. If not: VAPID keys weren't found
in secrets.toml — push stays disabled, other notifiers run anyway.
User subscribe flow
- Open the pool UI, log in
- Go to
/admin/notifications→ "Enable background push" button - Browser asks for permission → "Allow"
- Subscription is registered with the pool, from now on pushes arrive
Which events fire push
| Event | Tag | When |
|---|---|---|
block-found | block-found | Every block found (requireInteraction=true → notification stays until the user acknowledges it) |
health | health | RPC down OR health snapshot with warnings |
update | update | Pool update available (Phase 8e SSE event) |
Other events (SharesAccepted tick, NewJob, etc.) do NOT fire push — too spammy for background notifications.
iOS quirks
- Required: add the PWA to the home screen (Safari share menu → "Add to Home Screen"). In a regular Safari tab, iOS ignores Web Push.
- iOS 16.4+ is the minimum version (March 2023). On older iOS versions
the UI shows a
Browser unsupportedbadge.
Security note
The VAPID private key is sensitive — anyone holding it can impersonate your
pool to the push services. secrets.toml chmod 600. On suspected leak:
generate new keys + invalidate all subscriptions (a restart is enough —
stale subscriptions get deleted on the first 401 response).
Other Phase B options
- Matrix — not implemented; PR welcome, analogous to the Slack sink pattern.
- PagerDuty / Opsgenie — same; a generic webhook sink with HMAC signing would solve this without vendor lock-in.
See also
- Setup Health Checks — RPC-down/recovered are fired by the same health loop
- Observability — notifier counter
warppool_notifier_events_sent_total - Configuration Reference — all config.toml fields