# C Nostr Relay Database This directory contains the SQLite database schema and initialization scripts for the C Nostr Relay implementation. ## Files - **`schema.sql`** - Complete database schema based on nostr-rs-relay v18 - **`init.sh`** - Database initialization script - **`c_nostr_relay.db`** - SQLite database file (created after running init.sh) ## Quick Start 1. **Initialize the database:** ```bash cd db ./init.sh ``` 2. **Force reinitialize (removes existing database):** ```bash ./init.sh --force ``` 3. **Initialize with optimization and info:** ```bash ./init.sh --info --optimize ``` ## Database Schema The schema is fully compatible with the Nostr protocol and includes: ### Core Tables - **`event`** - Main event storage with all Nostr event data - **`tag`** - Denormalized tag index for efficient queries - **`user_verification`** - NIP-05 verification tracking - **`account`** - User account management (optional) - **`invoice`** - Lightning payment tracking (optional) ### Key Features - ✅ **NIP-01 compliant** - Full basic protocol support - ✅ **Replaceable events** - Supports kinds 0, 3, 10000-19999 - ✅ **Parameterized replaceable** - Supports kinds 30000-39999 with `d` tags - ✅ **Event deletion** - NIP-09 soft deletion with `hidden` column - ✅ **Event expiration** - NIP-40 automatic cleanup - ✅ **Authentication** - NIP-42 client authentication - ✅ **NIP-05 verification** - Domain-based identity verification - ✅ **Performance optimized** - Comprehensive indexing strategy ### Schema Version Current version: **v18** (compatible with nostr-rs-relay v18) ## Database Structure ### Event Storage ```sql CREATE TABLE event ( id INTEGER PRIMARY KEY, event_hash BLOB NOT NULL, -- 32-byte SHA256 hash first_seen INTEGER NOT NULL, -- relay receive timestamp created_at INTEGER NOT NULL, -- event creation timestamp expires_at INTEGER, -- NIP-40 expiration author BLOB NOT NULL, -- 32-byte pubkey delegated_by BLOB, -- NIP-26 delegator kind INTEGER NOT NULL, -- event kind hidden INTEGER DEFAULT FALSE, -- soft deletion flag content TEXT NOT NULL -- complete JSON event ); ``` ### Tag Indexing ```sql CREATE TABLE tag ( id INTEGER PRIMARY KEY, event_id INTEGER NOT NULL, name TEXT, -- tag name ("e", "p", etc.) value TEXT, -- tag value created_at INTEGER NOT NULL, -- denormalized for performance kind INTEGER NOT NULL -- denormalized for performance ); ``` ## Performance Features ### Optimized Indexes - **Hash-based lookups** - `event_hash_index` for O(1) event retrieval - **Author queries** - `author_index`, `author_created_at_index` - **Kind filtering** - `kind_index`, `kind_created_at_index` - **Tag searching** - `tag_covering_index` for efficient tag queries - **Composite queries** - Multi-column indexes for complex filters ### Query Optimization - **Denormalized tags** - Includes `kind` and `created_at` in tag table - **Binary storage** - BLOBs for hex data (pubkeys, hashes) - **WAL mode** - Write-Ahead Logging for concurrent access - **Automatic cleanup** - Triggers for data integrity ## Usage Examples ### Basic Operations 1. **Insert an event:** ```sql INSERT INTO event (event_hash, first_seen, created_at, author, kind, content) VALUES (?, ?, ?, ?, ?, ?); ``` 2. **Query by author:** ```sql SELECT content FROM event WHERE author = ? AND hidden != TRUE ORDER BY created_at DESC; ``` 3. **Filter by tags:** ```sql SELECT e.content FROM event e JOIN tag t ON e.id = t.event_id WHERE t.name = 'p' AND t.value = ? AND e.hidden != TRUE; ``` ### Advanced Queries 1. **Get replaceable event (latest only):** ```sql SELECT content FROM event WHERE author = ? AND kind = ? AND hidden != TRUE ORDER BY created_at DESC LIMIT 1; ``` 2. **Tag-based filtering (NIP-01 filters):** ```sql SELECT e.content FROM event e WHERE e.id IN ( SELECT t.event_id FROM tag t WHERE t.name = ? AND t.value IN (?, ?, ?) ) AND e.hidden != TRUE; ``` ## Maintenance ### Regular Operations 1. **Check database integrity:** ```bash sqlite3 c_nostr_relay.db "PRAGMA integrity_check;" ``` 2. **Optimize database:** ```bash sqlite3 c_nostr_relay.db "PRAGMA optimize; VACUUM; ANALYZE;" ``` 3. **Clean expired events:** ```sql DELETE FROM event WHERE expires_at <= strftime('%s', 'now'); ``` ### Monitoring 1. **Database size:** ```bash ls -lh c_nostr_relay.db ``` 2. **Table statistics:** ```sql SELECT name, COUNT(*) as count FROM ( SELECT 'events' as name FROM event UNION ALL SELECT 'tags' as name FROM tag UNION ALL SELECT 'verifications' as name FROM user_verification ) GROUP BY name; ``` ## Migration Support The schema includes a migration system for future updates: ```sql CREATE TABLE schema_info ( version INTEGER PRIMARY KEY, applied_at INTEGER NOT NULL, description TEXT ); ``` ## Security Considerations 1. **Input validation** - Always validate event JSON and signatures 2. **Rate limiting** - Implement at application level 3. **Access control** - Use `account` table for permissions 4. **Backup strategy** - Regular database backups recommended ## Compatibility - **SQLite version** - Requires SQLite 3.8.0+ - **nostr-rs-relay** - Schema compatible with v18 - **NIPs supported** - 01, 02, 05, 09, 10, 11, 26, 40, 42 - **C libraries** - Compatible with sqlite3 C API ## Troubleshooting ### Common Issues 1. **Database locked error:** - Ensure proper connection closing in your C code - Check for long-running transactions 2. **Performance issues:** - Run `PRAGMA optimize;` regularly - Consider `VACUUM` if database grew significantly 3. **Schema errors:** - Verify SQLite version compatibility - Check foreign key constraints ### Getting Help - Check the main project README for C implementation details - Review nostr-rs-relay documentation for reference implementation - Consult Nostr NIPs for protocol specifications ## License This database schema is part of the C Nostr Relay project and follows the same license terms.