padreug commented on issue aiolabs/lightning-pub#10

padreug
2026-04-01T16:50:12Z

Extension: Events (Ticketing)
NIP Review: Applicable Standards for Events Extension

Core NIPs to Implement

NIP-52: Calendar Events — PRIMARY FOUNDATION

Use kind 31923 (time-based calendar events) as the canonical event format. This makes every event discoverable on any Nostr client (Amethyst, Damus, etc.) for free.

Event structure:

{
  "kind": 31923,
  "content": "<markdown event description>",
  "tags": [
    ["d", "<unique-event-id>"],
    ["title", "Bitcoin Meetup Guatemala"],
    ["summary", "Monthly Lightning Network meetup"],
    ["image", "<poster-url>"],
    ["location", "Café Barista, Antigua"],
    ["g", "<geohash>"],
    ["start", "<unix-timestamp>"],
    ["end", "<unix-timestamp>"],
    ["start_tzid", "America/Guatemala"],
    ["p", "<organizer-pubkey>", "", "organizer"],
    ["p", "<speaker-pubkey>", "", "performer"],
    ["t", "bitcoin"],
    ["t", "meetup"],
    ["price", "50000", "sats"]
  ]
}

Also defines:

Kind 31922: Date-based events (all-day, multi-day) — use for festivals/conferences

Kind 31924: Calendar collections (group related events)

Kind 31925: RSVPs (status: accepted/declined/tentative) — doubles as ticket confirmation

NIP-57: Zaps — PAYMENT LAYER

Zap receipts (kind 9735) serve as ticket purchase proof. The a tag links the payment directly to the calendar event:

{
  "kind": 9734,
  "tags": [
    ["a", "31923:<organizer-pubkey>:<event-d-id>"],
    ["amount", "<price-in-millisats>"],
    ["p", "<organizer-pubkey>"],
    ["relays", "wss://relay.example.com"]
  ]
}

Zap receipt (kind 9735) then becomes the immutable ticket — cryptographically signed payment proof linked to the specific event.

NIP-33: Parameterized Replaceable Events — INFRASTRUCTURE

Events (kind 31923) are addressable via <kind>:<pubkey>:<d-tag>. This means organizers can update event details (venue change, time shift) without invalidating existing tickets/RSVPs. Deletion via NIP-09.

Supplementary NIPs

NIP | Kind | Use Case | Priority
NIP-72 (Communities) | 34550 | Venue/organizer brand community — ticket holders become members | Optional
NIP-51 (Lists) | 30003 | User's "saved events" bookmark set | Optional
NIP-38 (Statuses) | 30315 | Real-time event status ("Doors Open", "Sold Out") | Nice-to-have
NIP-99 (Classifieds) | 30402 | Alternative listing format with price and status tags — less suitable than NIP-52 | Skip
NIP-15 (Marketplace) | 30017/30018 | Order management patterns for group ticket purchases | Reference only

Recommended Implementation

Ticket purchase flow using standard NIPs:

1. Organizer publishes event (kind 31923) with price tag

2. Attendee zaps the event (kind 9734 request → kind 9735 receipt)

3. Extension records zap receipt as ticket confirmation

4. Attendee can also RSVP (kind 31925) for non-paid events or waitlists

5. Organizer queries zap receipts by a tag to get attendee list

What this gives us over LNbits: Every event is automatically visible on Nostr, tickets are verifiable zap receipts, attendees are identified by npub, and RSVPs work across any Nostr client — zero custom UI required for basic discovery.