Skip to content

Deegerwalker/Magneto

Repository files navigation

Magneto Directory

Magneto Directory is an operator-less, Nostr-native directory for content locators (BitTorrent magnets and IPFS CIDs). The client publishes signed Nostr events directly to relays. The backend only indexes and serves read-only queries.

Features (PR1)

  • Board definitions (kind 30091) using parameterized replaceable events
  • Listings (kind 30092) with magnet, I2P magnet, and IPFS locator tags
  • Curator picks per board (kind 30093) for consensus curation
  • Personal curated lists (kind 30094)
  • Minimal UI (boards, board page with New/Curated, listing detail, submit listing, profile, new list)
  • Read-only API routes
  • Relay indexer with signature validation

Stack

  • Next.js App Router + Route Handlers
  • TypeScript
  • Prisma + Postgres (Docker)
  • nostr-tools v2

Quick start

  1. Install dependencies
npm install
  1. Start Postgres
docker-compose up -d
  1. Configure env
cp .env.example .env
  1. Run migrations
npx prisma migrate dev --name init
  1. Run web + indexer
npm run dev
npm run indexer:dev

Env vars

  • DATABASE_URL Postgres connection string
  • MAGNETO_RELAYS comma-separated relay URLs for indexer
  • NEXT_PUBLIC_MAGNETO_RELAYS comma-separated relay URLs for client publishing
  • INDEXER_SINCE_DAYS backfill window (default 30)

Scripts

  • npm run dev start Next.js dev server
  • npm run indexer:dev backfill + live indexer
  • npm run indexer:rebuild wipe cache tables and reindex
  • npm run db:migrate Prisma migrate dev
  • npm run db:studio Prisma Studio
  • npm run typecheck TypeScript type check
  • npm run test alias for typecheck

Event schema (summary)

Kinds:

  • 30091 Board Definition (parameterized replaceable)
  • 30092 Listing
  • 30093 Curator Picks (parameterized replaceable)
  • 30094 Personal Curated List (parameterized replaceable)

Board definition tags:

  • d = magneto:<slug>
  • name = display title
  • optional: about, rules, t, r, visibility

Listing tags:

  • board = magneto:<slug>
  • locators: magnet, i2p, ipfs (at least one)
  • optional: title, summary, t

Curator picks tags:

  • d = magneto:picks:<board_slug>
  • board = magneto:<slug>
  • repeated e tags with marker pick

Personal list tags:

  • d = magneto:list:<list_slug>
  • name required
  • optional: about
  • items: board tags, e tags with marker item

Validation helpers live in src/lib/nostr/schema.ts.

Indexer behavior

  • Connects to configured relays
  • Backfills INDEXER_SINCE_DAYS history, then stays live
  • Validates signatures and schema
  • Writes derived records into Postgres

API endpoints (read-only)

  • GET /api/boards
  • GET /api/boards/:slug
  • GET /api/boards/:slug/new
  • GET /api/boards/:slug/curated
  • GET /api/listings/:eventId
  • GET /api/listings/:eventId/thread (stub)
  • GET /api/profiles/:npub
  • GET /api/profiles/:npub/lists
  • GET /api/profiles/:npub/lists/:dTag

UI routes

  • / landing
  • /boards directory
  • /b/[slug] board (New + Curated)
  • /b/[slug]/submit submit listing
  • /l/[eventId] listing detail
  • /p/[npub] profile
  • /lists/new create personal list

Publishing flow

  • Client builds event locally
  • Uses NIP-07 if available (window.nostr)
  • Falls back to JSON copy if NIP-07 is not available
  • Publishes signed event directly to relays via nostr-tools

Notes

  • No file hosting, no peer stats, no IPFS fetching.
  • Backend is read-only; all writes go to Nostr relays.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published