Skip to content

Commit 006e221

Browse files
authored
Merge pull request #4 from RooSoft/nostr_basics
Now using NostrBasics
2 parents a06bb8b + ea61a99 commit 006e221

File tree

98 files changed

+1503
-2109
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

98 files changed

+1503
-2109
lines changed

lib/examples/nostr_app/console_handler.ex

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,20 @@ defmodule NostrApp.ConsoleHandler do
4646
def handle(:transport_error, %{url: url, message: message}) do
4747
Logger.warning("transport error from #{url}: #{message}")
4848
end
49+
50+
def handle(:unknown_relay_message, %{url: url, message: message}) do
51+
Logger.warning("unknown relay message from #{url}: #{message}")
52+
end
53+
54+
def handle(:malformed_json_relay_message, %{url: url, message: message}) do
55+
Logger.warning("malformed JSON relay message from #{url}: #{message}")
56+
end
57+
58+
def handle(:ok, %{event_id: event_id, message: _message, success?: success?, url: url}) do
59+
Logger.info("#{url} sent #{event_id}: #{success?}")
60+
end
61+
62+
def handle(unknown_atom, data) do
63+
Logger.warning("got a #{unknown_atom}: #{inspect(data)}")
64+
end
4965
end

lib/examples/nostr_app/server.ex

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ defmodule NostrApp.Server do
99

1010
alias NostrApp.{ConsoleHandler, Subscribe}
1111

12+
alias NostrBasics.Keys.{PrivateKey, PublicKey}
13+
1214
alias Nostr.Client
13-
alias Nostr.Event.Types.{MetadataEvent, RecommendedServerEvent}
1415
alias Nostr.Models.{Profile}
15-
alias Nostr.Keys.{PrivateKey, PublicKey}
1616

1717
@impl true
1818
def init(%{relays: relays, private_key: private_key} = args) do
@@ -124,7 +124,7 @@ defmodule NostrApp.Server do
124124
@impl true
125125
def handle_cast({:delete, event_ids, note}, %{private_key: private_key} = socket) do
126126
case Client.delete_events(event_ids, note, private_key) do
127-
{:ok, _} -> Logger.info("sent a deletion command for #{event_ids}")
127+
{:ok, _} -> Logger.info("sent a deletion command for #{inspect(event_ids)}")
128128
{:error, message} -> Logger.error(message)
129129
end
130130

@@ -277,13 +277,6 @@ defmodule NostrApp.Server do
277277
{:noreply, socket}
278278
end
279279

280-
@impl true
281-
def handle_info({relay, %MetadataEvent{} = event}, socket) do
282-
Logger.info("From #{relay}, got a profile: #{inspect(event)}")
283-
284-
{:noreply, socket}
285-
end
286-
287280
@impl true
288281
def handle_info({relay, event}, socket) do
289282
# credo:disable-for-next-line
@@ -294,13 +287,6 @@ defmodule NostrApp.Server do
294287
{:noreply, socket}
295288
end
296289

297-
@impl true
298-
def handle_info(%RecommendedServerEvent{relay: relay, event: event}, socket) do
299-
IO.puts("#{relay} is recommended by #{event.pubkey |> PublicKey.to_npub()}")
300-
301-
{:noreply, socket}
302-
end
303-
304290
@impl true
305291
def handle_info(event, socket) do
306292
# credo:disable-for-next-line

lib/nostr/client.ex

Lines changed: 21 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ defmodule Nostr.Client do
77

88
require Logger
99

10-
alias Nostr.Event
11-
alias Nostr.Keys.{PublicKey, PrivateKey}
12-
alias Nostr.Event.{Signer, Validator}
13-
alias Nostr.Event.Types.{EncryptedDirectMessageEvent, TextEvent}
10+
alias NostrBasics.{Event}
11+
alias NostrBasics.Keys.{PublicKey, PrivateKey}
12+
1413
alias Nostr.Models.{Profile, Note}
1514
alias Nostr.Client.Relays.RelayManager
15+
alias Nostr.Client.Tasks
1616

1717
alias Nostr.Client.Subscriptions.{
1818
ProfileSubscription,
@@ -36,9 +36,6 @@ defmodule Nostr.Client do
3636
UpdateProfile
3737
}
3838

39-
alias Nostr.Crypto.AES256CBC
40-
alias Nostr.Client.Relays.RelaySocket
41-
4239
@default_config {}
4340

