VIBECODED FOR NOW. manual intervention forthcoming.
Send and receive encrypted notifications over Nostr using simple bash scripts powered by nak.
nstrfy.sh is a lightweight, bash-based notification system that uses the Nostr protocol for decentralized, end-to-end encrypted notifications. It's perfect for server monitoring, CI/CD alerts, backup notifications, and any scenario where you need reliable push notifications without centralized infrastructure.
- End-to-end encrypted using NIP-44
- Decentralized - uses public Nostr relays
- Zero dependencies except
nakandjq - Simple CLI - works like
curlorntfy - Priority levels - urgent, high, default, low, min
- Topics and tags - organize your notifications
- $0 infrastructure cost - no servers needed
./nstrfy.sh generate
β nak found: /opt/homebrew/bin/nak
βΉ Generating new private key...
β Key generated!
Private key (hex): e9279cf0e7f49246861f93f460cc63d7076fe26a3d4d32b3ccfe4959ee696e06
Public key (hex): cf0c3edb6ef6c01ca4f519c207f82dbfe9ab7b59b6d8a6dbf82b3e2089c7c535
Public key (npub): npub1euxrakmw7mqpef84r8pq07pdhl56k76ekmv2dklc9vlzpzw8c56skl3r04
./nstrfy.sh listen --key e9279cf0e7f49246861f93f460cc63d7076fe26a3d4d32b3ccfe4959ee696e06
./nstrfy.sh send --to npub1euxrakmw7mqpef84r8pq07pdhl56k76ekmv2dklc9vlzpzw8c56skl3r04 --title "NoTiFiCaTiOns" --message "Hey you should read this" --priority normal
# Install nak (Nostr Army Knife)
go install github.com/fiatjaf/nak@latest
# Install jq (JSON processor)
brew install jq # macOS
# or
apt install jq # Linux./nstrfy.sh generate
# Output:
# Private key (hex): d3d3c043fced10f33dd3dcd8eedc4aa96021200fa3a994af057452d94861f14b
# Public key (hex): 4b39fbe6174dea5ad1454d75d618c1603e52f80d1d4c01fde06cc2ccfd42c48b
# Public key (npub): npub1fvulheshfh494529f46avxxpvql997qdr4xqrl0qdnpvel2zcj9slg55al
# Save your private key securely!# In terminal 1
./nstrfy.sh listen --key <your_private_key_hex># In terminal 2
./nstrfy.sh send \
--to npub1... \
--title "Server Alert" \
--message "CPU usage is at 95%" \
--priority urgent \
--topic monitoringGenerate a new keypair:
./nstrfy.sh generateSend a notification:
./nstrfy.sh send \
--to <npub|hex> # Recipient's public key (required)
--title <text> # Notification title (required)
--message <text> # Notification message (required)
--priority <level> # urgent|high|default|low|min (default: default)
--topic <text> # Notification topic/category
--tags <tag1,tag2> # Comma-separated tags
--key <hex> # Sender's private key (generates ephemeral if omitted)
--relays <urls> # Comma-separated relay URLsListen for incoming notifications:
./nstrfy.sh listen \
--key <hex> # Your private key (required)
--relays <urls> # Comma-separated relay URLs#!/bin/bash
RECIPIENT="npub1your_npub..."
# Check CPU usage
CPU=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
if (( $(echo "$CPU > 90" | bc -l) )); then
./nstrfy.sh send \
--to "$RECIPIENT" \
--title "High CPU Usage" \
--message "CPU usage is at ${CPU}%" \
--priority urgent \
--topic monitoring
fi#!/bin/bash
RECIPIENT="npub1your_npub..."
if ./run-backup.sh; then
./nstrfy.sh send \
--to "$RECIPIENT" \
--title "Backup Complete" \
--message "Daily backup completed successfully" \
--priority low \
--tags "backup,success"
else
./nstrfy.sh send \
--to "$RECIPIENT" \
--title "Backup Failed" \
--message "Daily backup failed - check logs" \
--priority urgent \
--tags "backup,failure"
fi# GitHub Actions
- name: Notify deployment
if: always()
run: |
./nstrfy.sh send \
--to ${{ secrets.NOSTR_RECIPIENT }} \
--title "Deployment ${{ job.status }}" \
--message "Version ${{ github.sha }} deployed to production" \
--priority high \
--topic deployments# Daily report at 8 AM
0 8 * * * /usr/local/bin/nstrfy.sh send --to npub1... --title "Daily Report" --message "All systems operational"
# Check website every 5 minutes
*/5 * * * * curl -s https://mysite.com > /dev/null || /usr/local/bin/nstrfy.sh send --to npub1... --priority urgent --title "Website Down" --message "Site is not responding"By default, the script uses these public Nostr relays:
wss://relay.damus.iowss://nos.lolwss://relay.nostr.band
You can override with the --relays flag.
- Sender creates a JSON notification payload with title, message, priority, etc.
- Encryption happens using NIP-44 (modern, secure encryption standard)
- Publishing sends the encrypted event (kind 30078) to Nostr relays
- Receiver subscribes to events tagged with their public key
- Decryption happens automatically when notifications arrive
- Display shows the notification with formatting based on priority
This tool implements a draft NIP (Nostr Implementation Possibility) for encrypted notifications. See NIP-DRAFT.md for the full specification.
Key Details:
- Event Kind:
30078(parameterized replaceable) - Encryption: NIP-44 (NIP-04 is deprecated/broken in nak)
- Tags:
p(recipient pubkey),d(unique ID) - Content: Encrypted JSON with version, title, message, priority, etc.
| Feature | ntfy | nstrfy.sh |
|---|---|---|
| Architecture | Centralized | Decentralized |
| Encryption | Optional | Always E2E |
| Infrastructure | Self-host required | Free relays |
| Censorship | Can be blocked | Resistant |
| Privacy | Server sees metadata | Fully encrypted |
| Cost | Server/hosting costs | $0 |
| Installation | Server setup | Single script |
- End-to-end encryption: All notifications are encrypted with NIP-44
- No metadata leakage: Message content is never visible to relays
- Ephemeral keys: Optional anonymous sending with auto-generated keys
- Persistent keys: Optional authenticated notifications with reusable keys
- Key storage: Keep your private keys secure (
chmod 600)
You can receive notifications in multiple ways:
- Bash script (this project) - Terminal-based listener
- Web app - Browser-based receiver with desktop notifications
- Android app - Native mobile app with background service
- Custom client - Build your own using the NIP specification
- Check your private key is correct
- Verify relays are accessible
- Ensure listener is running
- Try with
-vflag for verbose output
This tool uses NIP-44 because NIP-04 is broken in nak 0.16.1. The web and Android clients have been updated to support both.
- Grant notification permission when prompted
- Check browser settings allow notifications for localhost
- Some browsers block notifications on HTTP (use HTTPS or localhost)
Contributions welcome! This is a simple bash script that can be extended with:
- Action buttons (HTTP callbacks)
- Image/icon support
- Delivery receipts
- Multi-recipient support
- Config file support
MIT
- nak - Nostr Army Knife CLI tool
- nostr-tools - JavaScript Nostr library
- Nostr Protocol - Main protocol repo
- ntfy - Centralized notification service (inspiration)
Built with:
- nak by @fiatjaf - Nostr CLI Swiss Army knife
- Nostr Protocol - Decentralized social protocol
- Inspired by ntfy - Simple notification service
- π Issues: GitHub Issues
- π¬ Questions: GitHub Discussions
- π Docs: This README and NIP-DRAFT.md