Files
c-relay/docs/user_guide.md

15 KiB

C Nostr Relay - User Guide

Complete guide for deploying, configuring, and managing the C Nostr Relay with event-based configuration system.

Table of Contents

Quick Start

1. Build and Start

# Clone and build
git clone <repository-url>
cd c-relay
git submodule update --init --recursive
make

# Start relay (zero configuration needed)
./build/c_relay_x86

2. First Startup - Save Keys

The relay will display admin keys on first startup:

=================================================================
IMPORTANT: SAVE THIS ADMIN PRIVATE KEY SECURELY!
=================================================================
Admin Private Key: a018ecc259ff296ef7aaca6cdccbc52cf28104ac7a1f14c27b0b8232e5025ddc
Admin Public Key:  68394d08ab87f936a42ff2deb15a84fbdfbe0996ee0eb20cda064aae673285d1
=================================================================

⚠️ CRITICAL: Save the admin private key - it's needed for configuration updates and only shown once!

3. Connect Clients

Your relay is now available at:

  • WebSocket: ws://localhost:8888
  • NIP-11 Info: http://localhost:8888 (with Accept: application/nostr+json header)
  • Web Admin Interface: http://localhost:8888/api/ (serves embedded admin interface)

Installation

System Requirements

  • Operating System: Linux, macOS, or Windows (WSL)
  • RAM: Minimum 512MB, recommended 2GB+
  • Disk: 100MB for binary + database storage (grows with events)
  • Network: Port 8888 (configurable via events)

Dependencies

Install required libraries:

Ubuntu/Debian:

sudo apt update
sudo apt install build-essential git sqlite3 libsqlite3-dev libwebsockets-dev libssl-dev libsecp256k1-dev libcurl4-openssl-dev zlib1g-dev

CentOS/RHEL:

sudo yum install gcc git sqlite-devel libwebsockets-devel openssl-devel libsecp256k1-devel libcurl-devel zlib-devel

macOS (Homebrew):

brew install git sqlite libwebsockets openssl libsecp256k1 curl zlib

Building from Source

# Clone repository
git clone <repository-url>
cd c-relay

# Initialize submodules
git submodule update --init --recursive

# Build
make clean && make

# Verify build
ls -la build/c_relay_x86

Production Deployment

# Install as system service
sudo systemd/install-service.sh

# Start service
sudo systemctl start c-relay

# Enable auto-start
sudo systemctl enable c-relay

# Check status
sudo systemctl status c-relay

Manual Deployment

# Create dedicated user
sudo useradd --system --home-dir /opt/c-relay --shell /bin/false c-relay

# Install binary
sudo mkdir -p /opt/c-relay
sudo cp build/c_relay_x86 /opt/c-relay/
sudo chown -R c-relay:c-relay /opt/c-relay

# Run as service user
sudo -u c-relay /opt/c-relay/c_relay_x86

Configuration Management

Event-Based Configuration System

Unlike traditional relays that use config files, this relay stores all configuration as kind 33334 Nostr events in the database. This provides:

  • Real-time updates: Changes applied instantly without restart
  • Cryptographic security: All config changes must be signed by admin
  • Audit trail: Complete history of configuration changes
  • No file management: No config files to manage or version control

First-Time Configuration

On first startup, the relay:

  1. Generates keypairs: Creates cryptographically secure admin and relay keys
  2. Creates database: <relay_pubkey>.nrdb file with optimized schema
  3. Stores default config: Creates initial kind 33334 event with sensible defaults
  4. Displays admin key: Shows admin private key once for you to save

Updating Configuration

To change relay configuration, create and send a signed kind 33334 event:

# Install nostrtool
npm install -g nostrtool

# Update relay description
nostrtool event \
  --kind 33334 \
  --content "C Nostr Relay Configuration" \
  --tag d <relay_pubkey> \
  --tag relay_description "My Production Relay" \
  --tag max_subscriptions_per_client 50 \
  --private-key <admin_private_key> \
  | nostrtool send ws://localhost:8888

Manual Event Creation

{
  "kind": 33334,
  "content": "C Nostr Relay Configuration",
  "tags": [
    ["d", "<relay_pubkey>"],
    ["relay_description", "My Production Relay"],
    ["max_subscriptions_per_client", "50"],
    ["pow_min_difficulty", "20"]
  ],
  "created_at": 1699123456,
  "pubkey": "<admin_pubkey>",
  "id": "<computed_event_id>",
  "sig": "<signature>"
}

Send this to your relay via WebSocket, and changes are applied immediately.

Configuration Parameters

Basic Settings

Parameter Description Default Example
relay_description Relay description for NIP-11 "C Nostr Relay" "My awesome relay"
relay_contact Admin contact information "" "admin@example.com"
relay_software Software identifier "c-relay" "c-relay v1.0"

Client Limits

