2025-09-03 20:39:06 -04:00
2025-09-03 20:39:06 -04:00
2025-10-03 04:52:40 -04:00
2025-09-13 08:49:09 -04:00

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

  • NIP-01: Basic protocol flow implementation
  • NIP-09: Event deletion
  • NIP-11: Relay information document
  • NIP-13: Proof of Work
  • NIP-15: End of Stored Events Notice
  • NIP-20: Command Results
  • NIP-33: Parameterized Replaceable Events
  • NIP-40: Expiration Timestamp
  • NIP-42: Authentication of clients to relays
  • NIP-45: Counting results
  • NIP-50: Keywords filter
  • NIP-70: Protected Events

🌐 Web Admin Interface

C-Relay includes a built-in web-based administration interface accessible at http://localhost:8888/api/. The interface provides:

  • Real-time Configuration Management: View and edit all relay settings through a web UI
  • Database Statistics Dashboard: Monitor event counts, storage usage, and performance metrics
  • Auth Rules Management: Configure whitelist/blacklist rules for pubkeys
  • NIP-42 Authentication: Secure access using your Nostr identity
  • Event-Based Updates: All changes are applied as cryptographically signed Nostr events

The web interface serves embedded static files with no external dependencies and includes proper CORS headers for browser compatibility.

🔧 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:

{
  "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:

["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
stats_query ["stats_query"] Get comprehensive database statistics

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:

["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:

["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:

["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:

["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:

["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:

["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"
}]

Database Statistics Query Response:

["EVENT", "temp_sub_id", {
  "id": "response_event_id",
  "pubkey": "relay_public_key",
  "created_at": 1234567890,
  "kind": 23457,
  "content": "nip44 encrypted:{\"query_type\": \"stats_query\", \"timestamp\": 1234567890, \"database_size_bytes\": 1048576, \"total_events\": 15432, \"database_created_at\": 1234567800, \"latest_event_at\": 1234567890, \"event_kinds\": [{\"kind\": 1, \"count\": 12000, \"percentage\": 77.8}, {\"kind\": 0, \"count\": 2500, \"percentage\": 16.2}], \"time_stats\": {\"total\": 15432, \"last_24h\": 234, \"last_7d\": 1456, \"last_30d\": 5432}, \"top_pubkeys\": [{\"pubkey\": \"abc123...\", \"event_count\": 1234, \"percentage\": 8.0}, {\"pubkey\": \"def456...\", \"event_count\": 987, \"percentage\": 6.4}]}",
  "tags": [
    ["p", "admin_public_key"]
  ],
  "sig": "response_event_signature"
}]
Description
No description provided
Readme 255 MiB
v1.0.0 Latest
2025-11-01 11:03:39 +00:00
Languages
C 79.6%
JavaScript 13.4%
Shell 6%
CSS 0.5%
HTML 0.3%
Other 0.2%