Passive schema validator for Nostr events. Fetches events from relays, validates them against schemata JSON Schemas, and reports which apps produce malformed blobs.
- Scan relays for events across 16 kinds (NIP-01, NIP-02, NIP-17, NIP-23, NIP-47, NIP-57, NIP-59, NIP-65)
- Validate each event against its JSON Schema using AJV
- Attribute events to apps via NIP-89 client tags
- Store results in SQLite for analysis
- Export findings as JSON + HTML dashboard
- Publish daily report to Nostr as kind:1 summary + kind:30023 long-form article
CI runs 3x/day via GitHub Actions with relay-friendly rate limiting, batch sizing, and randomized scan order.
# Scan relays for events and validate
sherlock scan --since 24h --relays wss://relay.damus.io
# Show database statistics
sherlock stats
# Show violation reports (by kind, client, error, or recent)
sherlock report --by kind
sherlock report --by client --format json
# Export findings to JSON + HTML dashboard
sherlock export
# Export and publish report to Nostr
sherlock export --publishdata/findings.json— Machine-readable findings with three views: by kind, by app, error patterns. Git-tracked; changes over time = trend data for free.docs/index.html— Interactive HTML dashboard with findings inlined (no fetch, no CORS, works as a local file). Served by GitHub Pages.- Nostr notes — Daily kind:1 highlights + kind:30023 full report published by the nostrability bot.
npm install --legacy-peer-deps
npx tscRequires nak on PATH for scanning and publishing.
The GitHub Actions workflow (scan.yml) runs 3x/day at staggered UTC times. It:
- Restores the SQLite DB from cache (incremental scanning)
- Scans relays with randomized order and jitter
- Exports
data/findings.json+docs/index.html - Publishes to Nostr (daily, first run only)
- Commits findings if changed
- Caches DB for next run
To enable Nostr publishing, add NOSTR_SECRET_KEY (nsec or hex) to GitHub repo secrets.
| NIP | Kinds | Description |
|---|---|---|
| NIP-01 | 0 | Profile metadata |
| NIP-02 | 3 | Contact list |
| NIP-17 | 14, 15, 10050 | Direct messages, file messages, DM relay list |
| NIP-23 | 30023 | Long-form content |
| NIP-47 | 13194, 23194–23197 | Nostr Wallet Connect |
| NIP-57 | 9734, 9735 | Zap request, zap receipt |
| NIP-59 | 13, 1059 | Seal, gift wrap |
| NIP-65 | 10002 | Relay list metadata |