NAME
Net::Nostr::AppHandler - NIP-89 recommended application handlers
SYNOPSIS
use Net::Nostr::AppHandler;
my $pubkey = 'aa' x 32;
my $app_pk = 'bb' x 32;
# Recommend an app for handling kind 31337 events
my $event = Net::Nostr::AppHandler->recommendation(
pubkey => $pubkey,
event_kind => '31337',
apps => [
{
coordinate => "31990:$app_pk:zapstr",
relay => 'wss://relay.example.com',
platform => 'web',
},
],
);
# Publish handler information for an app
my $handler = Net::Nostr::AppHandler->handler(
pubkey => $app_pk,
identifier => 'zapstr',
kinds => ['31337'],
content => '{"name":"Zapstr","picture":"https://example.com/icon.png"}',
platforms => [
{ platform => 'web', url => 'https://zapstr.live/a/<bech32>', entity => 'nevent' },
{ platform => 'web', url => 'https://zapstr.live/p/<bech32>', entity => 'nprofile' },
{ platform => 'ios', url => 'com.zapstr:///<bech32>' },
],
);
# Add a client tag to any event (MAY)
my $tag = Net::Nostr::AppHandler->client_tag(
name => 'My Client',
coordinate => "31990:$app_pk:my-client",
relay => 'wss://relay1',
);
# Parse a recommendation or handler event
my $info = Net::Nostr::AppHandler->from_event($event);
say $info->event_kind; # '31337'
# Query filters for discovery
my $filter = Net::Nostr::AppHandler->recommendation_filter(
event_kind => '31337',
authors => [$pubkey],
);
DESCRIPTION
Implements NIP-89 recommended application handlers. This NIP provides a way to discover applications that can handle unknown event kinds through two event types:
- Recommendations (kind 31989)
-
Addressable events where a user recommends one or more applications for handling a specific event kind. The
dtag contains the supported event kind, andatags reference handler information events. - Handler information (kind 31990)
-
Addressable events published by applications describing how to redirect users. Contains
ktags for supported event kinds and platform-specific URL templates with<bech32>placeholders that clients replace with NIP-19-encoded entities.
CONSTRUCTOR
new
my $info = Net::Nostr::AppHandler->new(%fields);
Creates a new Net::Nostr::AppHandler object. Typically returned by "from_event"; calling new directly is useful for testing or manual construction.
my $info = Net::Nostr::AppHandler->new(
event_kind => '31337',
apps => [],
kinds => [1, 30023],
);
Accepted fields: event_kind, identifier, kinds (defaults to []), content (defaults to ''), apps (defaults to []), platforms (defaults to []). Croaks on unknown arguments.
CLASS METHODS
recommendation
my $event = Net::Nostr::AppHandler->recommendation(
pubkey => $hex_pubkey, # required
event_kind => '31337', # required (d tag value)
apps => [ # optional
{
coordinate => '31990:pubkey:id', # required
relay => 'wss://...', # optional (SHOULD)
platform => 'web', # optional (SHOULD)
},
],
);
Creates a kind 31989 recommendation Net::Nostr::Event. pubkey and event_kind are required. Each app in the apps arrayref becomes an a tag. The relay and platform fields are optional but SHOULD be included per spec.
handler
my $event = Net::Nostr::AppHandler->handler(
pubkey => $hex_pubkey, # required
identifier => 'my-app', # required (d tag)
kinds => ['31337', '30023'], # required (k tags)
content => '{"name":"App"}', # optional (kind:0-style JSON)
platforms => [ # optional
{ platform => 'web', url => 'https://app.com/<bech32>', entity => 'nevent' },
{ platform => 'ios', url => 'com.app:///<bech32>' },
],
);
Creates a kind 31990 handler information Net::Nostr::Event. pubkey, identifier, and kinds are required.
The content field is an optional stringified JSON object with kind:0-style metadata. If empty, clients should use the pubkey's kind:0 profile instead.
Each entry in platforms becomes a platform tag. The entity field is an optional NIP-19 entity type (e.g. nevent, nprofile). A platform tag without an entity type is a generic handler for any NIP-19 entity.
client_tag
my $tag = Net::Nostr::AppHandler->client_tag(
name => 'My Client', # required
coordinate => '31990:pubkey:identifier', # required
relay => 'wss://relay.com', # optional
);
Creates a client tag arrayref suitable for inclusion in any event's tags. name and coordinate are required; croaks if either is missing. Clients MAY include this tag to identify themselves. This has privacy implications, so clients SHOULD allow users to opt out.
my $event = Net::Nostr::Event->new(
kind => 1,
pubkey => $pubkey,
content => 'Hello!',
tags => [$tag],
);
from_event
my $info = Net::Nostr::AppHandler->from_event($event);
Parses a kind 31989 or 31990 Net::Nostr::Event. Returns a Net::Nostr::AppHandler object with accessors, or undef if the event is not a handler kind.
For kind 31989 (recommendation), the returned object has event_kind and apps accessors.
For kind 31990 (handler), the returned object has identifier, kinds, content, and platforms accessors.
validate
Net::Nostr::AppHandler->validate($event);
Validates that an event is a well-formed NIP-89 event. Croaks if:
Kind is not 31989 or 31990
Missing
dtagKind 31990 missing
ktag
recommendation_filter
my $filter = Net::Nostr::AppHandler->recommendation_filter(
event_kind => '31337',
authors => [$user_pk, @follows],
);
Returns a hashref suitable for use as a Nostr filter to query for recommendations for a given event kind.
handler_filter
my $filter = Net::Nostr::AppHandler->handler_filter(
event_kind => '31337',
authors => [$app_pk],
);
Returns a hashref suitable for use as a Nostr filter to query for handler information for a given event kind.
ACCESSORS
These are available on objects returned by "from_event".
event_kind
my $kind = $info->event_kind; # '31337'
The event kind being recommended (from the d tag of kind 31989).
apps
my $apps = $info->apps;
# [{ coordinate => '31990:pk:id', relay => 'wss://...', platform => 'web' }]
Arrayref of hashrefs describing recommended apps (from a tags of kind 31989). Each hashref has a coordinate key, and optional relay and platform keys.
identifier
my $id = $info->identifier;
The d tag value identifying the handler (kind 31990).
kinds
my $kinds = $info->kinds; # ['31337', '30023']
Arrayref of supported event kind strings (from k tags of kind 31990).
content
my $json = $info->content; # '{"name":"Zapstr"}' or ''
The handler's metadata content (kind:0-style JSON string), or empty string.
platforms
my $platforms = $info->platforms;
# [{ platform => 'web', url => 'https://.../<bech32>', entity => 'nevent' }]
Arrayref of hashrefs describing platform handlers (kind 31990). Each hashref has platform and url keys. The entity key is optional and specifies the NIP-19 entity type the URL handles.