# C Nostr Relay - Event-Based Configuration System A high-performance Nostr relay implemented in C with SQLite backend, featuring a revolutionary **zero-configuration** approach using event-based configuration management. ## 📜 Supported NIPs - [x] NIP-01: Basic protocol flow implementation - [x] NIP-09: Event deletion - [x] NIP-11: Relay information document - [x] NIP-13: Proof of Work - [x] NIP-15: End of Stored Events Notice - [x] NIP-20: Command Results - [x] NIP-33: Parameterized Replaceable Events - [x] NIP-40: Expiration Timestamp - [x] NIP-42: Authentication of clients to relays - [x] NIP-45: Counting results - [ ] NIP-50: Keywords filter - [ ] NIP-70: Protected Events ## 🔧 Administrator API C-Relay uses an innovative **event-based administration system** where all configuration and management commands are sent as signed Nostr events using the admin private key generated during first startup. All admin commands use **NIP-44 encrypted command arrays** for security and compatibility. ### Authentication All admin commands require signing with the admin private key displayed during first-time startup. **Save this key securely** - it cannot be recovered and is needed for all administrative operations. ### Event Structure All admin commands use the same unified event structure with NIP-44 encrypted content: **Admin Command Event:** ```json { "id": "event_id", "pubkey": "admin_public_key", "created_at": 1234567890, "kind": 23456, "content": "AqHBUgcM7dXFYLQuDVzGwMST1G8jtWYyVvYxXhVGEu4nAb4LVw...", "tags": [ ["p", "relay_public_key"] ], "sig": "event_signature" } ``` The `content` field contains a NIP-44 encrypted JSON array representing the command. **Admin Response Event:** ```json ["EVENT", "temp_sub_id", { "id": "response_event_id", "pubkey": "relay_public_key", "created_at": 1234567890, "kind": 23457, "content": "BpKCVhfN8eYtRmPqSvWxZnMkL2gHjUiOp3rTyEwQaS5dFg...", "tags": [ ["p", "admin_public_key"] ], "sig": "response_event_signature" }] ``` The `content` field contains a NIP-44 encrypted JSON response object. ### Admin Commands All commands are sent as NIP-44 encrypted JSON arrays in the event content. The following table lists all available commands: | Command Type | Command Format | Description | |--------------|----------------|-------------| | **Configuration Management** | | `config_update` | `["config_update", [{"key": "auth_enabled", "value": "true", "data_type": "boolean", "category": "auth"}, {"key": "relay_description", "value": "My Relay", "data_type": "string", "category": "relay"}, ...]]` | Update relay configuration parameters (supports multiple updates) | | `config_query` | `["config_query", "all"]` | Query all configuration parameters | | **Auth Rules Management** | | `auth_add_blacklist` | `["blacklist", "pubkey", "abc123..."]` | Add pubkey to blacklist | | `auth_add_whitelist` | `["whitelist", "pubkey", "def456..."]` | Add pubkey to whitelist | | `auth_delete_rule` | `["delete_auth_rule", "blacklist", "pubkey", "abc123..."]` | Delete specific auth rule | | `auth_query_all` | `["auth_query", "all"]` | Query all auth rules | | `auth_query_type` | `["auth_query", "whitelist"]` | Query specific rule type | | `auth_query_pattern` | `["auth_query", "pattern", "abc123..."]` | Query specific pattern | | **System Commands** | | `system_clear_auth` | `["system_command", "clear_all_auth_rules"]` | Clear all auth rules | | `system_status` | `["system_command", "system_status"]` | Get system status | ### Available Configuration Keys **Basic Relay Settings:** - `relay_name`: Relay name (displayed in NIP-11) - `relay_description`: Relay description text - `relay_contact`: Contact information - `relay_software`: Software URL - `relay_version`: Software version - `supported_nips`: Comma-separated list of supported NIP numbers (e.g., "1,2,4,9,11,12,13,15,16,20,22,33,40,42") - `language_tags`: Comma-separated list of supported language tags (e.g., "en,es,fr" or "*" for all) - `relay_countries`: Comma-separated list of supported country codes (e.g., "US,CA,MX" or "*" for all) - `posting_policy`: Posting policy URL or text - `payments_url`: Payment URL for premium features - `max_connections`: Maximum concurrent connections - `max_subscriptions_per_client`: Max subscriptions per client - `max_event_tags`: Maximum tags per event - `max_content_length`: Maximum event content length **Authentication & Access Control:** - `auth_enabled`: Enable whitelist/blacklist auth rules (`true`/`false`) - `nip42_auth_required`: Enable NIP-42 cryptographic authentication (`true`/`false`) - `nip42_auth_required_kinds`: Event kinds requiring NIP-42 auth (comma-separated) - `nip42_challenge_timeout`: NIP-42 challenge expiration seconds **Proof of Work & Validation:** - `pow_min_difficulty`: Minimum proof-of-work difficulty - `nip40_expiration_enabled`: Enable event expiration (`true`/`false`) ### Dynamic Configuration Updates C-Relay supports **dynamic configuration updates** without requiring a restart for most settings. Configuration parameters are categorized as either **dynamic** (can be updated immediately) or **restart-required** (require relay restart to take effect). **Dynamic Configuration Parameters (No Restart Required):** - All relay information (NIP-11) settings: `relay_name`, `relay_description`, `relay_contact`, `relay_software`, `relay_version`, `supported_nips`, `language_tags`, `relay_countries`, `posting_policy`, `payments_url` - Authentication settings: `auth_enabled`, `nip42_auth_required`, `nip42_auth_required_kinds`, `nip42_challenge_timeout` - Subscription limits: `max_subscriptions_per_client`, `max_total_subscriptions` - Event validation limits: `max_event_tags`, `max_content_length`, `max_message_length` - Proof of Work settings: `pow_min_difficulty`, `pow_mode` - Event expiration settings: `nip40_expiration_enabled`, `nip40_expiration_strict`, `nip40_expiration_filter`, `nip40_expiration_grace_period` **Restart-Required Configuration Parameters:** - Connection settings: `max_connections`, `relay_port` - Database and core system settings When updating configuration, the admin API response will indicate whether a restart is required for each parameter. Dynamic updates take effect immediately and are reflected in NIP-11 relay information documents without restart. ### Response Format All admin commands return **signed EVENT responses** via WebSocket following standard Nostr protocol. Responses use JSON content with structured data. #### Response Examples **Success Response:** ```json ["EVENT", "temp_sub_id", { "id": "response_event_id", "pubkey": "relay_public_key", "created_at": 1234567890, "kind": 23457, "content": "nip44 encrypted:{\"query_type\": \"config_update\", \"status\": \"success\", \"message\": \"Operation completed successfully\", \"timestamp\": 1234567890}", "tags": [ ["p", "admin_public_key"] ], "sig": "response_event_signature" }] ``` **Error Response:** ```json ["EVENT", "temp_sub_id", { "id": "response_event_id", "pubkey": "relay_public_key", "created_at": 1234567890, "kind": 23457, "content": "nip44 encrypted:{\"query_type\": \"config_update\", \"status\": \"error\", \"error\": \"invalid configuration value\", \"timestamp\": 1234567890}", "tags": [ ["p", "admin_public_key"] ], "sig": "response_event_signature" }] ``` **Auth Rules Query Response:** ```json ["EVENT", "temp_sub_id", { "id": "response_event_id", "pubkey": "relay_public_key", "created_at": 1234567890, "kind": 23457, "content": "nip44 encrypted:{\"query_type\": \"auth_rules_all\", \"total_results\": 2, \"timestamp\": 1234567890, \"data\": [{\"rule_type\": \"blacklist\", \"pattern_type\": \"pubkey\", \"pattern_value\": \"abc123...\", \"action\": \"allow\"}]}", "tags": [ ["p", "admin_public_key"] ], "sig": "response_event_signature" }] ``` **Configuration Query Response:** ```json ["EVENT", "temp_sub_id", { "id": "response_event_id", "pubkey": "relay_public_key", "created_at": 1234567890, "kind": 23457, "content": "nip44 encrypted:{\"query_type\": \"config_all\", \"total_results\": 27, \"timestamp\": 1234567890, \"data\": [{\"key\": \"auth_enabled\", \"value\": \"false\", \"data_type\": \"boolean\", \"category\": \"auth\", \"description\": \"Enable NIP-42 authentication\"}, {\"key\": \"relay_description\", \"value\": \"My Relay\", \"data_type\": \"string\", \"category\": \"relay\", \"description\": \"Relay description text\"}]}", "tags": [ ["p", "admin_public_key"] ], "sig": "response_event_signature" }] ``` **Configuration Update Success Response:** ```json ["EVENT", "temp_sub_id", { "id": "response_event_id", "pubkey": "relay_public_key", "created_at": 1234567890, "kind": 23457, "content": "nip44 encrypted:{\"query_type\": \"config_update\", \"total_results\": 2, \"timestamp\": 1234567890, \"status\": \"success\", \"data\": [{\"key\": \"auth_enabled\", \"value\": \"true\", \"status\": \"updated\"}, {\"key\": \"relay_description\", \"value\": \"My Updated Relay\", \"status\": \"updated\"}]}", "tags": [ ["p", "admin_public_key"] ], "sig": "response_event_signature" }] ``` **Configuration Update Error Response:** ```json ["EVENT", "temp_sub_id", { "id": "response_event_id", "pubkey": "relay_public_key", "created_at": 1234567890, "kind": 23457, "content": "nip44 encrypted:{\"query_type\": \"config_update\", \"status\": \"error\", \"error\": \"field validation failed: invalid port number '99999' (must be 1-65535)\", \"timestamp\": 1234567890}", "tags": [ ["p", "admin_public_key"] ], "sig": "response_event_signature" }] ```