Operator tools and monitoring scripts for DigiByte DigiDollar Oracle nodes.
Maintained by digibyte-maxi (Oracle Slot 17) β see contact at the bottom.
| File | Purpose |
|---|---|
| oracle-monitor.sh | Bash health monitor v2.5.4 β 12 checks (daemon, oracle, chain sync, peers, price freshness, consensus status, disk, memory, swap pressure, version, NTP, quorum margin). Quorum tracking via getdigidollardeploymentinfo + getoracles with MuSig2 session health. Counts online oracles by heartbeat (stable across round transitions). Anti-flap: cooldown timer + hysteresis buffer prevent alert spam during volatile periods. --config /path for dual-instance monitoring (testnet + mainnet). DigiDollar BIP9 pre-activation guard downgrades oracle checks to standby INFO before activation. Auto-detects either digibyted (headless) or digibyte-qt (Qt wallet) so operators running either binary get correct alerts. Discord webhook alerts with red/yellow/green embeds, NETWORK_LABEL in card titles, footer version stamp. External config file, --dry-run mode, jq-based JSON parsing. State files prevent repeat alerts. |
| oracle-network-status.sh | Gitter network status bot v1.5 β posts automated oracle network health summaries to the DigiDollar Gitter channel every 12 hours via Matrix API. Network label in header (auto-detected or config override). Reports: fresh heartbeats, quorum health, consensus price, MuSig2 session, BIP9 activation, last bundle signers, software version adoption, stale/inactive oracle list with @ mention notifications. --config /path flag for dual-instance monitoring (testnet + mainnet). Bot account: @digidollar-oracle-bot:matrix.org. |
| oracle-roster.template | Template for the oracle-to-Gitter-handle mapping file used by the @ mention feature. Copy to ~/.oracle-monitor/oracle-roster.conf and populate with real Matrix IDs. The populated file stays on VPS only β never push to GitHub. |
| config.template | Configuration template for oracle-monitor.sh and oracle-network-status.sh. Copy to ~/.oracle-monitor/config and set your oracle ID, webhook URL, alert thresholds, quorum margin thresholds, anti-flap settings, network label, and Matrix API credentials for the Gitter bot. Both scripts work without it using built-in defaults. |
| ORACLE_SETUP_QUICKSTART.md | Quick-start checklist for new oracle operators. Covers download, config, key generation, and posting to Gitter. |
| ORACLE_SETUP_TUTORIAL.md | Full step-by-step tutorial for all platforms (Linux, Windows, macOS). Posted by shenger in the DigiDollar Gitter community. |
| ORACLE_HARDENING_GUIDE.md | VPS security hardening guide v1.4.1 β SSH, UFW, Fail2Ban, kernel hardening, systemd, resource isolation and OOM protection. Step-by-step, based on my live oracle setup. |
| HOME_ORACLE_HARDENING_GUIDE.md | Home network security hardening guide β Linux, Windows, macOS. Three tiers (Essential, Recommended, Advanced). Covers firewall, port forwarding, NTP, router hardening, UPS, VLANs, WireGuard. Network diagrams: Tier 1 Β· Tier 2 Β· Tier 3. Community-requested by Aussie Epic. |
| oracle-monitor.ps1 | Windows PowerShell port v2.5.4-win.1 β full logic parity with Linux v2.5.4. PS 5.1 and PS 7 compatible, zero dependencies (native JSON parsing). Includes watch mode (-Watch) and -Config for dual-instance monitoring. Ships UTF-8 with BOM. |
| config.template.ps1 | Windows configuration template for oracle-monitor.ps1. |
| oracle-monitor-macos.sh | macOS port v2.5.4-macos.1 β stock bash 3.2 compatible, jq is the only dependency. Includes watch mode (--watch) and --config for dual-instance monitoring. |
| config-macos.template | macOS configuration template for oracle-monitor-macos.sh. |
| CROSS_PLATFORM_SETUP.md | Setup guide for Windows and macOS ports β installation, config, Task Scheduler/cron, watch mode, troubleshooting. |
The Windows and macOS ports ship with parallel isolated test harnesses for verifying check_daemon + check_services behavior on your box before scheduling the monitor. Nine scenarios each β auto-detect for headless vs Qt, override honored, service check appropriately skipped when Qt is the running daemon, and so on.
| Harness | Purpose |
|---|---|
| test-macos-daemon-services.sh | Mocks pgrep, launchctl, and $CLI β runs 9 scenarios in isolation. Verifies parity with the Linux logic before you point the monitor at a live oracle. |
| test-win-daemon-services.ps1 | Mocks Get-Process, Get-Service, and Invoke-DGBCli β runs 9 scenarios under Windows PowerShell 5.1 or 7. Verifies PS-specific behavior including auto-detect candidate loop and Windows Service Qt-skip. Ships UTF-8 with BOM. |
Neither harness sends Discord alerts, touches state files, or runs against a real node β they're safe to run on any box, even without DigiByte installed.
More tools will be added as the DigiDollar testnet matures toward mainnet activation. Roadmap: See open issues for planned features β mainnet migration, bundle signer detection, cross-platform support, and more.
The monitor runs natively on all three major platforms. Same 12 checks, same DigiDollar BIP9 pre-activation guard, same quorum state machine, same anti-flap logic, same Qt/headless auto-detect, same Discord card format β only the platform plumbing differs.
| Platform | Script | Config template | Version |
|---|---|---|---|
| Linux | oracle-monitor.sh |
config.template |
2.5.4 |
| Windows 10/11 | oracle-monitor.ps1 |
config.template.ps1 |
2.5.4-win.1 |
| macOS | oracle-monitor-macos.sh |
config-macos.template |
2.5.4-macos.1 |
Windows needs no dependencies at all (PowerShell parses JSON natively). macOS needs only jq and runs on the stock bash 3.2 every Mac ships with. Setup for both is in CROSS_PLATFORM_SETUP.md. The rest of this README documents the Linux version; the ports behave identically.
digibyteddaemon process alive (auto-detects headlessdigibytedor Qt walletdigibyte-qtβ configurable viaDAEMON_PROCESSoverride)- Oracle is
runninginlistoracle - Chain sync (
blocksvsheadersfromgetblockchaininfoβ alerts when the node falls more thanMAX_CHAIN_BEHINDblocks behind) - Peer count (default min: 3)
- Price freshness (
is_staleflag ongetoracleprice) - Degraded consensus detection (
status!=okongetoracleprice) - Disk space (default min: 5GB free)
- Memory usage
- Swap pressure β alerts when swap usage exceeds threshold (default 100 MB). On a properly tuned box with
swappiness=10, any meaningful swap usage signals real memory pressure before things get critical (v2.4) digibyted.serviceand oracle process status vialistoracleRPC β systemd unit check auto-skips with an INFO line when the Qt wallet is the running daemon (Qt operators typically run outside systemd)- Binary version drift detection via RPC (
getnetworkinfoβ.subversion) β works identically for Qt and headless (v2.5) - NTP time synchronization
- Quorum margin tracking β counts online oracles via
getoracles trueusingheartbeat_status(stable across MuSig2 round transitions, matches dashboard's "Online Heartbeats" metric), compares against on-chain quorum threshold fromgetdigidollardeploymentinfo, reports MuSig2 session health. Anti-flap: cooldown timer throttles recovery alerts during volatile periods, hysteresis buffer prevents oscillation at band boundaries
Before DigiDollar BIP9 activates on your target chain, the oracle RPCs (listoracle, getoracleprice, getoracles) return no data β the deployment simply isn't live yet. Without special handling, a monitor pointed at a mainnet node right now would fire red alerts every 5 minutes for oracle down, price unknown, and quorum unavailable, even though nothing is actually broken.
The v2.5+ monitors solve this with a pre-flight check. A check_digidollar_active function runs first on every pass, reads getdigidollardeploymentinfo for the current deployment status, and sets a DD_ACTIVE global that the four oracle-dependent checks (check_oracle, check_price, check_services, check_quorum) consult before deciding whether to alert.
When DD_ACTIVE=false, those four checks downgrade "no data" to a blue βΉοΈ standby INFO line instead of a red alert β showing something like βΉοΈ Oracle: standby (DigiDollar deployment: started) in the health summary. The other 8 checks (daemon, chain, peers, disk, memory, swap, service, NTP, version) continue to alert normally on real problems. Result: your Discord channel stays quiet until DigiDollar activates, then automatically switches to full oracle alerting once DD_ACTIVE=true.
This is why a pre-activation mainnet monitor shows an all-green health summary with four βΉοΈ standby lines β that's correct pre-activation behavior, not a bug. It flips to full oracle data automatically the moment BIP9 locks in.
Discord embeds β color-coded:
- π΄ Red β critical (daemon down, oracle stopped, chain stuck, quorum at edge or lost)
- π‘ Yellow β warnings (low peers, low disk, stale price, degraded consensus, NTP desync, quorum getting thin, swap pressure)
- π’ Green β recovery confirmations (quorum healthy, margin improving)
- π΅ Blue β 12-hour status summary, plus βΉοΈ INFO lines for pre-activation standby state
- Card titles carry the
NETWORK_LABELfrom your config on every alert β health summaries (Testnet26 Health Summary), individual checks (Mainnet β π΄ Node Down), and the--testalert β so dual-instance operators can tell which daemon fired an alert at a glance without opening the card (v2.5.3) - Footer stamps the monitor version and your oracle identity on every card (e.g.
Oracle Monitor v2.5.4 β digibyte-maxi (ID 17))
State files in ~/.oracle-monitor/ prevent the same alert firing every 5 minutes β you get notified once when something breaks and once again when it recovers. Quorum tracking uses a single quorum_state file that stores the current band and timestamp, with cooldown and hysteresis to prevent alert flapping during network volatility.
All timestamps inside alerts are in UTC for unambiguous reading across timezones. Discord's footer time auto-converts to each viewer's local time.
Health summary with quorum tracking and MuSig2 session status:
Quorum state transition alerts β red/yellow/green as oracle count changes:
Both images will be refreshed post-DigiDollar BIP9 mainnet activation β see issue #29. The current images still represent the day-to-day healthy-oracle state most operators see; the update after activation will capture the stable long-term post-activation mainnet cards.
- Linux (tested on Ubuntu 24.04 LTS) β for Windows and macOS, see Platform support above
- DigiByte Core v9.26.4 (also compatible with v9.26.2/v9.26.3 and RC44βRC46 β uses
listoracle,getoracleprice,getdigidollardeploymentinfo,getoraclesRPCs) jq(for JSON parsing β install withsudo apt install jq)curl- A Discord webhook URL β create one at: Server Settings β Integrations β Webhooks β New Webhook
- Download the script and config template to your oracle VPS:
wget https://raw.githubusercontent.com/BaumerCrypto/digidollar-oracle-tools/main/oracle-monitor.sh
wget https://raw.githubusercontent.com/BaumerCrypto/digidollar-oracle-tools/main/config.template
chmod +x oracle-monitor.sh- Create your config file from the template:
mkdir -p ~/.oracle-monitor
cp config.template ~/.oracle-monitor/config- Edit the config file with your settings:
nano ~/.oracle-monitor/configSet your Discord webhook URL, oracle ID, and oracle name. For mainnet, change CLI="digibyte-cli".
- Test with
--dry-run(runs all checks, prints to terminal, skips Discord):
./oracle-monitor.sh --dry-run- Test the webhook:
./oracle-monitor.sh --testYou should see a test alert appear in your Discord channel.
- Test a full health summary:
./oracle-monitor.sh --summary- Add to cron (
crontab -e):
*/5 * * * * $HOME/oracle-monitor.sh 2>/dev/null
0 */12 * * * $HOME/oracle-monitor.sh --summary 2>/dev/null| Flag | What it does |
|---|---|
| (none) | Normal health check β alerts only on problems or recovery |
--summary |
Full status summary β always sends to Discord |
--dry-run |
Runs all checks, prints to terminal, skips Discord, no state changes |
--test |
Sends a test embed to Discord to verify webhook |
--config /path |
Use alternate config file β enables dual-instance monitoring (v2.3+) |
All thresholds are configurable in ~/.oracle-monitor/config. The script uses built-in defaults if a value isn't set.
| Setting | Default | Description |
|---|---|---|
DISCORD_WEBHOOK |
(empty) | Discord webhook URL for alerts |
ORACLE_ID |
0 |
Your oracle slot ID |
ORACLE_NAME |
my-oracle |
Your oracle name (shown in Discord embeds) |
CLI |
digibyte-cli -testnet |
RPC command. Use digibyte-cli for mainnet |
WALLET_FLAG |
-rpcwallet=oracle |
Wallet flag for RPC calls |
MIN_PEERS |
3 |
Minimum peer count before alerting |
MIN_DISK_GB |
5 |
Minimum free disk space (GB) |
MEM_THRESHOLD |
90 |
Memory usage % above which to alert |
SWAP_THRESHOLD_MB |
100 |
Swap usage in MB above which to alert. On a swappiness=10 box, any meaningful swap means real pressure (v2.4) |
MAX_CHAIN_BEHIND |
10 |
Blocks behind before alerting |
QUORUM_GREEN |
12 |
Oracles reporting at/above this = healthy (no alert). Tuned in v2.5.1 β the old 20/12 defaults fired "getting thin" at 2x the 7-of-35 quorum floor. Testnet suggestion: 10 |
QUORUM_YELLOW |
10 |
Below green but at/above this = "getting thin" warning. Testnet suggestion: 8 |
QUORUM_COOLDOWN |
30 |
Minutes between quorum recovery alerts. Escalation (worse) always fires immediately. Set to 0 to disable (v2.1+) |
QUORUM_HYSTERESIS |
3 |
Recovery buffer β must exceed threshold by this many oracles to recover. Prevents flapping at boundaries. Set to 0 to disable (v2.1+) |
The quorum minimum (oracle_consensus_required, currently 7) comes from the chain itself via getdigidollardeploymentinfo β it's not configurable. Below that threshold, DigiDollar signing halts regardless of your config settings.
| Active oracles | Status | Escalation alert | Recovery alert |
|---|---|---|---|
| π’ 12+ | Comfortable | β | β
Quorum Healthy |
| π‘ 10β11 | Getting thin | β οΈ Quorum Getting Thin |
β
Quorum Improved β Getting Thin β Healthy |
| π΄ 7β9 | At quorum edge | π¨ Quorum at Edge |
β
Quorum Improved β At Edge β Getting Thin |
| π Below 7 | DD signing halted | π¨ QUORUM LOST |
β
Quorum Recovered β LOST β At Edge |
Escalation (count drops into a worse band) always fires immediately. Recovery (count rises into a better band) is throttled by QUORUM_COOLDOWN and requires the count to exceed the threshold by QUORUM_HYSTERESIS oracles. This prevents a single oracle bouncing around a boundary from generating a stream of alerts.
| Recovery to | Threshold | Required count |
|---|---|---|
| π’ Healthy | QUORUM_GREEN (12) |
12 + 3 = 15 |
| π‘ Getting thin | QUORUM_YELLOW (10) |
10 + 3 = 13 |
| π΄ At edge | oracle_consensus_required (7) |
7 + 3 = 10 |
With QUORUM_HYSTERESIS=0, recovery fires at the exact threshold (v2.0 behavior).
Both scripts parse specific fields from DigiByte Core RPCs. If a future RC renames a field, these scripts may need updates. Known field names as of RC46:
| RPC | Field used |
|---|---|
listoracle |
running (not is_running) |
listoracle |
price_usd (not last_price_usd) |
getoracleprice |
price_usd, is_stale, status, oracle_count |
getdigidollardeploymentinfo |
oracle_consensus_required, oracle_total_slots, musig2_session.state, musig2_session.epoch, musig2_session.nonce_count, musig2_session.partial_sig_count |
getoracles true |
last_price_usd, status, heartbeat_status (v2.2: "fresh" = online within 30 min), heartbeat_age_seconds, heartbeat_timestamp, software_version (used by oracle-network-status.sh) |
getblockchaininfo |
chain (used by oracle-network-status.sh v1.4 for network label auto-detection) |
getoraclesigners |
bundle_count, bundles[].height, bundles[].signer_count, bundles[].signer_ids (used by oracle-network-status.sh) |
RC45 new RPCs (not used by these scripts yet but available):
| RPC | Purpose |
|---|---|
exportoracleprivkey |
Export oracle signing key from wallet (wallet-context, usable before activation) |
importoracleprivkey |
Import oracle signing key into wallet (wallet-context, usable before activation) |
Community-facing Gitter bot that posts oracle network health summaries to the DigiDollar Gitter channel every 12 hours. Unlike oracle-monitor.sh (which watches your own node and alerts you privately via Discord), this script monitors the entire oracle network and reports publicly.
- Network label β which chain the report covers (e.g. "Testnet26" or "Mainnet"), auto-detected from
getblockchaininfoor set viaNETWORK_LABELin config (v1.4) - Fresh Heartbeats β active oracle count vs roster size, quorum health status (healthy / thin / critical / lost)
- Consensus price β current DGB/USD price and oracle price feed status
- MuSig2 session β current epoch, signing state, nonce and signature counts
- BIP9 activation β deployment status and signaling bit
- Last bundle β most recent on-chain price bundle block height and signer count
- Software versions β dominant version among active operators (β current vs π outdated during upgrades)
- Stale oracles (
β οΈ ) β were running, went down (liveness concern). Operators are @ mentioned in Gitter for up to 6 cycles (3 days), then suppressed but still listed. - Inactive oracles (β) β have key or wallet issues on this testnet. Same @ mention behavior as stale.
π’ Oracle Network Status β Testnet26 β 2026-06-21 23:25 UTC
Fresh Heartbeats: 25/35 (quorum healthy β threshold: 7)
Consensus price: $0.002718 (status: active)
MuSig2: epoch 1160, complete, 7/7 nonces, 7/7 sigs
BIP9: active (bit 23)
Last bundle: block 46399, signed by 7 oracles
Software:
β
v9.26.0rc46-g873d6d068... : 21 operators
β
v9.26.0rc46-873d6d068b9f : 2 operators
β οΈ Stale (8):
β ID 5 Ycagel
β ID 11 hallvardo @hallvardo:gitter.im
β ID 13 DigiByteForce @digibyteforce:gitter.im
β ID 22 LivingTheLife
β ID 23 ChozenOne43 @chozenone43:gitter.im
β ID 27 DennisPitallano
β ID 30 DigibyteDaily @dailydgb:gitter.im
β ID 32 3DogsKanab @3dogskanab:gitter.im
β Inactive (2):
β ID 31 Peer2Peer
β ID 34 Manu_DGB_oracle
| RPC | What it provides |
|---|---|
getblockchaininfo |
Chain identification β auto-detects "test" β Testnet, "main" β Mainnet for header label (v1.4) |
getoracles true |
Per-oracle heartbeat status β active, stale, and offline lists |
getoracleprice |
Consensus price, feed status, oracle count |
getdigidollardeploymentinfo |
BIP9 activation, quorum config, MuSig2 session state |
getoraclesigners 50 |
Recent bundle signer participation (50-block window covers at least one full 40-block round) |
- Linux (tested on Ubuntu 24.04 LTS)
- DigiByte Core v9.26.4 (also compatible with v9.26.2/v9.26.3 and RC44βRC46)
jq,curl- A Matrix bot account joined to
#digidollar:gitter.im
- Create a Matrix bot account at Element (e.g.
@digidollar-oracle-bot:matrix.org) - Join
#digidollar:gitter.imfrom the bot account - Generate an access token on the VPS:
curl -s -X POST "https://matrix.org/_matrix/client/v3/login" \
-H "Content-Type: application/json" \
-d '{"type":"m.login.password","identifier":{"type":"m.id.user","user":"YOUR_BOT_USERNAME"},"password":"YOUR_PASSWORD"}' \
| jq -r '.access_token'- Get the room ID (Element β Room Settings β Advanced β Internal room ID)
- Add to
~/.oracle-monitor/config:
MATRIX_ACCESS_TOKEN="your_token_here"
MATRIX_ROOM_ID="!your_room_id:gitter.im"- Set the network label (optional β auto-detected from chain if not set):
NETWORK_LABEL="Testnet26"- For @ mentions (optional): populate the roster mapping file:
wget https://raw.githubusercontent.com/BaumerCrypto/digidollar-oracle-tools/main/oracle-roster.template
cp oracle-roster.template ~/.oracle-monitor/oracle-roster.conf
nano ~/.oracle-monitor/oracle-roster.conf
# Fill in oracle ID to Gitter Matrix ID mappings β see template for format- Test:
./oracle-network-status.sh --dry-run - Test:
./oracle-network-status.sh --test - Test mentions:
./oracle-network-status.sh --test-mention - Add to cron:
5 */12 * * * /home/YOUR_USER/oracle-network-status.sh 2>/dev/null
| Flag | What it does |
|---|---|
| (none) | Collect data and post to Gitter |
--dry-run |
Collect data, print to terminal, skip Gitter post |
--test |
Send a test message to Gitter to verify Matrix API |
--test-mention |
Send a test @ mention to verify Gitter notifications work |
--config /path |
Use alternate config file β enables dual-instance monitoring (v1.4) |
When mainnet launches, you can run two independent instances from the same script using --config:
# Testnet (default config)
5 */12 * * * /home/YOUR_USER/oracle-network-status.sh 2>/dev/null
# Mainnet (custom config)
10 */12 * * * /home/YOUR_USER/oracle-network-status.sh --config ~/.oracle-monitor-mainnet/config 2>/dev/nullEach instance uses its own config file and tracks mention state independently. The roster file is shared by default (same 35 operators on both networks). Setup:
mkdir -p ~/.oracle-monitor-mainnet
cp ~/.oracle-monitor/config ~/.oracle-monitor-mainnet/config
# Edit mainnet config: CLI="digibyte-cli", NETWORK_LABEL="Mainnet"
ln -s ~/.oracle-monitor/oracle-roster.conf ~/.oracle-monitor-mainnet/oracle-roster.conf--config combines with action flags in any order: --config /path --dry-run or --dry-run --config /path.
This script is designed for a single designated community operator to post to the shared DigiDollar Gitter channel. Running a second instance against the same channel will create duplicate posts. If you want to monitor your own oracle, use oracle-monitor.sh with a Discord webhook to your private channel.
| Component | Version |
|---|---|
| OS | Linux (Ubuntu 24.04 LTS), Windows 10/11 (PowerShell 5.1+), macOS (bash 3.2+) |
| DigiByte Core | v9.26.4 (also compatible with v9.26.2, v9.26.3, and RC44/RC45/RC46) |
| Chain | testnet26 |
| Oracle protocol | v0x03 MuSig2 bundle |
| oracle-monitor.sh | v2.5.4 |
| oracle-monitor.ps1 | v2.5.4-win.1 |
| oracle-monitor-macos.sh | v2.5.4-macos.1 |
| oracle-network-status.sh | v1.5 |
If you're running a different release and something breaks, please open an issue.
Pull requests welcome. If you spot a bug, run into a field-name change on a newer RC, or want to add a check, open an issue or PR.
digibyte-maxi β DigiDollar oracle operator (Slot 17)
- GitHub: BaumerCrypto (display name: BaumerCrypto2.0)
- X/Twitter: @BaumerCrypto2_0
- Gitter:
digibyte-maxiin #digidollar
MIT β use, fork, modify, share. Credit appreciated but not required.
These scripts are provided as-is for the DigiByte community. The DigiDollar protocol is live on testnet26; mainnet activation is in progress via miner signaling (BIP9 bit 23, signaling window opened June 1, 2026). Always test on testnet first and back up your oracle wallet.

