NAME

Net::Nostr::FollowList - NIP-02 follow list management

SYNOPSIS

use Net::Nostr::FollowList;

# Build a follow list
my $fl = Net::Nostr::FollowList->new;
$fl->add('a' x 64, relay => 'wss://relay.example.com/', petname => 'alice');
$fl->add('b' x 64, petname => 'bob');
$fl->add('c' x 64);

# Query
say $fl->count;                  # 3
say $fl->contains('a' x 64);    # 1

# Remove
$fl->remove('b' x 64);

# Convert to a kind 3 event for publishing
my $event = $fl->to_event(pubkey => $key->pubkey_hex);
$key->sign_event($event);
$client->publish($event);

# Parse from a received kind 3 event
my $fl = Net::Nostr::FollowList->from_event($event);
for my $f ($fl->follows) {
    say "$f->{petname}: $f->{pubkey} ($f->{relay})";
}

DESCRIPTION

Implements NIP-02 follow lists. A follow list is a kind 3 replaceable event containing p tags, one per followed profile. Each tag carries the profile's pubkey, an optional relay URL, and an optional petname.

New follows are appended to the end of the list per NIP-02 convention. Re-adding an existing pubkey updates the entry in place.

CONSTRUCTOR

new

my $fl = Net::Nostr::FollowList->new;

Creates an empty follow list.

from_event

my $fl = Net::Nostr::FollowList->from_event($event);

Parses a kind 3 event into a FollowList. Extracts all p tags and ignores other tag types. Croaks if the event is not kind 3.

my $event = Net::Nostr::Event->new(
    pubkey => 'a' x 64, kind => 3, content => '',
    tags => [['p', 'b' x 64, 'wss://relay.com/', 'bob']],
);
my $fl = Net::Nostr::FollowList->from_event($event);
say $fl->count;  # 1

METHODS

add

$fl->add($pubkey);
$fl->add($pubkey, relay => 'wss://relay.com/', petname => 'alice');

Adds a follow entry. $pubkey must be 64-character lowercase hex. relay and petname default to empty string. If the pubkey already exists, the entry is updated in place. Returns $self for chaining.

$fl->add('a' x 64, relay => 'wss://r.com/')
   ->add('b' x 64, petname => 'bob');

remove

$fl->remove($pubkey);

Removes the entry for the given pubkey. No-op if not present. Returns $self for chaining.

contains

my $bool = $fl->contains($pubkey);

Returns true if the given pubkey is in the follow list.

$fl->add('a' x 64);
say $fl->contains('a' x 64);  # 1
say $fl->contains('b' x 64);  # 0

count

my $n = $fl->count;

Returns the number of follows in the list.

follows

my @follows = $fl->follows;

Returns the list of follow entries as hashrefs, each with keys pubkey, relay, and petname. Entries appear in the order they were added.

for my $f ($fl->follows) {
    say "$f->{petname}: $f->{pubkey}";
}

to_tags

my $tags = $fl->to_tags;
# [['p', 'aa...', 'wss://r.com/', 'alice'], ...]

Returns the follow list as an arrayref of tag arrays, suitable for passing to "new" in Net::Nostr::Event.

to_event

my $event = $fl->to_event(pubkey => $pubkey_hex);
my $event = $fl->to_event(pubkey => $pubkey_hex, created_at => time());

Creates a kind 3 Net::Nostr::Event from the follow list. All extra arguments are passed through to Net::Nostr::Event->new. The kind, content, and tags fields are set automatically.

my $event = $fl->to_event(pubkey => $key->pubkey_hex);
$key->sign_event($event);

SEE ALSO

Net::Nostr, Net::Nostr::Event, Net::Nostr::Key