Nostr.NIP21 (Nostr Lib v0.2.1)

View Source

NIP-21: nostr: URI scheme.

This module provides encoding and decoding of nostr: URIs, which wrap NIP-19 bech32 identifiers for maximum interoperability.

Supported identifiers:

  • npub - public keys
  • nprofile - profiles with relay hints
  • note - event IDs
  • nevent - events with relay hints
  • naddr - addressable event coordinates

Note: nsec (private keys) are explicitly not supported in URIs for security reasons.

Examples

iex> Nostr.NIP21.to_uri("npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6")
{:ok, "nostr:npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6"}

iex> Nostr.NIP21.parse("nostr:npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6")
{:ok, :npub, "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"}

Summary

Functions

Creates a nostr: URI for an addressable event coordinate.

Creates a nostr: URI for an event with optional metadata.

Creates a nostr: URI for an event ID.

Creates a nostr: URI for a profile with optional relay hints.

Creates a nostr: URI for a public key.

Parses a nostr: URI and returns the decoded entity.

Converts a bech32-encoded NIP-19 string to a nostr: URI.

Functions

encode_naddr(identifier, pubkey, kind, relays \\ [])

@spec encode_naddr(String.t(), String.t(), non_neg_integer(), [String.t()]) ::
  {:ok, String.t()} | {:error, term()}

Creates a nostr: URI for an addressable event coordinate.

Examples

iex> Nostr.NIP21.encode_naddr("my-article", "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", 30023)
{:ok, "nostr:naddr1..."}

encode_nevent(event_id, opts \\ [])

@spec encode_nevent(
  String.t(),
  keyword()
) :: {:ok, String.t()} | {:error, term()}

Creates a nostr: URI for an event with optional metadata.

Options

  • :relays - list of relay URLs
  • :author - hex-encoded author public key
  • :kind - event kind number

Examples

iex> Nostr.NIP21.encode_nevent("b9f5441e45ca39179320e0031cfb18e34078673dcc3d3e3a3b3a981571b14f4e", relays: ["wss://relay.example.com"])
{:ok, "nostr:nevent1..."}

encode_note(event_id)

@spec encode_note(String.t()) :: {:ok, String.t()} | {:error, term()}

Creates a nostr: URI for an event ID.

Examples

iex> Nostr.NIP21.encode_note("b9f5441e45ca39179320e0031cfb18e34078673dcc3d3e3a3b3a981571b14f4e")
{:ok, "nostr:note1..."}

encode_nprofile(pubkey, relays \\ [])

@spec encode_nprofile(String.t(), [String.t()]) ::
  {:ok, String.t()} | {:error, term()}

Creates a nostr: URI for a profile with optional relay hints.

Examples

iex> Nostr.NIP21.encode_nprofile("3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d", ["wss://relay.example.com"])
{:ok, "nostr:nprofile1..."}

encode_npub(pubkey)

@spec encode_npub(String.t()) :: {:ok, String.t()} | {:error, term()}

Creates a nostr: URI for a public key.

Examples

iex> Nostr.NIP21.encode_npub("3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d")
{:ok, "nostr:npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6"}

parse(arg1)

@spec parse(String.t()) ::
  {:ok, :npub | :note, String.t()}
  | {:ok, :nprofile, Nostr.NIP19.Profile.t()}
  | {:ok, :nevent, Nostr.NIP19.Event.t()}
  | {:ok, :naddr, Nostr.NIP19.Address.t()}
  | {:error, :nsec_not_allowed | :invalid_uri_scheme | term()}

Parses a nostr: URI and returns the decoded entity.

Returns the same result as Nostr.NIP19.decode/1, but rejects nsec URIs.

Examples

iex> Nostr.NIP21.parse("nostr:npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6")
{:ok, :npub, "3bf0c63fcb93463407af97a5e5ee64fa883d107ef9e558472c4eb9aaaefa459d"}

iex> Nostr.NIP21.parse("nostr:nsec1...")
{:error, :nsec_not_allowed}

iex> Nostr.NIP21.parse("https://example.com")
{:error, :invalid_uri_scheme}

to_uri(bech32)

@spec to_uri(String.t()) :: {:ok, String.t()} | {:error, :nsec_not_allowed | term()}

Converts a bech32-encoded NIP-19 string to a nostr: URI.

Returns {:error, :nsec_not_allowed} if attempting to create a URI from a private key.

Examples

iex> Nostr.NIP21.to_uri("npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6")
{:ok, "nostr:npub180cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsyjh6w6"}

iex> Nostr.NIP21.to_uri("nsec1...")
{:error, :nsec_not_allowed}