NAME

Net::Nostr::ExternalId - NIP-73 External Content IDs

SYNOPSIS

use Net::Nostr::ExternalId;

# Build i/k tag pairs for an event
my ($i, $k) = Net::Nostr::ExternalId->url_tags(
    'https://myblog.example.com/post/2012-03-27/hello-world',
);
# $i = ['i', 'https://myblog.example.com/post/2012-03-27/hello-world']
# $k = ['k', 'web']

my ($i, $k) = Net::Nostr::ExternalId->isbn_tags('978-0-7653-8203-0');
# $i = ['i', 'isbn:9780765382030']  (hyphens stripped)

my ($i, $k) = Net::Nostr::ExternalId->geo_tags('EZS42E44YX96');
# $i = ['i', 'geo:ezs42e44yx96']  (lowercased)

my ($i, $k) = Net::Nostr::ExternalId->country_tags('ve');
# $i = ['i', 'iso3166:VE']  (uppercased)

# Optional URL hint (MAY)
my ($i, $k) = Net::Nostr::ExternalId->isan_tags(
    '0000-0000-401A-0000-7',
    hint => 'https://www.imdb.com/title/tt0120737',
);
# $i = ['i', 'isan:0000-0000-401A-0000-7', 'https://www.imdb.com/title/tt0120737']

# Parse an i tag value
my $parsed = Net::Nostr::ExternalId->parse('isbn:9780765382030');
# { type => 'isbn', value => '9780765382030' }

# Derive the k tag kind from an i tag value
my $kind = Net::Nostr::ExternalId->kind_for('geo:ezs42e44yx96');
# 'geo'

DESCRIPTION

Implements NIP-73 (External Content IDs). Provides builders for i/k tag pairs that reference external content identifiers, a parser to decompose i tag values, and a helper to derive the k tag kind.

i tags reference external content IDs. k tags represent the external content ID kind so clients can query all events for a specific kind.

Each builder normalizes its input per the spec requirements:

  • ISBN hyphens are stripped (MUST)

  • Geohashes are lowercased (MUST)

  • ISO 3166 codes are uppercased (MUST)

  • DOI identifiers are lowercased

  • Hashtag topics are lowercased

  • URL fragments are stripped

  • Blockchain transaction IDs are lowercased (hex)

  • Ethereum addresses are lowercased (hex)

Each i tag MAY include a URL hint as an optional third element to redirect people to a website if the client isn't opinionated about how to interpret the id. Pass hint => $url to any builder.

CONSTRUCTOR

new

my $id = Net::Nostr::ExternalId->new(
    type  => 'isbn',
    value => '9780765382030',
);

Creates a new Net::Nostr::ExternalId object. Croaks on unknown arguments.

CLASS METHODS

url_tags

my ($i, $k) = Net::Nostr::ExternalId->url_tags($url, hint => $hint);

Returns i/k tag pair for a URL. Fragments are stripped per the spec. The k tag kind is "web".

isbn_tags

my ($i, $k) = Net::Nostr::ExternalId->isbn_tags($isbn, hint => $hint);

Returns i/k tag pair for a book ISBN. Hyphens are stripped per the spec requirement that ISBNs MUST be referenced without hyphens. The k tag kind is "isbn".

geo_tags

my ($i, $k) = Net::Nostr::ExternalId->geo_tags($geohash, hint => $hint);

Returns i/k tag pair for a geohash. The value is lowercased per the spec requirement that geohashes MUST be lowercase. The k tag kind is "geo".

country_tags

my ($i, $k) = Net::Nostr::ExternalId->country_tags($code, hint => $hint);

Returns i/k tag pair for an ISO 3166 country or subdivision code (e.g. "VE", "US-CA"). The code is uppercased per the spec requirement that ISO 3166 codes MUST be uppercase. The k tag kind is "iso3166".

isan_tags

my ($i, $k) = Net::Nostr::ExternalId->isan_tags($isan, hint => $hint);

Returns i/k tag pair for a movie ISAN. ISANs SHOULD be referenced without the version part. The k tag kind is "isan".

doi_tags

my ($i, $k) = Net::Nostr::ExternalId->doi_tags($doi, hint => $hint);

Returns i/k tag pair for a paper DOI. The DOI is lowercased. The k tag kind is "doi".

hashtag_tags

my ($i, $k) = Net::Nostr::ExternalId->hashtag_tags($topic, hint => $hint);

Returns i/k tag pair for a hashtag. The topic is lowercased. The i value is prefixed with #. The k tag kind is "#".

podcast_feed_tags

my ($i, $k) = Net::Nostr::ExternalId->podcast_feed_tags($guid, hint => $hint);

Returns i/k tag pair for a podcast RSS feed GUID. The k tag kind is "podcast:guid".

podcast_episode_tags

my ($i, $k) = Net::Nostr::ExternalId->podcast_episode_tags($guid, hint => $hint);

Returns i/k tag pair for a podcast RSS item GUID. The k tag kind is "podcast:item:guid".

podcast_publisher_tags

my ($i, $k) = Net::Nostr::ExternalId->podcast_publisher_tags($guid, hint => $hint);

Returns i/k tag pair for a podcast RSS publisher GUID. The k tag kind is "podcast:publisher:guid".

blockchain_tx_tags

my ($i, $k) = Net::Nostr::ExternalId->blockchain_tx_tags(
    $blockchain, $txid, chain_id => $chain_id, hint => $hint,
);

Returns i/k tag pair for a blockchain transaction. $blockchain is the chain name (e.g. "bitcoin", "ethereum"). $txid is lowercased (hex). If chain_id is provided (e.g. for Ethereum), it is included in the identifier. The k tag kind is "$blockchain:tx".

blockchain_address_tags

my ($i, $k) = Net::Nostr::ExternalId->blockchain_address_tags(
    $blockchain, $address, chain_id => $chain_id, hint => $hint,
);

Returns i/k tag pair for a blockchain address. Bitcoin base58 addresses are case-sensitive; Bitcoin bech32 and Ethereum hex addresses are lowercase. If chain_id is provided, it is included in the identifier. The k tag kind is "$blockchain:address".

parse

my $parsed = Net::Nostr::ExternalId->parse($i_tag_value);

Parses an i tag value and returns a hashref with type (the k tag kind) and value (the extracted identifier). For blockchain types, blockchain and chain_id are also included. Returns undef for unrecognized formats.

kind_for

my $kind = Net::Nostr::ExternalId->kind_for($i_tag_value);

Returns the k tag kind string for a given i tag value. This is a convenience wrapper around "parse". Returns undef for unrecognized formats.

ACCESSORS

type

The external content ID type (k tag kind value).

value

The extracted identifier value.

blockchain

The blockchain name (for blockchain types only).

chain_id

The chain ID (for blockchain types with a chain ID, e.g. Ethereum).

hint

An optional URL hint.

SEE ALSO

NIP-73, Net::Nostr, Net::Nostr::Metadata