Nostr.NIP30 (Nostr Lib v0.2.1) (nip30)

View Source

Custom Emoji helpers (NIP-30)

Custom emoji may be added to kind 0, kind 1, kind 7, and kind 30315 events by including emoji tags in the form: ["emoji", shortcode, image-url]

Shortcodes must be alphanumeric characters and underscores only. Clients parse :shortcode: patterns in content to display custom emoji.

Examples

# Create emoji tags from a map
NIP30.build_tags(%{"wave" => "https://example.com/wave.png"})

# Extract emoji map from event tags
NIP30.from_tags(event.tags)
# => %{"wave" => "https://example.com/wave.png"}

# Find shortcodes in content
NIP30.extract_shortcodes("Hello :wave: world!")
# => ["wave"]

Defined in NIP 30 https://github.com/nostr-protocol/nips/blob/master/30.md

Summary

Functions

Builds emoji tags from a map or list of emoji definitions.

Extracts all :shortcode: patterns from content text.

Extracts emoji tags from a list of tags into a map of shortcode => url.

Checks if content contains any :shortcode: patterns.

Creates a single emoji tag.

Validates if a shortcode has valid format (alphanumeric + underscore only).

Functions

build_tags(emojis)

@spec build_tags(map() | Keyword.t() | [{binary(), binary()}]) :: [Nostr.Tag.t()]

Builds emoji tags from a map or list of emoji definitions.

Accepts:

  • Map: %{"shortcode" => "url", ...}
  • Keyword list: [shortcode: "url", ...]
  • List of tuples: [{"shortcode", "url"}, ...]

Examples

iex> Nostr.NIP30.build_tags(%{"wave" => "https://example.com/wave.png"})
[%Nostr.Tag{type: :emoji, data: "wave", info: ["https://example.com/wave.png"]}]

iex> Nostr.NIP30.build_tags([{"smile", "https://example.com/smile.png"}])
[%Nostr.Tag{type: :emoji, data: "smile", info: ["https://example.com/smile.png"]}]

extract_shortcodes(content)

@spec extract_shortcodes(binary()) :: [binary()]

Extracts all :shortcode: patterns from content text.

Returns a list of shortcodes (without the colons).

Examples

iex> Nostr.NIP30.extract_shortcodes("Hello :wave: and :smile:!")
["wave", "smile"]

iex> Nostr.NIP30.extract_shortcodes("No emojis here")
[]

from_tags(tags)

@spec from_tags([Nostr.Tag.t()]) :: %{required(binary()) => binary()}

Extracts emoji tags from a list of tags into a map of shortcode => url.

Examples

iex> tags = [
...>   %Nostr.Tag{type: :emoji, data: "wave", info: ["https://example.com/wave.png"]},
...>   %Nostr.Tag{type: :p, data: "pubkey123", info: []}
...> ]
iex> Nostr.NIP30.from_tags(tags)
%{"wave" => "https://example.com/wave.png"}

has_emojis?(content)

@spec has_emojis?(binary()) :: boolean()

Checks if content contains any :shortcode: patterns.

Examples

iex> Nostr.NIP30.has_emojis?("Hello :wave:!")
true

iex> Nostr.NIP30.has_emojis?("No emojis here")
false

to_tag(shortcode, url)

@spec to_tag(binary(), binary()) :: Nostr.Tag.t()

Creates a single emoji tag.

Examples

iex> Nostr.NIP30.to_tag("wave", "https://example.com/wave.png")
%Nostr.Tag{type: :emoji, data: "wave", info: ["https://example.com/wave.png"]}

valid_shortcode?(shortcode)

@spec valid_shortcode?(binary()) :: boolean()

Validates if a shortcode has valid format (alphanumeric + underscore only).

Examples

iex> Nostr.NIP30.valid_shortcode?("wave")
true

iex> Nostr.NIP30.valid_shortcode?("my_emoji_123")
true

iex> Nostr.NIP30.valid_shortcode?("invalid-emoji")
false

iex> Nostr.NIP30.valid_shortcode?("has space")
false