defmodule Nostr.Models.Note.Id do
@moduledoc """
Note id conversion functions
"""
@hrp "note"
alias Nostr.Event
@doc """
Converts a note binary id into a bech32 format
## Examples
iex> <<0x2e4b14f5d54a4190c0101b87382db1ce5ef9ec5db39dc2265bac5bd9d91cded2::256>>
...> |> Nostr.Models.Note.Id.to_bech32()
"note19e93faw4ffqepsqsrwrnstd3ee00nmzakwwuyfjm43dankgummfqms4p6q"
iex> "2e4b14f5d54a4190c0101b87382db1ce5ef9ec5db39dc2265bac5bd9d91cded2"
...> |> Nostr.Models.Note.Id.to_bech32()
"note19e93faw4ffqepsqsrwrnstd3ee00nmzakwwuyfjm43dankgummfqms4p6q"
"""
@spec to_bech32(binary()) :: binary()
def to_bech32(note_id) do
Event.Id.to_bech32(note_id, @hrp)
end
@doc """
Converts a note binary id into a hex format
## Examples
iex> <<0x2e4b14f5d54a4190c0101b87382db1ce5ef9ec5db39dc2265bac5bd9d91cded2::256>>
...> |> Nostr.Models.Note.Id.to_hex()
{:ok, "2e4b14f5d54a4190c0101b87382db1ce5ef9ec5db39dc2265bac5bd9d91cded2"}
iex> "note19e93faw4ffqepsqsrwrnstd3ee00nmzakwwuyfjm43dankgummfqms4p6q"
...> |> Nostr.Models.Note.Id.to_hex()
{:ok, "2e4b14f5d54a4190c0101b87382db1ce5ef9ec5db39dc2265bac5bd9d91cded2"}
"""
@spec to_hex(<<_::256>> | String.t()) :: {:ok, <<_::512>>} | {:error, atom()}
def to_hex(@hrp <> _ = bech32_note_id) do
case Event.Id.to_hex(bech32_note_id) do
{:ok, @hrp, <<_::512>> = id} -> {:ok, id}
{:ok, type, _id} -> {:error, "tried to convert a bech32 #{type} id into a note"}
{:error, message} -> {:error, message}
end
end
def to_hex(note_id) do
{:ok, _, hex} = Event.Id.to_hex(note_id)
{:ok, hex}
end
@doc """
Converts a bech32 note id into a hex string format
## Examples
iex> "note19e93faw4ffqepsqsrwrnstd3ee00nmzakwwuyfjm43dankgummfqms4p6q"
...> |> Nostr.Models.Note.Id.to_hex!
"2e4b14f5d54a4190c0101b87382db1ce5ef9ec5db39dc2265bac5bd9d91cded2"
"""
@spec to_hex!(binary()) :: <<_::512>>
def to_hex!(@hrp <> _ = bech32_note_id) do
Event.Id.to_hex!(bech32_note_id)
end
@doc """
Converts a bech32 note id into its binary format
## Examples
iex> "note19e93faw4ffqepsqsrwrnstd3ee00nmzakwwuyfjm43dankgummfqms4p6q"
...> |> Nostr.Models.Note.Id.from_bech32
{:ok, <<0x2e4b14f5d54a4190c0101b87382db1ce5ef9ec5db39dc2265bac5bd9d91cded2::256>>}
"""
@spec from_bech32(binary()) :: {:ok, binary()} | {:error, atom()}
def from_bech32(@hrp <> _ = bech32_note_id) do
case Event.Id.from_bech32(bech32_note_id) do
{:ok, @hrp, id} -> {:ok, id}
{:ok, type, _id} -> {:error, "tried to convert a bech32 #{type} id into a note"}
{:error, message} -> {:error, message}
end
end
@doc """
Converts a bech32 note id into its binary format
## Examples
iex> "note19e93faw4ffqepsqsrwrnstd3ee00nmzakwwuyfjm43dankgummfqms4p6q"
...> |> Nostr.Models.Note.Id.from_bech32!
<<0x2e4b14f5d54a4190c0101b87382db1ce5ef9ec5db39dc2265bac5bd9d91cded2::256>>
"""
@spec from_bech32!(binary()) :: <<_::256>>
def from_bech32!(@hrp <> _ = bech32_note_id) do
Event.Id.from_bech32!(bech32_note_id)
end
@doc """
Does its best to convert any note id format to binary, issues an error if it can't
## Examples
iex> "note1qkjgra6cm5ms6m88kqdapfjnxm8q50lcurevtpvm4f6pfs8j5sxq90f098"
...> |> Nostr.Models.Note.Id.to_binary()
{ :ok, <<0x05a481f758dd370d6ce7b01bd0a65336ce0a3ff8e0f2c5859baa7414c0f2a40c::256>> }
"""
@spec to_binary(<<_::256>> | String.t() | list()) ::
{:ok, <<_::256>>} | {:ok, list(<<_::256>>)} | {:error, String.t()}
def to_binary(<<_::256>> = note_id), do: {:ok, note_id}
def to_binary("note" <> _ = note_id), do: from_bech32(note_id)
def to_binary(note_ids) when is_list(note_ids) do
note_ids
|> Enum.reverse()
|> Enum.reduce({:ok, []}, fn note_id, acc ->
case acc do
{:ok, binary_note_ids} ->
case to_binary(note_id) do
{:ok, binary_note_id} ->
{:ok, [binary_note_id | binary_note_ids]}
{:error, message} ->
{:error, message}
end
{:error, message} ->
{:error, message}
end
end)
end
def to_binary(not_lowercase_bech32_note_id) do
case String.downcase(not_lowercase_bech32_note_id) do
"note" <> _ = bech32_note_id -> from_bech32(bech32_note_id)
_ -> {:error, "#{not_lowercase_bech32_note_id} is not a valid note id"}
end
end
end