A high-performance Nostr Data Vending Machine (DVM) for indexing and querying kind 32222 video events.
- Indexer: Ingests kind 32222 events from relay, stores in ClickHouse
- DVM Service: Provides NIP-90 WebSocket and GraphQL HTTP query interfaces
- Storage: ClickHouse for events, Redis for caching
- Performance: <200ms p95 latency at 50+ QPS with caching
- ClickHouse instance at
clickhouse.divine.video - Nostr relay at
wss://relay3.openvine.co - Redis (via Docker or managed)
- Copy environment configuration:
cp .env.example .env
# Edit .env with your settings- Initialize ClickHouse schema:
clickhouse-client --host clickhouse.divine.video < schema.sql- Run with Docker Compose:
docker-compose upBackfill historical events:
cargo run -p indexer -- backfill --since 0Run live subscription:
cargo run -p indexer -- liveQuery example:
query {
searchVideos(
minLoops: 100,
hashtags: ["music"],
sort: ["likes:desc"],
limit: 50
) {
items {
id
title
loops
likes
duration
hashtags
hls
}
cursor
}
}Job request (kind 5302):
{
"kind": 5302,
"tags": [
["param", "minLoops", "100"],
["param", "hashtags", "music,funny"],
["param", "sort", "likes:desc"],
["param", "limit", "50"]
]
}Result (kind 6302): Full Nostr events in content field
# All tests
cargo test --workspace
# Specific crate
cargo test -p indexer
cargo test -p dvmcargo build --releaseSee .env.example for all configuration options:
RELAY_URL: Source relay for eventsCLICKHOUSE_URL: ClickHouse connectionREDIS_URL: Redis for cachingRATE_LIMIT_PER_MIN: Request rate limitingCACHE_TTL_SEC: Cache duration
events_raw: Raw Nostr eventsvideo_32222: Typed wide table with parsed fieldsvideo_32222_current: Current state (NIP-33 replaceable)events_deleted: Tombstoned events (kind 5)
- Time range:
since,until - Metrics:
minLoops,minLikes - Duration:
durationMin,durationMax - Hashtags: Array intersection
- Sorting: Multi-field with direction
- Pagination: Cursor-based continuation
MIT