Parameter Description Default Range
max_subscriptions_per_client Max subscriptions per client "25" 1-100
max_total_subscriptions Total relay subscription limit "5000" 100-50000
max_message_length Maximum message size (bytes) "65536" 1024-1048576
max_event_tags Maximum tags per event "2000" 10-10000
max_content_length Maximum event content length "65536" 1-1048576

Proof of Work (NIP-13)

Parameter Description Default Options
pow_min_difficulty Minimum PoW difficulty "0" 0-40
pow_mode PoW validation mode "optional" "disabled", "optional", "required"

Event Expiration (NIP-40)

Parameter Description Default Options
nip40_expiration_enabled Enable expiration handling "true" "true", "false"
nip40_expiration_strict Strict expiration mode "false" "true", "false"
nip40_expiration_filter Filter expired events "true" "true", "false"
nip40_expiration_grace_period Grace period (seconds) "300" 0-86400

Web Admin Interface

The relay includes a built-in web-based administration interface that provides a user-friendly way to manage your relay without command-line tools.

Accessing the Interface

  1. Open your browser and navigate to: http://localhost:8888/api/
  2. Authenticate using your Nostr identity (the admin interface uses NIP-42 authentication)
  3. Manage configuration through the web interface

Features

  • Real-time Configuration: View and edit all relay settings
  • Database Statistics: Monitor event counts, storage usage, and performance metrics
  • Auth Rules Management: Configure whitelist/blacklist rules for pubkeys
  • Relay Connection Testing: Verify WebSocket connectivity and NIP-11 information
  • Event-Based Updates: All changes are applied as signed Nostr events

Security Notes

  • The web interface requires NIP-42 authentication with your admin pubkey
  • All configuration changes are cryptographically signed
  • The interface serves embedded static files (no external dependencies)
  • CORS headers are included for proper browser operation

Browser Compatibility

The admin interface works with modern browsers that support:

  • WebSocket connections
  • ES6 JavaScript features
  • Modern CSS Grid and Flexbox layouts

Administration

Viewing Current Configuration

# Find your database
ls -la *.nrdb

# View configuration events
sqlite3 <relay_pubkey>.nrdb "SELECT created_at, tags FROM events WHERE kind = 33334 ORDER BY created_at DESC LIMIT 1;"

# View all configuration history
sqlite3 <relay_pubkey>.nrdb "SELECT datetime(created_at, 'unixepoch') as date, tags FROM events WHERE kind = 33334 ORDER BY created_at DESC;"

Admin Key Management

Backup Admin Keys

# Create secure backup
echo "Admin Private Key: <your_admin_key>" > admin_keys_backup_$(date +%Y%m%d).txt
chmod 600 admin_keys_backup_*.txt

# Store in secure location (password manager, encrypted drive, etc.)

Key Recovery

If you lose your admin private key:

  1. Stop the relay: pkill c_relay or sudo systemctl stop c-relay
  2. Backup events: cp <relay_pubkey>.nrdb backup_$(date +%Y%m%d).nrdb
  3. Remove database: rm <relay_pubkey>.nrdb*
  4. Restart relay: This creates new database with new keys
  5. ⚠️ Note: All stored events and configuration history will be lost

Security Best Practices

Admin Key Security

  • Never share the admin private key
  • Store securely in password manager or encrypted storage
  • Backup safely to multiple secure locations
  • Monitor configuration changes in logs

Network Security

# Restrict access with firewall
sudo ufw allow 8888/tcp

# Use reverse proxy for HTTPS (recommended)
# Configure nginx/apache to proxy to ws://localhost:8888

Database Security

# Secure database file permissions
chmod 600 <relay_pubkey>.nrdb
chown c-relay:c-relay <relay_pubkey>.nrdb

# Regular backups
cp <relay_pubkey>.nrdb backup/relay_backup_$(date +%Y%m%d_%H%M%S).nrdb

Monitoring

Service Status

# Check if relay is running
ps aux | grep c_relay

# SystemD status
sudo systemctl status c-relay

# Network connections
netstat -tln | grep 8888
sudo ss -tlpn | grep 8888

Log Monitoring

# Real-time logs (systemd)
sudo journalctl -u c-relay -f

# Recent logs
sudo journalctl -u c-relay --since "1 hour ago"

# Error logs only
sudo journalctl -u c-relay -p err

# Configuration changes
sudo journalctl -u c-relay | grep "Configuration updated via kind 33334"

Database Analytics

# Connect to database
sqlite3 <relay_pubkey>.nrdb

# Event statistics
SELECT event_type, COUNT(*) as count FROM events GROUP BY event_type;

# Recent activity
SELECT datetime(created_at, 'unixepoch') as date, kind, LENGTH(content) as content_size 
FROM events 
ORDER BY created_at DESC 
LIMIT 10;

# Subscription analytics (if logging enabled)
SELECT * FROM subscription_analytics ORDER BY date DESC LIMIT 7;

# Configuration changes
SELECT datetime(created_at, 'unixepoch') as date, tags 
FROM configuration_events 
ORDER BY created_at DESC;

