Command Snippets
Quick reference for common Nostr operations using command-line tools.
Tools Setup
Install nak (Nostr Army Knife)
go install github.com/fiatjaf/nak@latest
Install websocat
cargo install websocat
# or via package manager
brew install websocat # macOS
apt install websocat # Debian/Ubuntu
Install jq
brew install jq # macOS
apt install jq # Debian/Ubuntu
Event Queries
Fetch Recent Notes
# Using nak
nak req -k 1 -l 10 wss://relay.damus.io
# Using websocat
echo '["REQ", "x", {"kinds": [1], "limit": 10}]' | \
websocat -n wss://relay.damus.io
Query by Author
# Get profile (kind 0)
nak req -k 0 -a <pubkey-hex> wss://relay.damus.io
# Get notes from author
nak req -k 1 -a <pubkey-hex> -l 20 wss://relay.damus.io
# Using websocat
echo '["REQ", "x", {"kinds": [1], "authors": ["<pubkey-hex>"], "limit": 20}]' | \
websocat -n wss://relay.damus.io
Get Follow List
# Kind 3 is follow list
nak req -k 3 -a <pubkey-hex> -l 1 wss://relay.damus.io
# Extract followed pubkeys
nak req -k 3 -a <pubkey-hex> -l 1 wss://relay.damus.io | \
jq -r '.tags[] | select(.[0]=="p") | .[1]'
Get Relay List (NIP-65)
nak req -k 10002 -a <pubkey-hex> -l 1 wss://relay.damus.io
# Extract relay URLs
nak req -k 10002 -a <pubkey-hex> wss://relay.damus.io | \
jq -r '.tags[] | select(.[0]=="r") | .[1]'
Search Notes
# If relay supports NIP-50 search
echo '["REQ", "x", {"kinds": [1], "search": "nostr", "limit": 20}]' | \
websocat -n wss://relay.nostr.band
Time-Bounded Query
# Events from last 24 hours
SINCE=$(($(date +%s) - 86400))
nak req -k 1 --since $SINCE -l 50 wss://relay.damus.io
# Events in date range
echo '["REQ", "x", {"kinds": [1], "since": 1700000000, "until": 1700100000}]' | \
websocat -n wss://relay.damus.io
Event Publishing
Publish a Note
# Interactive (will prompt for key)
nak event -c "Hello Nostr!" wss://relay.damus.io
# With private key
nak event -c "Hello Nostr!" --sec <privkey-hex> wss://relay.damus.io
# With reply
nak event -c "Great post!" \
-e <event-id> \
--sec <privkey-hex> \
wss://relay.damus.io
Publish Profile
nak event -k 0 \
-c '{"name":"alice","about":"Developer"}' \
--sec <privkey-hex> \
wss://relay.damus.io
Publish Follow List
nak event -k 3 \
-p <pubkey1> \
-p <pubkey2> \
-p <pubkey3> \
--sec <privkey-hex> \
wss://relay.damus.io
Delete Event
# Kind 5 deletion
nak event -k 5 \
-e <event-id-to-delete> \
--sec <privkey-hex> \
wss://relay.damus.io
Key Operations
Generate Keys
# Generate new keypair
nak key generate
# Output format
# Private key (hex): <64-char-hex>
# Public key (hex): <64-char-hex>
# nsec: <nsec1...>
# npub: <npub1...>
Convert Between Formats
# npub to hex
nak decode npub1...
# hex to npub
nak encode npub <hex>
# nsec to hex
nak decode nsec1...
# hex to nsec
nak encode nsec <hex>
Encode Note ID
# Event ID to note format
nak encode note <event-id-hex>
# Decode note to hex
nak decode note1...
Create NIP-19 Entities
# Create nprofile (pubkey + relays)
nak encode nprofile \
--pubkey <hex> \
--relay wss://relay.damus.io \
--relay wss://nos.lol
# Create nevent (event + relays)
nak encode nevent \
--id <event-id> \
--relay wss://relay.damus.io \
--author <pubkey>
# Create naddr (replaceable event address)
nak encode naddr \
--pubkey <hex> \
--kind 30023 \
--identifier "my-article" \
--relay wss://relay.damus.io
Relay Operations
Check Relay Info (NIP-11)
# Get relay information document
curl -s -H "Accept: application/nostr+json" https://relay.damus.io/ | jq
# Check supported NIPs
curl -s -H "Accept: application/nostr+json" https://relay.damus.io/ | \
jq '.supported_nips'
# Get relay name
curl -s -H "Accept: application/nostr+json" https://relay.damus.io/ | \
jq -r '.name'
Test Relay Connection
# Quick connectivity test
websocat -v wss://relay.damus.io/ 2>&1 | head -5
# Send ping and wait for response
echo '["REQ", "test", {"limit": 1}]' | \
timeout 5 websocat -n wss://relay.damus.io | head -1
Count Events (NIP-45)
# If relay supports COUNT
echo '["COUNT", "x", {"kinds": [1]}]' | \
websocat -n wss://relay.nostr.band
Monitor Live Events
# Stream all kind 1 events (firehose)
echo '["REQ", "stream", {"kinds": [1], "limit": 0}]' | \
websocat -n --ping-interval 30 wss://relay.damus.io
# Filter by hashtag
echo '["REQ", "stream", {"kinds": [1], "#t": ["nostr"], "limit": 0}]' | \
websocat -n --ping-interval 30 wss://relay.damus.io
Data Processing
Parse Event JSON
# Extract content from events
nak req -k 1 -l 5 wss://relay.damus.io | jq -r '.content'
# Get event IDs
nak req -k 1 -l 5 wss://relay.damus.io | jq -r '.id'
# Get created_at as date
nak req -k 1 -l 5 wss://relay.damus.io | \
jq -r '.created_at | todate'
Filter Events
# Events with images
nak req -k 1 -l 100 wss://relay.damus.io | \
jq 'select(.content | test("\\.(jpg|png|gif)"))'
# Events mentioning a pubkey
nak req -k 1 -l 100 wss://relay.damus.io | \
jq 'select(.tags[][] == "<pubkey>")'
Count by Kind
nak req -l 1000 wss://relay.damus.io | \
jq -s 'group_by(.kind) | map({kind: .[0].kind, count: length})'
Extract Tags
# Get all hashtags
nak req -k 1 -l 100 wss://relay.damus.io | \
jq -r '.tags[] | select(.[0]=="t") | .[1]' | \
sort | uniq -c | sort -rn
# Get all mentioned pubkeys
nak req -k 1 -l 100 wss://relay.damus.io | \
jq -r '.tags[] | select(.[0]=="p") | .[1]' | \
sort | uniq -c | sort -rn
Sync Operations
Export Events
# Export user's events to file
nak req -a <pubkey> wss://relay.damus.io > events.jsonl
# Export with specific kinds
nak req -k 0 -k 1 -k 3 -a <pubkey> wss://relay.damus.io > profile.jsonl
Import Events
# Publish events from file
cat events.jsonl | while read event; do
echo "[\"EVENT\", $event]" | websocat -n wss://destination-relay.com
sleep 0.1
done
Sync Relays
# Using nak sync (if available)
nak sync wss://source.com wss://dest.com \
--filter '{"authors": ["<pubkey>"]}'
# Using strfry
strfry sync wss://relay.damus.io --filter '{"kinds": [1]}'
Advanced Queries
Get Thread
# Get root event and all replies
ROOT_ID="<event-id>"
nak req -e $ROOT_ID wss://relay.damus.io
nak req --e-tag $ROOT_ID wss://relay.damus.io
Get Reactions
# Reactions to an event
nak req -k 7 --e-tag <event-id> wss://relay.damus.io
# Count likes
nak req -k 7 --e-tag <event-id> wss://relay.damus.io | \
jq -s 'map(select(.content == "+" or .content == "")) | length'
Get Zaps
# Zap receipts for an event
nak req -k 9735 --e-tag <event-id> wss://relay.damus.io
# Total zapped
nak req -k 9735 --e-tag <event-id> wss://relay.damus.io | \
jq -r '.tags[] | select(.[0]=="bolt11") | .[1]'
Get Reposts
# Kind 6 reposts
nak req -k 6 --e-tag <event-id> wss://relay.damus.io
Verification
Verify Event Signature
# nak automatically verifies, but to check manually:
nak verify < event.json
Check NIP-05
# Verify NIP-05 identifier
curl -s "https://example.com/.well-known/nostr.json?name=alice" | \
jq '.names.alice'
One-Liners
# Random relay from nostr.watch
curl -s https://api.nostr.watch/v1/online | jq -r '.[]' | shuf | head -1
# Latest note from pubkey
nak req -k 1 -a <pubkey> -l 1 wss://relay.damus.io | jq -r '.content'
# Who does this person follow?
nak req -k 3 -a <pubkey> wss://relay.damus.io | \
jq -r '.tags[] | select(.[0]=="p") | .[1]' | wc -l
# What relays does this person use?
nak req -k 10002 -a <pubkey> wss://relay.damus.io | \
jq -r '.tags[] | select(.[0]=="r") | "\(.[2] // "rw"): \(.[1])"'
# Search for notes about bitcoin today
SINCE=$(($(date +%s) - 86400))
echo '["REQ","x",{"kinds":[1],"search":"bitcoin","since":'$SINCE'}]' | \
websocat -n wss://relay.nostr.band | jq -r '.[2].content' | head -20
Environment Setup
# Add to ~/.bashrc or ~/.zshrc
# Default relay
export NOSTR_RELAY="wss://relay.damus.io"
# Your keys (be careful with nsec!)
export NOSTR_PUBKEY="<your-pubkey-hex>"
# Handy aliases
alias nostr-req="nak req"
alias nostr-pub="nak event"
alias nostr-info="curl -s -H 'Accept: application/nostr+json'"
# Quick note function
nostr-note() {
nak event -c "$1" --sec $NOSTR_PRIVKEY $NOSTR_RELAY
}