No description
  • Go 96.7%
  • Dockerfile 3.3%
Find a file
@s.roertgen 8a31ceae92
All checks were successful
Build and Push Docker Image / build (push) Successful in 5m48s
Update nostrlib to pick up upstream relay refactor
2026-03-05 14:24:50 +01:00
.forgejo/workflows add Forgejo Actions workflow for Docker image builds 2026-02-10 15:07:20 +01:00
.dockerignore Initial commit: calendar relay for NIP-52 events 2026-02-10 09:28:57 +01:00
.env.example Add SERVICE_URL env var to fix NIP-98 auth behind reverse proxy 2026-03-03 15:46:25 +01:00
.gitignore Initial commit: calendar relay for NIP-52 events 2026-02-10 09:28:57 +01:00
CLAUDE.md feat: support NIP-52 kinds 31924 (calendar) and 31925 (RSVP) 2026-02-20 17:08:42 +01:00
docker-compose.yml add Forgejo Actions workflow for Docker image builds 2026-02-10 15:07:20 +01:00
Dockerfile Initial commit: calendar relay for NIP-52 events 2026-02-10 09:28:57 +01:00
go.mod Update nostrlib to pick up upstream relay refactor 2026-03-05 14:24:50 +01:00
go.sum Update nostrlib to pick up upstream relay refactor 2026-03-05 14:24:50 +01:00
LICENSE license: add Unlicense (public domain) 2026-02-10 12:49:07 +01:00
main.go Add SERVICE_URL env var to fix NIP-98 auth behind reverse proxy 2026-03-03 15:46:25 +01:00
management.go Add dynamic admin management via NIP-86 2026-03-03 13:07:32 +01:00
README.md Add SERVICE_URL env var to fix NIP-98 auth behind reverse proxy 2026-03-03 15:46:25 +01:00

Calendar Relay

A specialized Nostr relay for calendar events (NIP-52) with support for date range queries and geohash-based location filtering.

Features

  • Accepts NIP-52 events: calendar events (31922, 31923), calendars (31924), and RSVPs (31925)
  • Extended query parameters for date/time ranges (kinds 31922, 31923):
    • #start_after - Events starting at or after Unix timestamp
    • #start_before - Events starting before Unix timestamp
    • #end_after - Events ending at or after Unix timestamp
    • #end_before - Events ending before Unix timestamp
  • Geohash prefix queries with #g tag
  • BoltDB persistence with secondary calendar indexes
  • NIP-86 management API for administration
  • Negentropy sync support
  • Docker support

Quick Start

Local Development

  1. Copy .env.example to .env and configure:

    cp .env.example .env
    
  2. Run the relay:

    go run .
    

Docker

# Copy and configure environment
cp .env.example .env
# Edit .env with your settings

# Build and run
docker compose up -d --build

Query Examples

# All NIP-52 events
nak req -k 31922 -k 31923 -k 31924 -k 31925 ws://localhost:3334

# Events starting after Jan 1, 2024
nak req -k 31923 -t 'start_after=1704067200' ws://localhost:3334

# Events starting in January 2024
nak req -k 31923 -t 'start_after=1704067200' -t 'start_before=1706745600' ws://localhost:3334

# Events in San Francisco area (geohash prefix)
nak req -k 31923 -t 'g=9q8y' ws://localhost:3334

# Combined: SF events in January 2024
nak req -k 31923 -t 'start_after=1704067200' -t 'start_before=1706745600' -t 'g=9q8y' ws://localhost:3334

Configuration

Variable Description Default
NAME Relay name Calendar Relay
DESCRIPTION Relay description -
ICON Relay icon URL -
PUBKEY Operator pubkey (hex) -
ADMIN_PUBKEYS Admin pubkeys (comma-separated hex) -
SERVICE_URL Public-facing WebSocket URL (e.g. wss://your-relay.example.com). Set when behind a reverse proxy so NIP-98 auth uses the correct URL auto-detected
PORT HTTP port 3334
DB_PATH BoltDB event store path ./data/events.db
INDEX_PATH Calendar index DB path ./data/calendar_index.db

NIP-86 Management API

Requires NIP-42 authentication with an admin pubkey.

Standard Methods

  • banpubkey - Ban a pubkey from publishing
  • allowpubkey - Remove pubkey ban
  • listbannedpubkeys - List all banned pubkeys
  • banevent - Ban an event ID
  • allowevent - Remove event ban
  • listbannedevents - List all banned events
  • changerelayname - Update relay name
  • changerelaydescription - Update relay description
  • changerelayicon - Update relay icon
  • stats - Get relay statistics

Custom Methods

  • rebuildindex - Rebuild the calendar index from scratch

Event Structure

Calendar Events (kinds 31922, 31923)

Required tags: d, title, start. Optional: end, g (geohash), location, p, t, r.

{
  "kind": 31923,
  "tags": [
    ["d", "my-event-2024"],
    ["title", "Nostr Meetup"],
    ["start", "1704067200"],
    ["end", "1704074400"],
    ["g", "9q8yy"]
  ],
  "content": "Join us for a Nostr meetup!"
}

Calendars (kind 31924)

Required tags: d, title. Optional: a (references to calendar events).

{
  "kind": 31924,
  "tags": [
    ["d", "my-calendar"],
    ["title", "Community Events"],
    ["a", "31923:<pubkey>:my-event-2024", "ws://relay.example.com"]
  ],
  "content": "A calendar for community events"
}

RSVPs (kind 31925)

Required tags: d, a (reference to calendar event), status (accepted/declined/tentative). Optional: e, fb, p.

{
  "kind": 31925,
  "tags": [
    ["d", "rsvp-1"],
    ["a", "31923:<pubkey>:my-event-2024", "ws://relay.example.com"],
    ["status", "accepted"],
    ["fb", "busy"]
  ],
  "content": ""
}

License

Unlicense - Public Domain