Net-Nostr

 view release on metacpan or  search on metacpan

lib/Net/Nostr/Calendar.pm  view on Meta::CPAN

            ["31922:$pk:vacation-2024", 'wss://relay'],
        ],
    );

    # RSVP (kind 31925)
    my $rsvp = Net::Nostr::Calendar->rsvp(
        pubkey       => $hex_pubkey,
        identifier   => 'rsvp-1',
        event_coord  => "31922:$organizer_pk:vacation-2024",
        status       => 'accepted',
        fb           => 'busy',
    );

    # Parse any calendar event
    my $parsed = Net::Nostr::Calendar->from_event($event);

    # Validate
    Net::Nostr::Calendar->validate($event);

=head1 DESCRIPTION

lib/Net/Nostr/Calendar.pm  view on Meta::CPAN

=head2 rsvp

    my $event = Net::Nostr::Calendar->rsvp(
        pubkey             => $hex_pubkey,    # required
        identifier         => $id,            # required (d tag)
        event_coord        => $coord,         # required (a tag)
        status             => 'accepted',     # required
        event_relay        => $url,           # optional (a tag relay)
        event_id           => $eid,           # optional (e tag)
        event_id_relay     => $url,           # optional (e tag relay)
        fb                 => 'busy',         # optional (free/busy)
        event_author       => $pk,            # optional (p tag)
        event_author_relay => $url,           # optional (p tag relay)
        content            => $note,          # optional, defaults to ''
    );

Creates a kind 31925 RSVP L<Net::Nostr::Event>. C<status> must be
C<accepted>, C<declined>, or C<tentative>. The C<fb> tag is
automatically omitted when C<status> is C<declined>.

=head2 from_event

lib/Net/Nostr/Calendar.pm  view on Meta::CPAN

=head2 event_id

The specific calendar event revision ID (C<e> tag value, RSVP only).

=head2 status

RSVP status: C<accepted>, C<declined>, or C<tentative>.

=head2 fb

Free/busy indicator: C<free> or C<busy>. Must be omitted or ignored if
C<status> is C<declined>.

=head2 event_author

Pubkey of the calendar event author (RSVP only).

=head1 SEE ALSO

L<NIP-52|https://github.com/nostr-protocol/nips/blob/master/52.md>,
L<Net::Nostr>, L<Net::Nostr::Event>

t/51-Calendar.t  view on Meta::CPAN

# POD example: rsvp
###############################################################################

subtest 'POD: rsvp' => sub {
    my $organizer_pk = 'c' x 64;
    my $rsvp = Net::Nostr::Calendar->rsvp(
        pubkey       => $PK,
        identifier   => 'rsvp-1',
        event_coord  => "31922:${organizer_pk}:vacation-2024",
        status       => 'accepted',
        fb           => 'busy',
    );
    is($rsvp->kind, 31925, 'kind');
};

###############################################################################
# POD example: from_event
###############################################################################

