6.2 KiB
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 v18init.sh- Database initialization scriptc_nostr_relay.db- SQLite database file (created after running init.sh)
Quick Start
-
Initialize the database:
cd db ./init.sh -
Force reinitialize (removes existing database):
./init.sh --force -
Initialize with optimization and info:
./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 datatag- Denormalized tag index for efficient queriesuser_verification- NIP-05 verification trackingaccount- 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
dtags - ✅ Event deletion - NIP-09 soft deletion with
hiddencolumn - ✅ 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
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
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_indexfor O(1) event retrieval - Author queries -
author_index,author_created_at_index - Kind filtering -
kind_index,kind_created_at_index - Tag searching -
tag_covering_indexfor efficient tag queries - Composite queries - Multi-column indexes for complex filters
Query Optimization
- Denormalized tags - Includes
kindandcreated_atin 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
-
Insert an event:
INSERT INTO event (event_hash, first_seen, created_at, author, kind, content) VALUES (?, ?, ?, ?, ?, ?); -
Query by author:
SELECT content FROM event WHERE author = ? AND hidden != TRUE ORDER BY created_at DESC; -
Filter by tags:
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
-
Get replaceable event (latest only):
SELECT content FROM event WHERE author = ? AND kind = ? AND hidden != TRUE ORDER BY created_at DESC LIMIT 1; -
Tag-based filtering (NIP-01 filters):
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
-
Check database integrity:
sqlite3 c_nostr_relay.db "PRAGMA integrity_check;" -
Optimize database:
sqlite3 c_nostr_relay.db "PRAGMA optimize; VACUUM; ANALYZE;" -
Clean expired events:
DELETE FROM event WHERE expires_at <= strftime('%s', 'now');
Monitoring
-
Database size:
ls -lh c_nostr_relay.db -
Table statistics:
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:
CREATE TABLE schema_info (
version INTEGER PRIMARY KEY,
applied_at INTEGER NOT NULL,
description TEXT
);
Security Considerations
- Input validation - Always validate event JSON and signatures
- Rate limiting - Implement at application level
- Access control - Use
accounttable for permissions - 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
-
Database locked error:
- Ensure proper connection closing in your C code
- Check for long-running transactions
-
Performance issues:
- Run
PRAGMA optimize;regularly - Consider
VACUUMif database grew significantly
- Run
-
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.