No description
  • Svelte 55.6%
  • TypeScript 42.5%
  • Dockerfile 0.8%
  • Nix 0.4%
  • HTML 0.4%
  • Other 0.2%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Steffen Rörtgen c4b131e6df
Some checks failed
Build and publish relay-manager image / test (push) Successful in 19s
Build and publish relay-manager image / image (push) Failing after 2s
relay-proxy: restrict targets to configured relays
The proxy forwarded NIP-86 and NIP-11 requests to any ws(s):// URL a
caller supplied, which made it an open server-side request forwarder.
It now accepts only hosts from PUBLIC_DEFAULT_RELAYS; without that
setting it allows only wss:// relays on public hostnames. Redirects are
no longer followed and credentials in relay URLs are rejected.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-09 13:00:56 +02:00
.forgejo/workflows Dockerize with adapter-node, Forgejo image workflow, PUBLIC_DEFAULT_RELAYS 2026-10-09 12:58:39 +02:00
e2e Add event sync feature and multi-relay support 2026-02-13 09:21:28 +01:00
src relay-proxy: restrict targets to configured relays 2026-10-09 13:00:56 +02:00
static Initial commit: NIP-86 relay management web app 2026-02-12 13:23:07 +01:00
.dockerignore Dockerize with adapter-node, Forgejo image workflow, PUBLIC_DEFAULT_RELAYS 2026-10-09 12:58:39 +02:00
.envrc Initial commit: NIP-86 relay management web app 2026-02-12 13:23:07 +01:00
.gitignore Dockerize with adapter-node, Forgejo image workflow, PUBLIC_DEFAULT_RELAYS 2026-10-09 12:58:39 +02:00
.npmrc Initial commit: NIP-86 relay management web app 2026-02-12 13:23:07 +01:00
CLAUDE.md Initial commit: NIP-86 relay management web app 2026-02-12 13:23:07 +01:00
Dockerfile Dockerize with adapter-node, Forgejo image workflow, PUBLIC_DEFAULT_RELAYS 2026-10-09 12:58:39 +02:00
flake.lock Initial commit: NIP-86 relay management web app 2026-02-12 13:23:07 +01:00
flake.nix Initial commit: NIP-86 relay management web app 2026-02-12 13:23:07 +01:00
LICENSE License under AGPL-3.0-only 2026-10-09 12:53:14 +02:00
package.json Dockerize with adapter-node, Forgejo image workflow, PUBLIC_DEFAULT_RELAYS 2026-10-09 12:58:39 +02:00
playwright.config.ts Initial commit: NIP-86 relay management web app 2026-02-12 13:23:07 +01:00
pnpm-lock.yaml Dockerize with adapter-node, Forgejo image workflow, PUBLIC_DEFAULT_RELAYS 2026-10-09 12:58:39 +02:00
README.md Dockerize with adapter-node, Forgejo image workflow, PUBLIC_DEFAULT_RELAYS 2026-10-09 12:58:39 +02:00
svelte.config.js Dockerize with adapter-node, Forgejo image workflow, PUBLIC_DEFAULT_RELAYS 2026-10-09 12:58:39 +02:00
tsconfig.json Initial commit: NIP-86 relay management web app 2026-02-12 13:23:07 +01:00
vite.config.ts Initial commit: NIP-86 relay management web app 2026-02-12 13:23:07 +01:00
vitest.config.ts Add event sync feature and multi-relay support 2026-02-13 09:21:28 +01:00

Relay Manager

Web-based admin panel for managing Nostr relays that support NIP-86 (Relay Management API).

Features

  • Dashboard — Relay info, stats, and status overview
  • Event browser — Browse and inspect stored events
  • Pubkey management — View and manage known pubkeys
  • Moderation — Ban/unban pubkeys and events
  • Access control — Configure relay allow/deny lists
  • Admin management — Add or remove relay administrators
  • Relay-to-relay sync — Sync events between relays
  • Settings — Relay configuration and schema management

Tech Stack

Getting Started

Prerequisites

  • Node.js 22+ and pnpm (or use nix develop with the included flake)

Install & Run

pnpm install
pnpm dev

Build

pnpm build
pnpm preview  # preview the production build

Authentication

On the login screen, enter a relay URL and choose a signing method:

  • Extension (NIP-07) — Browser extension like nos2x or Alby
  • Bunker (NIP-46) — Remote signing via a bunker URL
  • nsec — Direct private key entry (stored in memory only, never persisted)

API calls to the relay are authenticated with NIP-98 HTTP auth events.

Deployment

The app uses @sveltejs/adapter-node and ships a Dockerfile (Node 22, pnpm via corepack, listens on :3000, non-root, healthcheck on /). NIP-86 calls are proxied through the SvelteKit server route /api/relay-proxy to avoid CORS; they stay NIP-98 signed by the browser signer, so the server holds no secret.

docker build -t relay-manager .
docker run -p 3000:3000 \
  -e ORIGIN=https://relay-manager.example.org \
  -e PUBLIC_DEFAULT_RELAYS=wss://relay-a.example.org,wss://relay-b.example.org \
  relay-manager
Variable Purpose
PORT / HOST adapter-node listen address (defaults 3000 / 0.0.0.0 in the image)
ORIGIN Public origin the app is served from (adapter-node origin checks)
PUBLIC_DEFAULT_RELAYS Optional comma-separated wss:// URLs offered on the login screen and seeded into the saved-relay list

Pushes to main and v* tags build and publish git.edufeed.org/edufeed/relay-manager via .forgejo/workflows/build.yml.

Development

pnpm dev          # start dev server
pnpm build        # production build
pnpm test         # run unit tests (vitest)
pnpm test:e2e     # run e2e tests (playwright)
pnpm check        # svelte-check + type checking
pnpm format       # format with prettier
pnpm lint         # check formatting

Nix

A flake.nix is included for reproducible development environments with Node.js 22, pnpm, and Playwright:

nix develop