NAME
Net::Nostr::RelayMonitor - NIP-66 Relay Discovery and Liveness Monitoring
SYNOPSIS
use Net::Nostr::RelayMonitor;
# Build a relay discovery event (kind 30166)
my $event = Net::Nostr::RelayMonitor->discovery_event(
pubkey => $pubkey,
relay_url => 'wss://relay.example.com/',
network => 'clearnet',
nips => [1, 11, 42],
rtt_open => '150',
requirements => ['!payment', 'auth'],
);
# Build a monitor announcement event (kind 10166)
my $event = Net::Nostr::RelayMonitor->announcement_event(
pubkey => $pubkey,
frequency => '3600',
checks => [qw(ws nip11 ssl dns)],
timeouts => [{ test => 'open', ms => '5000' }],
);
# Parse either kind
my $mon = Net::Nostr::RelayMonitor->from_event($event);
say $mon->relay_url; # discovery events
say $mon->frequency; # announcement events
# Validate
Net::Nostr::RelayMonitor->validate($event);
DESCRIPTION
Implements NIP-66 (Relay Discovery and Liveness Monitoring). Provides methods to build and parse two event types:
- Kind 30166 -- Relay Discovery Events
-
Addressable events published by monitors documenting relay characteristics inferred from NIP-11 documents or probing. The
dtag MUST be set to the relay's normalized URL (or a hex pubkey for non-URL relays). ThecontentMAY include the stringified JSON of the relay's NIP-11 document. - Kind 10166 -- Relay Monitor Announcements
-
Replaceable events advertising a monitor's intent to publish discovery events at a regular frequency.
Clients MUST NOT require 30166 events to function. Clients SHOULD NOT trust a single monitor source.
CONSTRUCTOR
new
my $mon = Net::Nostr::RelayMonitor->new(%fields);
Creates a new Net::Nostr::RelayMonitor object. All fields are optional. Array fields (nips, requirements, topics, kinds, languages, timeouts, checks) default to []. Croaks on unknown arguments. Typically returned by "from_event".
CLASS METHODS
discovery_event
my $event = Net::Nostr::RelayMonitor->discovery_event(
pubkey => $hex_pubkey,
relay_url => 'wss://relay.example.com/',
network => 'clearnet',
relay_type => 'PrivateInbox',
nips => [1, 11, 42],
requirements => ['!payment', 'auth'],
topics => ['nsfw'],
kinds => ['1', '!20000'],
geohash => 'ww8p1r4t8',
languages => ['en'],
rtt_open => '234',
rtt_read => '150',
rtt_write => '300',
nip11 => '{"name":"My Relay"}',
created_at => time(),
);
Creates a kind 30166 addressable Net::Nostr::Event. relay_url is required and becomes the d tag. nip11, if provided, becomes the event content (otherwise empty string). Multi-value tags (nips, requirements, topics, kinds, languages) are emitted as repeated tags per the spec. Any remaining arguments are passed through to "new" in Net::Nostr::Event.
announcement_event
my $event = Net::Nostr::RelayMonitor->announcement_event(
pubkey => $hex_pubkey,
frequency => '3600',
timeouts => [
{ test => 'open', ms => '5000' },
{ test => 'read', ms => '3000' },
{ ms => '10000' }, # applies to all tests
],
checks => [qw(ws nip11 ssl dns geo)],
geohash => 'ww8p1r4t8',
created_at => time(),
);
Creates a kind 10166 replaceable Net::Nostr::Event. frequency is required (seconds between publications). timeouts is an arrayref of hashrefs with ms (milliseconds) and optional test (test type). When test is omitted, the timeout applies to all tests. checks is an arrayref of lowercase check names. Any remaining arguments are passed through to "new" in Net::Nostr::Event.
from_event
my $mon = Net::Nostr::RelayMonitor->from_event($event);
Parses a kind 30166 or 10166 event into a Net::Nostr::RelayMonitor object. Returns undef if the event kind is neither 30166 nor 10166.
my $mon = Net::Nostr::RelayMonitor->from_event($event);
if ($event->kind == 30166) {
say $mon->relay_url;
say $mon->network;
} else {
say $mon->frequency;
say join ', ', @{$mon->checks};
}
validate
Net::Nostr::RelayMonitor->validate($event);
Validates a NIP-66 event. For kind 30166, checks that a d tag is present. For kind 10166, checks that a frequency tag is present. Croaks if the kind is unsupported or required tags are missing. Returns 1 on success.
eval { Net::Nostr::RelayMonitor->validate($event) };
warn "Invalid: $@" if $@;
ACCESSORS
Discovery Event Fields (kind 30166)
relay_url
Relay URL from the d tag. For non-URL relays, may be a hex pubkey.
network
Network type. SHOULD be one of clearnet, tor, i2p, loki.
relay_type
Relay type in PascalCase (e.g. PrivateInbox).
nips
Arrayref of supported NIP numbers (as strings).
requirements
Arrayref of requirement strings. False values use ! prefix (e.g. !payment). Corresponds to NIP-11 limitations.
topics
Arrayref of topic strings.
kinds
Arrayref of accepted/unaccepted kind strings. Unaccepted kinds use ! prefix (e.g. !20000).
geohash
NIP-52 geohash string. Used by both discovery and announcement events.
languages
Arrayref of ISO-639-1 language codes.
rtt_open
Open round-trip time in milliseconds (string).
rtt_read
Read round-trip time in milliseconds (string).
rtt_write
Write round-trip time in milliseconds (string).
nip11
Stringified JSON of the relay's NIP-11 informational document, or undef.
Announcement Event Fields (kind 10166)
frequency
Publication frequency in seconds (string).
timeouts
Arrayref of timeout hashrefs. Each has ms (milliseconds) and optional test (test type). When test is absent, the timeout applies to all tests.
# With test type
{ test => 'open', ms => '5000' }
# Without test type (applies to all)
{ ms => '5000' }
checks
Arrayref of lowercase check name strings (e.g. ws, nip11, ssl, dns, geo).
SEE ALSO
NIP-66, Net::Nostr::RelayInfo, Net::Nostr, Net::Nostr::Event