4441
@doc """
@@ -184,29 +181,11 @@ defmodule Nostr.Client do
184181
Sends an encrypted direct message
185182
"""
186183
@spec send_encrypted_direct_messages(PublicKey.id(), String.t(), PrivateKey.id()) ::
187-
:ok | {:error, binary()}
184+
:ok | {:error, String.t()}
188185
def send_encrypted_direct_messages(remote_pubkey, message, private_key) do
189-
with {:ok, binary_remote_pubkey} <- PublicKey.to_binary(remote_pubkey),
190-
{:ok, binary_private_key} <- PrivateKey.to_binary(private_key),
191-
{:ok, binary_local_pubkey} <- PublicKey.from_private_key(binary_private_key),
192-
encrypted_message = AES256CBC.encrypt(message, binary_private_key, binary_remote_pubkey),
193-
dm_event =
194-
EncryptedDirectMessageEvent.create(
195-
encrypted_message,
196-
binary_local_pubkey,
197-
binary_remote_pubkey
198-
),
199-
{:ok, signed_event} <- Signer.sign_event(dm_event.event, private_key),
200-
:ok <- Validator.validate_event(signed_event) do
201-
for relay_pid <- RelayManager.active_pids() do
202-
RelaySocket.send_event(relay_pid, signed_event)
203-
end
204-
205-
:ok
206-
else
207-
{:error, message} when is_atom(message) -> Atom.to_string(message)
208-
{:error, message} -> {:error, message}
209-
end
186+
relay_pids = RelayManager.active_pids()
187+
188+
Tasks.SendEncryptedDirectMessage.execute(message, remote_pubkey, private_key, relay_pids)
210189
end
211190

212191
@doc """
@@ -215,7 +194,7 @@ defmodule Nostr.Client do
215194
@spec subscribe_note(Note.id()) :: DynamicSupervisor.on_start_child()
216195
def subscribe_note(note_id) do
217196
case Event.Id.to_binary(note_id) do
218-
{:ok, "note", binary_note_id} ->
197+
{:ok, binary_note_id} ->
219198
DynamicSupervisor.start_child(
220199
Nostr.Subscriptions,
221200
{NoteSubscription, [RelayManager.active_pids(), binary_note_id, self()]}
@@ -227,9 +206,9 @@ defmodule Nostr.Client do
227206
end
228207

229208
@doc """
230-
Get an author's notes
209+
Get a list of author's notes
231210
"""
232-
@spec subscribe_notes(list(Note.id())) ::
211+
@spec subscribe_notes(list(Note.id()) | Note.id()) ::
233212
{:ok, DynamicSupervisor.on_start_child()} | {:error, String.t()}
234213
def subscribe_notes(pubkeys) when is_list(pubkeys) do
235214
case PublicKey.to_binary(pubkeys) do
@@ -247,14 +226,18 @@ defmodule Nostr.Client do
247226
end
248227
end
249228

229+
def subscribe_notes(pubkey) do
230+
subscribe_notes([pubkey])
231+
end
232+
250233
@doc """
251234
Deletes events
252235
"""
253236
@spec delete_events(list(Note.id()), String.t(), PrivateKey.id()) ::
254237
{:ok, GenServer.on_start()} | {:error, String.t()}
255238
def delete_events(note_ids, note, privkey) do
256239
with {:ok, binary_privkey} <- PrivateKey.to_binary(privkey),
257-
{:ok, "note", binary_note_ids} <- Event.Id.to_binary(note_ids) do
240+
{:ok, binary_note_ids} <- Event.Id.to_binary(note_ids) do
258241
{:ok,
259242
DeleteEvents.start_link(RelayManager.active_pids(), binary_note_ids, note, binary_privkey)}
260243
else
@@ -285,7 +268,7 @@ defmodule Nostr.Client do
285268
@spec repost(Note.id(), PrivateKey.id()) :: {:ok, GenServer.on_start()} | {:error, String.t()}
286269
def repost(note_id, privkey) do
287270
with {:ok, binary_privkey} <- PrivateKey.to_binary(privkey),
288-
{:ok, "note", binary_note_id} <- Event.Id.to_binary(note_id) do
271+
{:ok, binary_note_id} <- Event.Id.to_binary(note_id) do
289272
{:ok, SendRepost.start_link(RelayManager.active_pids(), binary_note_id, binary_privkey)}
290273
else
291274
{:error, message} -> {:error, message}
@@ -352,27 +335,16 @@ defmodule Nostr.Client do
352335
"""
353336
@spec send_note(String.t(), PrivateKey.id()) :: :ok | {:error, String.t()}
354337
def send_note(note, privkey) do
355-
with {:ok, binary_privkey} <- PrivateKey.to_binary(privkey),
356-
{:ok, pubkey} <- PublicKey.from_private_key(privkey),
357-
text_event = TextEvent.create(note, pubkey),
358-
{:ok, signed_event} <- Signer.sign_event(text_event.event, binary_privkey),
359-
:ok <- Validator.validate_event(signed_event) do
360-
for relay_pid <- RelayManager.active_pids() do
361-
RelaySocket.send_event(relay_pid, signed_event)
362-
end
363-
364-
:ok
365-
else
366-
{:error, message} when is_atom(message) -> {:error, Atom.to_string(message)}
367-
{:error, message} -> {:error, message}
368-
end
338+
relay_pids = RelayManager.active_pids()
339+
340+
Tasks.SendNote.execute(note, privkey, relay_pids)
369341
end
370342

