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. Any unrecognized keys are stored as extension fields and included in to_json output. See "extensions". 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 preserved as extension fields and are available via "extensions".
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
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).
extensions
my $ext = $info->extensions; # hashref or empty hashref
Returns a shallow copy of any extension fields passed to the constructor that are not part of the NIP-11 standard fields. These are included in the JSON output of to_json and to_http_response.
my $info = Net::Nostr::RelayInfo->new(
name => 'Overnet Relay',
overnet => { version => '1.0', features => ['chat'] },
);
my $ext = $info->extensions;
# { overnet => { version => '1.0', features => ['chat'] } }