541 lines
15 KiB
Markdown
541 lines
15 KiB
Markdown
# 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](#quick-start)
|
|
- [Installation](#installation)
|
|
- [Web Admin Interface](#web-admin-interface)
|
|
- [Configuration Management](#configuration-management)
|
|
- [Administration](#administration)
|
|
- [Monitoring](#monitoring)
|
|
- [Troubleshooting](#troubleshooting)
|
|
- [Advanced Usage](#advanced-usage)
|
|
|
|
## Quick Start
|
|
|
|
### 1. Build and Start
|
|
```bash
|
|
# 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:**
|
|
```bash
|
|
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:**
|
|
```bash
|
|
sudo yum install gcc git sqlite-devel libwebsockets-devel openssl-devel libsecp256k1-devel libcurl-devel zlib-devel
|
|
```
|
|
|
|
**macOS (Homebrew):**
|
|
```bash
|
|
brew install git sqlite libwebsockets openssl libsecp256k1 curl zlib
|
|
```
|
|
|
|
### Building from Source
|
|
```bash
|
|
# 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
|
|
|
|
#### SystemD Service (Recommended)
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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:
|
|
|
|
#### Using nostrtool (recommended)
|
|
```bash
|
|
# 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
|
|
```json
|
|
{
|
|
"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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# Test WebSocket connection
|
|
wscat -c ws://localhost:8888
|
|
|
|
# Send test message
|
|
{"id":"test","method":"REQ","params":["test",{}]}
|
|
```
|
|
|
|
#### Database Issues
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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
|
|
```javascript
|
|
// 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
|
|
```bash
|
|
#!/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
|
|
```bash
|
|
# 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
|
|
```bash
|
|
# 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. |