Current section
Files
Jump to
Current section
Files
lib/nostr/event/client_auth.ex
defmodule Nostr.Event.ClientAuth do
@moduledoc """
Client authentication
Defined in NIP 42
https://github.com/nostr-protocol/nips/blob/master/42.md
"""
@moduledoc tags: [:event, :nip42], nip: 42
defstruct [:event, :relay, :challenge]
@type t() :: %__MODULE__{
event: Nostr.Event.t(),
challenge: String.t(),
relay: URI.t()
}
@doc """
Create a new ClientAuth event for authentication.
## Arguments:
- `relay` - the relay URL to authenticate with
- `challenge` - the challenge string received from the relay
- `opts` - other optional event arguments (`pubkey`, `created_at`, `tags`)
## Example:
iex> auth = Nostr.Event.ClientAuth.create("wss://relay.example.com", "challenge123")
iex> auth.relay
"wss://relay.example.com"
iex> auth.challenge
"challenge123"
iex> auth.event.kind
22242
"""
@spec create(relay :: String.t(), challenge :: String.t(), opts :: Keyword.t()) :: t()
def create(relay, challenge, opts \\ []) do
tags = [
Nostr.Tag.create(:relay, relay),
Nostr.Tag.create(:challenge, challenge)
]
opts = Keyword.update(opts, :tags, tags, &(tags ++ &1))
22_242
|> Nostr.Event.create(opts)
|> parse()
end
@doc "Parses a kind 22242 event into a `ClientAuth` struct with relay and challenge."
@spec parse(event :: Nostr.Event.t()) :: __MODULE__.t()
def parse(%Nostr.Event{kind: 22_242} = event) do
%__MODULE__{
event: event,
relay: get_tag(event, :relay),
challenge: get_tag(event, :challenge)
}
end
defp get_tag(%Nostr.Event{tags: tags}, tag) do
tags
|> Enum.find(&(&1.type == tag))
|> Map.get(:data)
end
end