# 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.