View Source GenNostr behaviour (GenNostr v0.1.0)
A low level websocket client that implements the Nostr protocol.
It works like a GenServer.
architecture
Architecture
The GenNostr process spawn a PrimarySupervisor with a ConnectionRegistry and a ConnectionSupervisor (DynamicSupervisor) that supervises connections. The ConnectionRegistry store the url as key to avoid connections to same relay.
The GenNostr process is the client and the websocket processes are then
connections. The client send commands to connections. The connections emit
events that can to be generated by the commands or by websocket messages
and sends back the response to client through handlers.
Link to this section Summary
Callbacks
Invoked when a gen_nostr connection receives a AUTH message (NIP-42).
Invoked when a GenNostr process receives a GenServer call.
Invoked when a GenNostr process receives a GenServer cast.
Invoked when a connection has been established to a relay.
Invoked when a GenNostr process receives a message.
Invoked when a gen_nostr connection is disconected from relay.
Invoked when a gen_nostr connection receives a EOSE message (NIP-15).
Invoked when a gen_nostr connection has a error and can trigger a
handle_disconnect/3 if the error close the connection.
Invoked when a gen_nostr connection receives a EVENT message (NIP-01).
Invoked when a GenNostr process receives a message.
Invoked when a gen_nostr connection receives a NOTICE message (NIP-01).
Invoked when a gen_nostr connection receives a OK message (NIP-20).
Invoked when the gen_nostr process starts.
Invoked when a GenNostr process is terminated.
Functions
Crate a new connection to relay.
Send a broadcast message to connected relays.
Relay url list of all current connections.
Tries to reconnect after a disconnection.
Finishes the connection and removes the relay.
Send a message to the specified url or relay.
Starts a GenNostr client process.
Link to this section Callbacks
@callback handle_auth(auth_msg :: term(), relay :: GenNostr.Relay.t(), state :: term()) :: {:ok, new_state} | {:stop, new_state} | {:stop, reason :: term(), new_state} when new_state: term()
Invoked when a gen_nostr connection receives a AUTH message (NIP-42).
@callback handle_call( request :: term(), from :: GenServer.from(), state :: term() ) :: {:reply, reply, new_state} | {:reply, reply, new_state, timeout() | :hibernate | {:continue, term()}} | {:noreply, new_state} | {:noreply, new_state, timeout() | :hibernate | {:continue, term()}} | {:stop, reason, new_state} | {:stop, reason, reply, new_state} when new_state: term(), reply: term(), reason: term()
Invoked when a GenNostr process receives a GenServer call.
Behaves the same as GenServer.handle_call/3
@callback handle_cast(request :: term(), state :: term()) :: {:noreply, new_state} | {:noreply, new_state, timeout() | :hibernate | {:continue, term()}} | {:stop, reason :: term(), new_state} when new_state: term()
Invoked when a GenNostr process receives a GenServer cast.
Behaves the same as GenServer.handle_cast/2
@callback handle_connect(relay :: GenNostr.Relay.t(), state :: term()) :: {:ok, new_state} | {:stop, reason :: term(), new_state} when new_state: term()
Invoked when a connection has been established to a relay.
@callback handle_continue(continue_arg, state :: term()) :: {:noreply, new_state} | {:noreply, new_state, timeout() | :hibernate | {:continue, continue_arg}} | {:stop, reason :: term(), new_state} when new_state: term(), continue_arg: term()
Invoked when a GenNostr process receives a message.
Behaves the same as GenServer.handle_continue/2
@callback handle_disconnect( reason :: term(), relay :: GenNostr.Relay.t(), state :: term() ) :: {:ok, new_state} | {:stop, stop_reason :: term(), new_state} when new_state: term()
Invoked when a gen_nostr connection is disconected from relay.
@callback handle_eose(eose_msg :: term(), relay :: GenNostr.Relay.t(), state :: term()) :: {:ok, new_state} | {:stop, new_state} | {:stop, reason :: term(), new_state} when new_state: term()
Invoked when a gen_nostr connection receives a EOSE message (NIP-15).
@callback handle_error(reason :: term(), relay :: GenNostr.Relay.t(), state :: term()) :: {:ok, new_state} | {:stop, stop_reason :: term(), new_state} when new_state: term()
Invoked when a gen_nostr connection has a error and can trigger a
handle_disconnect/3 if the error close the connection.
@callback handle_event(event_msg :: term(), relay :: GenNostr.Relay.t(), state :: term()) :: {:ok, new_state} | {:stop, new_state} | {:stop, reason :: term(), new_state} when new_state: term()
Invoked when a gen_nostr connection receives a EVENT message (NIP-01).
@callback handle_info(msg :: :timeout | term(), state :: term()) :: {:noreply, new_state} | {:noreply, new_state, timeout() | :hibernate | {:continue, term()}} | {:stop, reason :: term(), new_state} when new_state: term()
Invoked when a GenNostr process receives a message.
Behaves the same as GenServer.handle_info/2
@callback handle_notice( notice_msg :: term(), relay :: GenNostr.Relay.t(), state :: term() ) :: {:ok, new_state} | {:stop, new_state} | {:stop, reason :: term(), new_state} when new_state: GenNostr.Relay.t()
Invoked when a gen_nostr connection receives a NOTICE message (NIP-01).
@callback handle_ok(ok_msg :: term(), relay :: GenNostr.Relay.t(), state :: term()) :: {:ok, new_state} | {:stop, new_state} | {:stop, reason :: term(), new_state} when new_state: term()
Invoked when a gen_nostr connection receives a OK message (NIP-20).
@callback init(init_arg :: term()) :: {:ok, state} | {:ok, state, timeout() | :hibernate | {:continue, continue_arg :: term()}} | :ignore | {:stop, reason :: any()} when state: term()
Invoked when the gen_nostr process starts.
Behaves the same as GenServer.init/1
@impl GenNostr
def init(args) do
relays = Keyword.get(args, :relays, [])
options = Keyword.get(args, :options, [])
Enum.each(relays, &GenNostr.add_relay(&1, options))
{:ok, %{}}
end
@callback terminate(reason, state :: term()) :: term() when reason: :normal | :shutdown | {:shutdown, term()} | term()
Invoked when a GenNostr process is terminated.
Note that this callback is not always invoked as the process shuts down.
See GenServer.terminate/2 for more information.
Link to this section Functions
Crate a new connection to relay.
options
Options
:mint- keyword list of specific options of elixir mint, default to[protocols: [:http1]]:reconnect- timeouts list in msec used byreconnect/1, default to[500, 1_000, 5_000, 10_000, 30_000]:tasks- keyword list of recurring timeout tasks in msec, default to[garbage_collector: 60 * 60 * 1000]
examples
Examples
# using a url and default options
GenNostr.add_relay("wss://relay.com/")
# using the Relay struct and default options
GenNostr.Relay.new(url: "wss://relay.com/")
|> GenNostr.add_relay()
Send a broadcast message to connected relays.
@spec list_relays() :: [String.t()]
Relay url list of all current connections.
@spec reconnect(GenNostr.Relay.t()) :: term()
Tries to reconnect after a disconnection.
This function must be used within handle_disconnect/3.
examples
Examples
@impl GenNostr
def handle_disconnect(reason, relay, state) do
Logger.info("Disconnected from relay")
# don't reconnect if the :remove_relay is the reason
case reason do
:remove_relay -> Logger.info("Don't reconnect")
_ -> GenNostr.reconnect(relay)
end
{:ok, state}
end
Finishes the connection and removes the relay.
This function invokes handle_disconnect/3 and receive a reason of :remove_relay
examples
Examples
# using a url and default options
GenNostr.remove_relay("wss://relay.com/")
# using the Relay struct and default options
GenNostr.Relay.new(url: "wss://relay.com/")
|> GenNostr.remove_relay()
Send a message to the specified url or relay.
@spec start_link(module(), term(), GenServer.options()) :: GenServer.on_start()
Starts a GenNostr client process.
This function return a GenServer.start_link/3
examples
Examples
defmodule NostrClient do
use GenNostr
def start_link(args) do
GenNostr.start_link(__MODULE__, args, name: __MODULE__)
end
end