NAME

Net::Nostr::RelayInfo - NIP-11 relay information document

SYNOPSIS

use Net::Nostr::RelayInfo;

# Build a relay information document
my $info = Net::Nostr::RelayInfo->new(
    name           => 'My Relay',
    description    => 'A relay for everyone',
    pubkey         => $admin_pubkey,
    self           => $relay_pubkey,
    contact        => 'mailto:admin@example.com',
    supported_nips => [1, 9, 11, 42, 44],
    software       => 'https://example.com/relay',
    version        => '1.0.0',
);

# Serialize to JSON
my $json = $info->to_json;

# Parse a relay info document (e.g. from an HTTP response)
my $info = Net::Nostr::RelayInfo->from_json($json);
say $info->name;
say join(', ', @{$info->supported_nips});

# Generate an HTTP response with CORS headers
my $http_response = $info->to_http_response;

# Set on a relay to enable NIP-11
use Net::Nostr::Relay;
my $relay = Net::Nostr::Relay->new(
    relay_info => $info,
);
$relay->start('127.0.0.1', 8080);

DESCRIPTION

Implements NIP-11, the relay information document. This is a JSON document served over HTTP at the same URI as the relay's WebSocket endpoint. Clients request it with an Accept: application/nostr+json header.

When a relay_info is set on a Net::Nostr::Relay, the relay will automatically serve the document in response to HTTP requests with the correct Accept header, and handle CORS preflight OPTIONS requests.

CONSTRUCTOR

new

my $info = Net::Nostr::RelayInfo->new(
    name             => 'My Relay',
    description      => 'A relay for everyone',
    banner           => 'https://example.com/banner.jpg',
    icon             => 'https://example.com/icon.png',
    pubkey           => $admin_pubkey_hex,
    self             => $relay_pubkey_hex,
    contact          => 'mailto:admin@example.com',
    supported_nips   => [1, 9, 11],
    software         => 'https://example.com/relay',
    version          => '1.0.0',
    terms_of_service => 'https://example.com/tos',
    limitation       => { max_subscriptions => 50 },
    payments_url     => 'https://example.com/pay',
    fees             => { admission => [{ amount => 1000, unit => 'msats' }] },
);

All fields are optional and may be omitted. Croaks on unknown arguments. The name field SHOULD be less than 30 characters. The pubkey field is the administrative contact pubkey. The self field is the relay's own pubkey. supported_nips is an arrayref of integer NIP numbers.

The limitation hashref may contain any of the following keys:

my $info = Net::Nostr::RelayInfo->new(
    limitation => {
        max_message_length   => 16384,
        max_subscriptions    => 300,
        max_limit            => 5000,
        max_subid_length     => 100,
        max_event_tags       => 100,
        max_content_length   => 8196,
        min_pow_difficulty   => 30,
        auth_required        => \1,
        payment_required     => \1,
        restricted_writes    => \1,
        created_at_lower_limit => 31536000,
        created_at_upper_limit => 3,
        default_limit        => 500,
    },
);

The fees hashref maps fee types to arrayrefs of fee entries. Each fee entry has amount and unit keys, and optionally period (for subscriptions) or kinds (for per-kind publication fees):

my $info = Net::Nostr::RelayInfo->new(
    payments_url => 'https://my-relay/payments',
    fees => {
        admission    => [{ amount => 1000000, unit => 'msats' }],
        subscription => [{ amount => 5000000, unit => 'msats',
                           period => 2592000 }],
        publication  => [{ kinds => [4], amount => 100,
                           unit => 'msats' }],
    },
);

CLASS METHODS

from_json

my $info = Net::Nostr::RelayInfo->from_json($json_string);

Parses a JSON relay information document. Unknown fields are ignored per spec.

use HTTP::Tiny;
my $resp = HTTP::Tiny->new->get($relay_url, {
    headers => { Accept => 'application/nostr+json' },
});
die "Failed to fetch relay info: $resp->{status}"
    unless $resp->{success};
my $info = Net::Nostr::RelayInfo->from_json($resp->{content});

cors_preflight_response

my $http = Net::Nostr::RelayInfo->cors_preflight_response;

Returns an HTTP 204 response string with CORS headers for handling OPTIONS preflight requests. May be called as a class method or a function -- the invocant is not used.

METHODS

to_json

my $json = $info->to_json;

Serializes the relay information document to a JSON string. Only fields that have been set are included.

to_http_response

my $http = $info->to_http_response;

Returns a complete HTTP 200 response string with the JSON body, Content-Type: application/nostr+json, and the required CORS headers (Access-Control-Allow-Origin, Access-Control-Allow-Headers, Access-Control-Allow-Methods).

ACCESSORS

name

Relay name (SHOULD be less than 30 characters).

description

Relay description.

Banner image URL.

icon

Icon image URL.

pubkey

Admin contact pubkey (64-char lowercase hex).

self

Relay's own pubkey (64-char lowercase hex).

contact

Admin contact URI (e.g. mailto:admin@example.com).

supported_nips

Arrayref of supported NIP numbers.

software

URL of the relay software project.

version

Relay software version string.

terms_of_service

URL of terms of service.

limitation

Hashref of relay limitations (see "new" for supported keys).

payments_url

URL for relay payment information.

fees

Hashref of fee schedules (see "new" for structure).

SEE ALSO

NIP-11, Net::Nostr, Net::Nostr::Relay