JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 15
  • Score
    100M100P100Q75150F
  • License MIT

REST API agent for managing Nostr relays without touching the terminal

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@bitmacro/relay-agent) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    @bitmacro/relay-agent

    CI npm version License: MIT

    Manage your Nostr relay without touching the terminal.

    relay-agent is a REST API agent that runs on your relay server and translates HTTP requests into strfry CLI commands. It is part of the BitMacro Relay Manager ecosystem.


    Quick Start

    Via npx

    npx @bitmacro/relay-agent --port 7800 --token your-secret-token

    Use --version or --help to check version or CLI options.

    Via Docker

    Multi-arch image (amd64, arm64) at ghcr.io/bitmacro/relay-agent. Includes strfry binary. Mount your strfry data volume:

    docker pull ghcr.io/bitmacro/relay-agent:latest
    docker run -p 7800:7800 \
      -e RELAY_AGENT_TOKEN=your-secret-token \
      -v /path/to/strfry-db:/app/strfry-db \
      -v /path/to/whitelist.txt:/app/whitelist.txt \
      ghcr.io/bitmacro/relay-agent:latest

    Or build locally: docker build -t relay-agent .

    Multiple relays: Use the compose fragment. Place relay-agent next to your docker-compose.yml.

    Server deployment (complete flow)

    # 1. Clone (or pull) relay-agent into a subdir next to your docker-compose.yml
    git clone https://github.com/bitmacro/relay-agent.git relay-agent
    
    # 2. Configure .env in the directory containing docker-compose.yml
    echo "RELAY_AGENT_TOKEN_PRIVATE=your-secret-token" >> .env
    echo "RELAY_AGENT_TOKEN_PUBLIC=your-secret-token" >> .env
    echo "RELAY_AGENT_TOKEN_PAID=your-secret-token" >> .env
    
    # 3. Pull images from GHCR (or build locally if testing before merge)
    docker compose -f docker-compose.yml -f relay-agent/docker-compose.relay-agents.yml pull
    
    # 4. Start the services
    docker compose -f docker-compose.yml -f relay-agent/docker-compose.relay-agents.yml up -d relay-agent-private relay-agent-public relay-agent-paid

    Before GHCR has the image: Use build instead of pull — the compose includes a build fallback. Run docker compose ... build then up -d.

    See docker-compose.relay-agents.yml for the full setup (1 agent per relay in v0.1).


    Operational Commands

    For operators using the compose fragment (docker-compose.yml + relay-agent/docker-compose.relay-agents.yml):

    # Rebuild and restart a specific agent
    docker compose -f docker-compose.yml -f relay-agent/docker-compose.relay-agents.yml up -d --build relay-agent-public
    
    # Rebuild and restart all relay agents
    docker compose -f docker-compose.yml -f relay-agent/docker-compose.relay-agents.yml up -d --build relay-agent-private relay-agent-public relay-agent-paid
    
    # Pull latest image and restart (when using GHCR)
    docker compose -f docker-compose.yml -f relay-agent/docker-compose.relay-agents.yml pull
    docker compose -f docker-compose.yml -f relay-agent/docker-compose.relay-agents.yml up -d relay-agent-private relay-agent-public relay-agent-paid
    
    # View logs
    docker compose -f docker-compose.yml -f relay-agent/docker-compose.relay-agents.yml logs -f relay-agent-public
    
    # Stop all relay agents
    docker compose -f docker-compose.yml -f relay-agent/docker-compose.relay-agents.yml stop relay-agent-private relay-agent-public relay-agent-paid

    Smoke Test

    Verify the agent can talk to strfry LMDB:

    docker exec relay-agent-public sh -c 'curl -s -m 60 -H "Authorization: Bearer $RELAY_AGENT_TOKEN" http://localhost:7800/stats'

    Expected response: {"total_events":...,"db_size":"...","uptime":...,"version":"..."}


    REST API Endpoints

    Method Path Description Example Response
    GET /health Health check (no auth) {"status":"ok","timestamp":"..."}
    GET /events List events (NIP-01 filter) [{id, pubkey, kind, ...}, ...]
    DELETE /events/:id Delete event by id {"deleted":"<id>"}
    GET /stats Relay statistics {total_events, db_size, uptime, version}
    POST /policy/block Block pubkey {"blocked":"<pubkey>"}
    POST /policy/allow Allow pubkey {"allowed":"<pubkey>"}
    GET /users List unique pubkeys {"users":["<pubkey>", ...]}

    Query parameters for GET /events

    Param Type Description
    kinds comma-separated e.g. 1,3
    authors comma-separated pubkeys
    since unix timestamp
    until unix timestamp
    limit number max events to return

    Authentication

    All endpoints except /health require:

    Authorization: Bearer <your-token>

    Environment Variables

    Variable Default Description
    RELAY_AGENT_TOKEN Required. Bearer token for API auth
    STRFRY_BIN strfry Path to strfry binary
    STRFRY_DB_PATH ./strfry-db Path to strfry database directory
    STRFRY_CONFIG Path to strfry config file (for explicit db path)
    WHITELIST_PATH /etc/strfry/whitelist.txt Path to whitelist file
    PORT 7800 HTTP server port
    ALLOWED_ORIGINS Comma-separated extra CORS origins (defaults include https://admin.bitmacro.io, http://localhost:3000)

    Compatibility

    relay-agent strfry
    0.1.x 1.0.x

    Architecture

    bitmacro-api (Vercel)
        │  HTTP REST + Bearer JWT
        ▼
    relay-agent  ← this package
        │  child_process spawn()
        ▼
    strfry (local C++ process / LMDB)

    The relay-agent is stateless — it has no database. State lives in Supabase, managed by bitmacro-api. The relay-agent only translates HTTP calls into strfry CLI commands.


    Troubleshooting

    503 "relay unavailable"

    1. Capture the error — run logs in one terminal, then curl in another:

      # Terminal 1
      docker compose -f docker-compose.yml -f relay-agent/docker-compose.relay-agents.yml logs -f relay-agent-private
      # Terminal 2
      curl -H "Authorization: Bearer TOKEN" "http://localhost:7811/events?limit=3"

      The strfry stderr will appear in the logs.

    2. LMDB "Resource temporarily unavailable" — relay and relay-agent share the same db. Increase maxreaders in your relay's strfry.conf (e.g. ./nostr/private/strfry.conf):

      dbParams {
        maxreaders = 512
      }

      Then restart the relay: docker restart relay_private

    3. Verify db path — relay-agent mounts ./nostr/private/data:/app/strfry-db. Your relay (relay_private) must use the same host path for its strfry db. Check your main docker-compose.yml:

      grep -A5 relay_private docker-compose.yml
    4. Test strfry inside container:

      docker compose -f docker-compose.yml -f relay-agent/docker-compose.relay-agents.yml run --rm relay-agent-private sh -c 'ls -la /app/strfry-db && /app/strfry --config /app/strfry.conf scan "{}" | head -3'

      If data.mdb is missing or strfry fails, fix the volume path.


    Security

    • Run on a private network. The relay-agent should run on the operator's server and never be exposed directly to the internet.
    • Access is controlled by the bitmacro-api, which proxies requests with a shared Bearer token.
    • Use a strong, random token in production. Rotate it if compromised.

    Contributing

    See CONTRIBUTING.md for setup and PR guidelines.