Performance Monitoring

# Database size
du -sh <relay_pubkey>.nrdb*

# Memory usage
ps aux | grep c_relay | awk '{print $6}' # RSS memory in KB

# Connection count (approximate)
netstat -an | grep :8888 | grep ESTABLISHED | wc -l

# System resources
top -p $(pgrep c_relay)

Troubleshooting

Common Issues

Relay Won't Start

# Check port availability
netstat -tln | grep 8888
# If port in use, find process: sudo lsof -i :8888

# Check binary permissions
ls -la build/c_relay_x86
chmod +x build/c_relay_x86

# Check dependencies
ldd build/c_relay_x86

Configuration Not Updating

  1. Verify signature: Ensure event is properly signed with admin private key
  2. Check admin pubkey: Must match the pubkey from first startup
  3. Validate event structure: Use nostrtool validate or similar
  4. Check logs: Look for validation errors in relay logs
  5. Test WebSocket: Ensure WebSocket connection is active
# Test WebSocket connection
wscat -c ws://localhost:8888

# Send test message
{"id":"test","method":"REQ","params":["test",{}]}

Database Issues

# Check database integrity
sqlite3 <relay_pubkey>.nrdb "PRAGMA integrity_check;"

# Check schema version
sqlite3 <relay_pubkey>.nrdb "SELECT * FROM schema_info WHERE key = 'version';"

# View database size and stats
sqlite3 <relay_pubkey>.nrdb "PRAGMA page_size; PRAGMA page_count;"

Performance Issues

# Analyze slow queries (if any)
sqlite3 <relay_pubkey>.nrdb "PRAGMA compile_options;"

# Check database optimization
sqlite3 <relay_pubkey>.nrdb "PRAGMA optimize;"

# Monitor system resources
iostat 1 5  # I/O statistics
free -h     # Memory usage

Recovery Procedures

Corrupted Database Recovery

# Attempt repair
sqlite3 <relay_pubkey>.nrdb ".recover" > recovered.sql
sqlite3 recovered.nrdb < recovered.sql

# If repair fails, start fresh (loses all events)
mv <relay_pubkey>.nrdb <relay_pubkey>.nrdb.corrupted
./build/c_relay_x86  # Creates new database

Lost Configuration Recovery

If configuration is lost but database is intact:

  1. Find old config: sqlite3 <relay_pubkey>.nrdb "SELECT * FROM configuration_events;"
  2. Create new config event: Use last known good configuration
  3. Sign and send: Update with current timestamp and new signature

Emergency Restart

# Quick restart with clean state
sudo systemctl stop c-relay
mv <relay_pubkey>.nrdb <relay_pubkey>.nrdb.backup
sudo systemctl start c-relay

# Check logs for new admin keys
sudo journalctl -u c-relay --since "5 minutes ago" | grep "Admin Private Key"

Advanced Usage

Custom Event Handlers

The relay supports custom handling for different event types. Configuration changes trigger:

  • Subscription Manager Updates: When client limits change
  • PoW System Reinitialization: When PoW settings change
  • Expiration System Updates: When NIP-40 settings change
  • Relay Info Updates: When NIP-11 information changes

API Integration

// Connect and send configuration update
const ws = new WebSocket('ws://localhost:8888');

ws.on('open', function() {
  const configEvent = {
    kind: 33334,
    content: "Updated configuration",
    tags: [
      ["d", relayPubkey],
      ["relay_description", "Updated via API"]
    ],
    created_at: Math.floor(Date.now() / 1000),
    pubkey: adminPubkey,
    // ... add id and sig
  };
  
  ws.send(JSON.stringify(["EVENT", configEvent]));
});

Backup Strategies

Automated Backup

#!/bin/bash
# backup-relay.sh
DATE=$(date +%Y%m%d_%H%M%S)
DB_FILE=$(ls *.nrdb | head -1)
BACKUP_DIR="/backup/c-relay"

mkdir -p $BACKUP_DIR
cp $DB_FILE $BACKUP_DIR/relay_backup_$DATE.nrdb
gzip $BACKUP_DIR/relay_backup_$DATE.nrdb

# Cleanup old backups (keep 30 days)
find $BACKUP_DIR -name "relay_backup_*.nrdb.gz" -mtime +30 -delete

Configuration Export

# Export configuration events
sqlite3 <relay_pubkey>.nrdb "SELECT json_object(
  'kind', kind,
  'content', content,
  'tags', json(tags),
  'created_at', created_at,
  'pubkey', pubkey,
  'sig', sig
) FROM events WHERE kind = 33334 ORDER BY created_at;" > config_backup.json

Migration Between Servers

# Source server
tar czf relay_migration.tar.gz *.nrdb* relay.log

# Target server  
tar xzf relay_migration.tar.gz
./build/c_relay_x86  # Will detect existing database and continue

This user guide provides comprehensive coverage of the C Nostr Relay's event-based configuration system. For additional technical details, see the developer documentation in the docs/ directory.