A simple Nostr relay and client implementation in Go with SQLite storage.
- Relay: The main Nostr relay server
- Publisher: Tool to publish events to relays
- Monitor: Tool to track database changes in real-time
- Forwarder: Tool to subscribe to external relays and forward events to your local relay
- Content Export: Tool to export event content from specific authors to text files
- Broadcast: Tool to broadcast a Nostr event to all online relays listed on nostr.watch
Build all components:
make all
Run the relay:
make run-relay
# or directly:
./bin/relay
Publish a note:
make run-publish-sample-events
# or with custom options:
./bin/publish-sample-events -relay ws://localhost:8080/ws -content "Hello, Nostr!" -kind 1
Monitor database changes:
make run-monitor
Forward events from other relays:
make run-fetch-and-publish-custom ARGS="-sources wss://relay.damus.io -target ws://localhost:8080/ws -kinds 1,4"
# or directly:
./bin/fetch-and-publish -sources wss://relay.damus.io -target ws://localhost:8080/ws -kinds 1,4
Export event content from a pubkey:
make run-export-content-custom PUBKEY=3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaef47fec
Broadcast an event to multiple relays:
make run-broadcast EVENT_ID=<event-id>
# or directly:
./bin/broadcast <event-id>
The relay supports several command-line options:
-port
: Port to run the relay on (default: 8080)-db
: Path to SQLite database (default: "nostr.db")-verbose
: Enable verbose logging of received events-v
: Short form for verbose logging-timeout
: WebSocket connection timeout in seconds (default: 0, no timeout)
Examples:
# Run with default settings
make run-relay
# Run with custom port
make run-relay-custom ARGS="-port 9000"
# Run with verbose logging
make run-relay-custom ARGS="-v"
# Run with custom database
make run-relay-custom ARGS="-db custom_nostr.db"
The forwarder supports several command-line options:
-sources
: Comma-separated list of source relay URLs to subscribe to-target
: Target relay URL to forward events to (default: "ws://localhost:8080/ws")-kinds
: Comma-separated list of event kinds to forward-pubkeys
: Comma-separated list of public keys to filter by (supports both hex and bech32/npub formats)-since
: Only forward events newer than this Unix timestamp (0 = no limit)-until
: Only forward events older than this Unix timestamp (0 = no limit)-limit
: Maximum number of events to request from each source relay-batch
: Number of events to forward in a batch (default: 10)-log
: Log event details when forwarding-discover
: Automatically discover relays using nostr.watch API-relays
: Number of relays to auto-discover (default: 10)-nip65
: Discover user's preferred relays from their NIP-65 (kind 10002) events
Examples:
# Forward events from specific authors
make run-fetch-and-publish-custom ARGS="-sources wss://relay.damus.io -pubkeys 3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"
# Forward events using NIP-65 relay discovery
make run-fetch-and-publish-custom ARGS="-nip65 -pubkeys npub1sn0wdenkukak0d9dfczzeacvhkrgz92ak56egt7vdgzn8pv2wfqqhrjdv9"
# Forward recent events (last 24 hours)
make run-fetch-and-publish-custom ARGS="-sources wss://relay.damus.io -since $(date -v-1d +%s)"
# Forward only reactions and metadata
make run-fetch-and-publish-custom ARGS="-sources wss://relay.damus.io -kinds 7,0"
# Forward from multiple relays with auto-discovery
make run-fetch-and-publish-custom ARGS="-discover -relays 20 -kinds 1,4 -log"
The broadcast tool sends a Nostr event to all online relays listed on nostr.watch.
# Broadcast an event by ID
make run-broadcast EVENT_ID=<event-id>
# Or directly
./bin/broadcast <event-id>
The tool:
- Retrieves the event from the local database by ID
- Fetches the list of online relays from nostr.watch
- Broadcasts the event concurrently to all relays
- Reports success/failure statistics
The content export tool supports several command-line options:
--pubkey
: (Required) The public key to filter events by--db
: Path to SQLite database (default: "nostr.db")--output
: Output file path (default: "<shortened_pubkey>.txt")--sort
: Sort order of events: 'asc' or 'desc' by creation time (default: "asc")--separator
: Separator between event contents (default: two newlines)
Examples:
# Export all content from a specific pubkey
make run-export-content-custom PUBKEY=3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaef47fec
# Export in reverse chronological order to a specific file
make run-export-content-custom PUBKEY=3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaef47fec ARGS="--sort desc --output my_export.txt"
The monitor tool tracks changes to the database in real-time:
# Run the monitor
make run-monitor
# Run with custom options
make run-monitor-custom ARGS="-db custom_nostr.db -kinds 1,4"
Run the tests:
# Run core relay tests
make test
# Run all tests including integration tests
make test-all
cmd/
: Command-line applicationsrelay/
: Main relay serverbroadcast/
: Event broadcasting toolexport-content/
: Content export toolfetch-and-publish/
: Event forwarding toolmonitor/
: Database monitoring toolpublish-sample-events/
: Event publishing tool
relay/
: Core relay implementationclient/
: Client library for Nostr protocollib/
: Shared librariescrypto/
: Cryptographic operationsutils/
: Utility functions
test/
: Integration tests