371343
@spec react(Note.id(), PrivateKey.id(), String.t()) ::
372344
{:ok, GenServer.on_start()} | {:error, String.t()}
373345
def react(note_id, privkey, content \\ "+") do
374346
with {:ok, binary_privkey} <- PrivateKey.to_binary(privkey),
375-
{:ok, "note", binary_note_id} <- Event.Id.to_binary(note_id) do
347+
{:ok, binary_note_id} <- Event.Id.to_binary(note_id) do
376348
{
377349
:ok,
378350
SendReaction.start_link(

lib/nostr/client/frame_dispatcher.ex

Lines changed: 0 additions & 43 deletions
This file was deleted.

lib/nostr/client/relays/relay_socket/frame_handler.ex

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,49 @@ defmodule Nostr.Client.Relays.RelaySocket.FrameHandler do
33
Websocket frames are first sent here to be decoded and then sent to the frame dispatcher
44
"""
55

6-
alias Nostr.Frames.Notice
6+
alias NostrBasics.RelayMessage
77

88
@spec handle_text_frame(list(), list(), map(), pid()) :: :ok
99
def handle_text_frame(frame, subscriptions, relay_url, owner_pid) do
10-
with {:ok, data} <- Jason.decode(frame),
11-
{:ok, item} <- Nostr.Client.FrameDispatcher.dispatch(data) do
12-
case get_atom_id(item) do
13-
nil ->
14-
%Notice{message: message} = get_event(item)
15-
send(owner_pid, {:console, :notice, %{url: relay_url, message: message}})
16-
17-
atom_id ->
18-
case Keyword.get(subscriptions, atom_id) do
19-
nil ->
20-
:ok
21-
22-
subscriber ->
23-
{_id, event} = item
24-
25-
send(subscriber, {relay_url, event})
26-
end
27-
end
28-
29-
:ok
30-
else
31-
{:error, _} ->
32-
send(owner_pid, {:console, :parsing_error, %{url: relay_url, frame: frame}})
33-
:ok
10+
RelayMessage.parse(frame)
11+
|> handle_message(subscriptions, relay_url, owner_pid)
12+
end
13+
14+
defp handle_message({:event, subscription_id, event}, subscriptions, relay_url, _owner_pid) do
15+
case Keyword.get(subscriptions, String.to_atom(subscription_id)) do
16+
nil -> {relay_url, event}
17+
subscriber -> send(subscriber, {relay_url, subscription_id, event})
3418
end
3519
end
3620

37-
defp get_atom_id({nil, _}), do: nil
38-
defp get_atom_id({id, _}), do: String.to_atom(id)
21+
defp handle_message({:notice, message}, _subscriptions, relay_url, owner_pid) do
22+
send(owner_pid, {:console, :notice, %{url: relay_url, message: message}})
23+
end
24+
25+
defp handle_message(
26+
{:end_of_stored_events, subscription_id},
27+
subscriptions,
28+
relay_url,
29+
_owner_pid
30+
) do
31+
message = {:end_of_stored_events, relay_url, subscription_id}
32+
33+
case Keyword.get(subscriptions, String.to_atom(subscription_id)) do
34+
nil -> message
35+
subscriber -> send(subscriber, message)
36+
end
37+
end
3938

40-
defp get_event({_, event}), do: event
39+
defp handle_message({:ok, event_id, success?, message}, _subscriptions, relay_url, owner_pid) do
40+
info = %{url: relay_url, event_id: event_id, success?: success?, message: message}
41+
send(owner_pid, {:console, :ok, info})
42+
end
43+
44+
defp handle_message({:unknown, message}, _subscriptions, relay_url, owner_pid) do
45+
send(owner_pid, {:console, :unknown_relay_message, url: relay_url, message: message})
46+
end
47+
48+
defp handle_message({:json_error, message}, _subscriptions, relay_url, owner_pid) do
49+
send(owner_pid, {:console, :malformed_json_relay_message, url: relay_url, message: message})
50+
end
4151
end

lib/nostr/client/relays/relay_socket/publisher.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ defmodule Nostr.Client.Relays.RelaySocket.Publisher do
3939
send(pid, {:console, :unexpected, %{url: relay_url, frame: frame}})
4040
end
4141

42+
def workflow_error(pid, relay_url, message) do
43+
send(pid, {:console, :workflow_error, %{url: relay_url, message: message}})
44+
end
45+
4246
defp stringify(message) when is_atom(message), do: Atom.to_string(message)
4347
defp stringify(message) when is_binary(message), do: message
4448
end

0 commit comments

Comments
 (0)