mirror of
https://github.com/privkeyio/whisper.git
synced 2026-10-23 16:14:09 +00:00
Encrypted Nostr DM pipe (NIP-17 + NIP-44) with a Unix-style CLI and TUI
- C 85.9%
- Nix 7.3%
- Makefile 6.3%
- Shell 0.5%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .github/workflows | ||
| .gitignore | ||
| flake.lock | ||
| flake.nix | ||
| LICENSE | ||
| main.c | ||
| Makefile | ||
| README.md | ||
| recv.c | ||
| send.c | ||
| test_util.c | ||
| tui.c | ||
| tui.h | ||
| util.c | ||
| whisper.h | ||
| whisper.sh | ||
whisper
Encrypted DM pipe for Nostr using NIP-17 + NIP-44. Unix-style CLI for private messaging.
# Send encrypted DM (using keep vault)
echo "secret message" | whisper send --to npub1... --keep-key main --relay wss://relay.damus.io
# Receive encrypted DMs
whisper recv --keep-key main --relay wss://relay.damus.io
# Interactive TUI
whisper tui --keep-key main --relay wss://relay.damus.io --to npub1...
Install
Nix (recommended)
# Run directly
nix run github:privkeyio/whisper -- send --to npub1... --relay wss://...
# Or install
nix profile install github:privkeyio/whisper
# Dev shell
nix develop github:privkeyio/whisper
Manual Build
1. Build Dependencies
# Build libnostr-c with relay and NIP-17 support
cd ../libnostr-c/build
cmake .. -DNOSTR_FEATURE_NIP17=ON -DNOSTR_FEATURE_RELAY=ON
make
2. Build whisper
make
3. Set Up Your Key
Option A: Use keep (recommended)
# Install keep: https://github.com/privkeyio/keep
keep init
keep generate --name main
Option B: Manual key file
mkdir -p ~/.config/whisper && chmod 700 ~/.config/whisper
echo "nsec1..." > ~/.config/whisper/nsec && chmod 600 ~/.config/whisper/nsec
4. Send a Message
# Using keep vault (recommended)
echo "hey!" | whisper send --to npub1... --keep-key main --relay wss://relay.damus.io
# Using key file
echo "hey!" | whisper send --to npub1... --nsec-file ~/.config/whisper/nsec --relay wss://relay.damus.io
5. Receive Messages
# Stream incoming DMs
whisper recv --keep-key main --relay wss://relay.damus.io
# Get last 10 messages as JSON
whisper recv --keep-key main --relay wss://relay.damus.io --limit 10 --json
Usage
whisper - Encrypted Nostr DMs (NIP-17)
Usage:
whisper send --to <npub> --relay <url> [key options]
whisper recv --relay <url> [key options]
whisper tui --relay <url> [--to <npub>] [key options]
Key options (in order of priority):
--keep-key <name> Use key from keep vault (recommended)
--nsec-file <path> Read key from file
--nsec <nsec|hex> Key as argument (visible in history)
NOSTR_NSEC env var Fallback if no key option
Send options:
--to <npub|hex> Recipient public key
--relay <url> Relay URL
--subject <text> Optional subject
--timeout <ms> Timeout (default: 5000)
Recv options:
--relay <url> Relay URL
--since <timestamp> Only messages after timestamp
--limit <n> Max messages (0 = stream)
--json Output JSON format
--timeout <ms> Timeout (default: 5000)
TUI options:
--relay <url> Relay URL
--to <npub|hex> Initial recipient (can change with /to)
TUI commands:
/to <npub> Set recipient
/clear Clear messages
/quit Exit TUI
/help Show commands
TUI keys:
Enter Send message
Ctrl+Q Quit
PgUp/PgDn Scroll messages
Security
Key Protection:
- Use
--keep-keywith keep vault (recommended) - Or
--nsec-fileto avoid keys in shell history - Keys are wiped from memory using
secure_wipe()before exit - Environment variable
NOSTR_NSECas fallback (visible to child processes)
Protocol:
- NIP-17: Private Direct Messages (triple-wrapped)
- NIP-44: Modern encryption (XChaCha20-Poly1305)
- NIP-59: Gift Wrap (ephemeral sender key)
Messages are encrypted and wrapped so relays cannot read content or see the real sender.
Exit Codes
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Invalid arguments |
| 2 | Key parsing error |
| 3 | Relay connection failed |
| 4 | Encryption/decryption failed |
| 5 | Timeout |
Examples
# Send secret to a friend (using keep vault)
echo "meet at the usual spot, 9pm" | whisper send \
--to npub1friend... \
--keep-key main \
--relay wss://relay.damus.io
# Pipe from another command
cat secret.txt | whisper send --to npub1... --keep-key main --relay wss://relay.damus.io
# Monitor inbox continuously
whisper recv --keep-key main --relay wss://relay.damus.io | tee inbox.log
# Export messages as JSON for processing
whisper recv --keep-key main --relay wss://relay.damus.io --limit 100 --json > messages.json
# Without keep (using env var)
export NOSTR_NSEC=nsec1...
echo "hello" | whisper send --to npub1... --relay wss://relay.damus.io
Building from Source
Prerequisites
- libnostr-c (with NIP-17 and relay features)
- libwebsockets
- libcjson
- libsecp256k1
- noscrypt
- OpenSSL
- notcurses (optional, for TUI mode)
Compile
# Standard build
make
# With custom libnostr-c path
LIBNOSTR_DIR=/path/to/libnostr-c make
License
MIT