How pleb.school uses Nostr for content
pleb.school publishes course and lesson content to Nostr and keeps operational metadata in PostgreSQL. The UI merges both sources into a single, consistent view.
Event kinds used
- NIP-23 (kind 30023): free resources (long-form)
- NIP-99 (kind 30402): paid resources (classified listings with price hint)
- NIP-51 (kind 30004): courses (lists of lessons)
- NIP-57 (kind 9735): zap receipts
- NIP-01 (kind 0): profiles
Example: free resource (NIP-23)
{ "kind": 30023, "tags": [["d","lesson-id"],["title","Lesson title"],["summary","..."]] }
Example: paid resource (NIP-99)
{ "kind": 30402, "tags": [["d","lesson-id"],["title","Premium lesson"],["price","10000","sats"]] }
Example: course (NIP-51)
{ "kind": 30004, "tags": [["d","course-id"],["name","Course title"],["a","30023:pubkey:lesson-id"]] }
Why the database still matters
- The database stores the authoritative price and ownership
- Each published event is linked via a noteId
- The UI merges DB metadata with Nostr content for display and access checks
Publishing flow (high level)
Draft in DB -> create event -> sign (NIP-07 or server-side) -> publish to relays -> store noteId
Publishing to Nostr makes content portable and verifiable, while pleb.school enforces access to paid content based on database purchases and zap receipts.