subtest 'POD: from_event' => sub {
    my $event = Net::Nostr::Calendar->date_event(

t/nip/06.t  view on Meta::CPAN

        'public key matches spec';
    is $key->privkey_nsec, 'nsec10allq0gjx7fddtzef0ax00mdps9t2kmtrldkyjfs8l5xruwvh2dq0lhhkp',
        'nsec matches spec';
    is $key->pubkey_npub, 'npub1zutzeysacnf9rru6zqwmxd54mud0k44tst6l70ja5mhv8jjumytsd2x7nu',
        'npub matches spec';
};

# --- Test vector 2 from NIP-06 spec ---

subtest 'test vector 2: 24-word mnemonic' => sub {
    my $mnemonic = 'what bleak badge arrange retreat wolf trade produce cricket blur garlic valid proud rude strong choose busy staff weather area salt hollow arm fade';
    my $key = Net::Nostr::Key->from_mnemonic($mnemonic);

    is $key->privkey_hex, 'c15d739894c81a2fcfd3a2df85a0d2c0dbc47a280d092799f144d73d7ae78add',
        'private key matches spec';
    is $key->pubkey_hex, 'd41b22899549e1f3d335a31002cfd382174006e166d3e658e3a5eecdb6463573',
        'public key matches spec';
    is $key->privkey_nsec, 'nsec1c9wh8xy5eqdzln7n5t0ctgxjcrdug73gp5yj0x03gntn67h83twssdfhel',
        'nsec matches spec';
    is $key->pubkey_npub, 'npub16sdj9zv4f8sl85e45vgq9n7nsgt5qphpvmf7vk8r5hhvmdjxx4es8rq74h',
        'npub matches spec';

t/nip/52.t  view on Meta::CPAN

    my $event = Net::Nostr::Calendar->rsvp(
        pubkey       => $PK,
        identifier   => 'test',
        event_coord  => "31922:${PK}:test",
        status       => 'tentative',
    );
    my @s = grep { $_->[0] eq 'status' } @{$event->tags};
    is($s[0][1], 'tentative', 'tentative');
};

# Spec: fb tag (optional) free/busy
subtest 'rsvp: fb tag busy' => sub {
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey       => $PK,
        identifier   => 'test',
        event_coord  => "31922:${PK}:test",
        status       => 'accepted',
        fb           => 'busy',
    );
    my @fb = grep { $_->[0] eq 'fb' } @{$event->tags};
    is($fb[0][1], 'busy', 'fb busy');
};

subtest 'rsvp: fb tag free' => sub {
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey       => $PK,
        identifier   => 'test',
        event_coord  => "31922:${PK}:test",
        status       => 'accepted',
        fb           => 'free',
    );
    my @fb = grep { $_->[0] eq 'fb' } @{$event->tags};
    is($fb[0][1], 'free', 'fb free');
};

subtest 'rsvp: fb tag omitted when status declined' => sub {
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey       => $PK,
        identifier   => 'test',
        event_coord  => "31922:${PK}:test",
        status       => 'declined',
        fb           => 'busy',
    );
    my @fb = grep { $_->[0] eq 'fb' } @{$event->tags};
    is(scalar @fb, 0, 'fb omitted when declined');
};

# Spec: p tag (optional) pubkey of calendar event author
subtest 'rsvp: p tag (optional)' => sub {
    my $author = 'b' x 64;
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey           => $PK,

t/nip/52.t  view on Meta::CPAN

    my $eid = 'b' x 64;
    my $author = 'c' x 64;
    my $event = Net::Nostr::Calendar->rsvp(
        pubkey             => $PK,
        identifier         => 'random-identifier',
        event_coord        => "31922:${author}:d-identifier",
        event_relay        => 'wss://relay.example.com',
        event_id           => $eid,
        event_id_relay     => 'wss://relay.example.com',
        status             => 'accepted',
        fb                 => 'busy',
        event_author       => $author,
        event_author_relay => 'wss://relay.example.com',
        content            => 'note',
    );

    is($event->kind, 31925, 'kind');
    is($event->content, 'note', 'content');

    my @e = grep { $_->[0] eq 'e' } @{$event->tags};
    is($e[0][1], $eid, 'e tag');

t/nip/52.t  view on Meta::CPAN

    my @a = grep { $_->[0] eq 'a' } @{$event->tags};
    is($a[0][1], "31922:${author}:d-identifier", 'a tag');

    my @d = grep { $_->[0] eq 'd' } @{$event->tags};
    is($d[0][1], 'random-identifier', 'd');

    my @s = grep { $_->[0] eq 'status' } @{$event->tags};
    is($s[0][1], 'accepted', 'status');

    my @fb = grep { $_->[0] eq 'fb' } @{$event->tags};
    is($fb[0][1], 'busy', 'fb');

    my @p = grep { $_->[0] eq 'p' } @{$event->tags};
    is($p[0][1], $author, 'p tag');
};

###############################################################################
# from_event: round-trip parsing
###############################################################################

subtest 'from_event: date event round-trip' => sub {



( run in 1.891 second using v1.01-cache-2.11-cpan-39bf76dae61 )