NAME

Net::Nostr::RelayAdmin - NIP-86 relay management API

SYNOPSIS

use Net::Nostr::RelayAdmin qw(
    encode_request decode_response request_with_auth
);

# Encode a management request
my $body = encode_request(
    method => 'banpubkey',
    params => ['aa' x 32, 'spammer'],
);

# Decode a response
my $result = decode_response('{"result":true}');
# or handle errors
eval { decode_response('{"error":"not authorized"}') };
warn $@ if $@;

# Build a full authenticated request
my %req = request_with_auth(
    method    => 'supportedmethods',
    params    => [],
    key       => $key,
    relay_url => 'wss://relay.example.com',
);
# %req contains: body, authorization, content_type

DESCRIPTION

Implements the client side of the NIP-86 relay management API. NIP-86 defines a JSON-RPC-like request-response protocol over HTTP for relay administration. Requests are sent to the relay's WebSocket URI with Content-Type: application/nostr+json+rpc and authorized using NIP-98 HTTP auth with a required payload tag.

The following management methods are defined by NIP-86:

supportedmethods - list supported methods
banpubkey, unbanpubkey, listbannedpubkeys - pubkey banning
allowpubkey, unallowpubkey, listallowedpubkeys - pubkey allowlisting
listeventsneedingmoderation, allowevent, banevent, listbannedevents - event moderation
changerelayname, changerelaydescription, changerelayicon - relay metadata
allowkind, disallowkind, listallowedkinds - kind filtering
blockip, unblockip, listblockedips - IP blocking

Unknown method names are passed through without parameter validation, allowing forward compatibility with relay-specific extensions.

FUNCTIONS

All functions are exportable. None are exported by default.

encode_request

my $body = encode_request(
    method => $method_name,
    params => \@params,       # optional, defaults to []
);

Encodes a relay management request as a JSON string with method and params fields. Croaks if method is missing or empty. Croaks if params is provided but not an array reference.

For known NIP-86 methods, validates that params contain the correct types: 64-char lowercase hex for pubkey/event-id methods, non-negative integers for kind methods, non-empty strings for relay metadata methods, and non-empty strings for IP methods.

my $body = encode_request(
    method => 'banpubkey',
    params => ['aa' x 32, 'spammer'],
);

decode_response

my $result = decode_response($json);

Parses a JSON response string and returns the result field. If the response contains a non-empty error field, croaks with the error message. Croaks if the input is missing, empty, or not valid JSON.

my $result = decode_response('{"result":true}');

eval { decode_response('{"error":"not authorized"}') };
if ($@) {
    # handle error
}

request_with_auth

my %req = request_with_auth(
    method    => $method_name,
    params    => \@params,       # optional, defaults to []
    key       => $nostr_key,
    relay_url => $relay_url,
);

Builds a complete authenticated relay management request. Returns a hash with three keys:

body - the JSON request body
authorization - a NIP-98 Authorization header value (Nostr <base64>)
content_type - application/nostr+json+rpc

The NIP-98 auth event uses POST as the HTTP method, the relay_url as the u tag, and includes a payload tag with the SHA-256 hash of the request body, as required by NIP-86.

Croaks if key or relay_url is missing. The key must be a Net::Nostr::Key object with a private key for signing.

my %req = request_with_auth(
    method    => 'supportedmethods',
    params    => [],
    key       => $key,
    relay_url => 'wss://relay.example.com',
);

SEE ALSO

NIP-86, Net::Nostr, Net::Nostr::HttpAuth