NAME
Net::Nostr::RelayGroups - Optional NIP-29 group policy for Net::Nostr::Relay
SYNOPSIS
use Net::Nostr::Relay;
use Net::Nostr::RelayGroups;
# $master is the relay's private Net::Nostr::Key; $url is its ws/wss URL.
my $policy = Net::Nostr::RelayGroups->new(key => $master, max_pins => 2);
my $relay = Net::Nostr::Relay->new(relay_url => $url, groups => $policy);
DESCRIPTION
Provides relay-scoped group state, moderation, ordered pins, and subgroups. Pass an instance as the groups option to Net::Nostr::Relay. Group support is disabled by default. When enabled, the relay advertises NIP-29 subgroups and its signing public key through NIP-11.
Anyone may create an unused group with kind 9007, becoming its first member and admin. New groups are public, open for joining, and restricted to members for writes. Only the admin role grants moderation privileges; arbitrary other role labels grant none. Membership and administration never inherit through parent links. Closed groups require a previously accepted invite code. Invites are reusable. Creation and every accepted membership action generate relay-signed kind 9000/9001 events, including the creator's initial admin role. These canonical transitions have timestamps later than the triggering request and previous membership transitions for that user in this group. This makes rapid changes and successive membership actions distinguishable, even within one second; generated timestamps may run ahead of wall-clock time. Original accepted requests remain stored. Group metadata on the wire cannot bypass moderation.
Metadata edits preserve omitted display fields and flags; public, open, visible, and unrestricted clear their opposing flags. Omitted parent detaches a group, and every edit must include all existing children in the desired order. Reparenting requires administration of both groups, rejects missing parents and cycles, and updates both sides. Deleting a group removes its stored events and metadata, and makes its children roots. Pins replace the entire ordered list; empty lists clear it. Malformed or duplicate recognized metadata fields, contradictory flags, invalid supported kinds, empty role labels, and malformed join codes are rejected before storage changes. Kind 9001 permits only a public key in its p tag. supported_kinds can be edited; an empty list disables ordinary group publications while moderation remains available.
Private group history and live events, and hidden group metadata, are served only to authenticated members. The Relay also applies this policy to COUNT and negentropy. Reconciliation sessions are closed after group state changes so a prior snapshot cannot bypass revoked membership; clients may reopen them. Writes use the signed event author's membership. Timeline references must be eight lowercase hex characters identifying another author's event on this relay, including events outside the group. Zero references are permitted; publication more than one hour old or ten minutes in the future is rejected.
State is derived from the relay's signed metadata in the storage backend. Use a persistent store that retains this metadata for durable groups. The default in-memory store does not survive restarts. LiveKit token issuance, automatic membership propagation, history import, and replica management are outside this policy; AV metadata edits are rejected. Administrative local storage injection is trusted and must maintain valid signed group state.
METHODS
new
Strict constructor accepting named arguments as either a flat list or a single hash reference. Requires key, a private Net::Nostr::Key used to sign state events. Optional max_pins is a non-negative integer; omission allows unlimited pins and zero allows only empty lists. Unknown arguments and invalid values croak. The returned policy is ready for use and has no mutable public configuration accessors.
pubkey
Returns the relay signing public key as lowercase hex.
prepare
Accepts an event and a Net::Nostr::RelayStore-compatible backend. Verifies the event ID and signature, then validates group structure, permissions, and state transitions. Returns a plan with events (signed metadata and membership events) and delete_ids. It does not mutate storage. Violations croak with a Nostr error prefix. The Relay applies the complete plan only after validation succeeds. This is a semantic policy operation; the input must already be a structurally valid Net::Nostr::Event.
can_read
Accepts an event, a hashref of authenticated public keys, and the backend. Returns whether those identities may read the event under current group state. Public groups do not require authentication. Unknown groups and foreign group metadata are hidden. This checks authorization of an already parsed event; it does not authenticate the supplied identity map.
SEE ALSO
NIP-29, NIP-42, Net::Nostr::Group, Net::Nostr::Relay, Net::Nostr::RelayStore