From 2497097f6cd639f9bfefec1d037a8c19a65e8145 Mon Sep 17 00:00:00 2001 From: polwex Date: Tue, 18 Nov 2025 05:43:28 +0700 Subject: big fixes to websockets handling --- app/app/nostrill.hoon | 125 +++++++++++------- app/lib/json/nostrill.hoon | 55 +++++++- app/lib/mutations/nostr.hoon | 289 +++++++++++++++++++++--------------------- app/lib/mutations/trill.hoon | 1 + app/lib/nostr/client.hoon | 65 +++------- app/lib/nostrill.hoon | 14 +- app/lib/nostrill/follows.hoon | 6 +- app/lib/websockets.hoon | 28 +++- app/sur/nostr.hoon | 3 +- app/sur/nostrill.hoon | 23 +++- app/ted/ws.hoon | 47 ------- 11 files changed, 344 insertions(+), 312 deletions(-) delete mode 100644 app/ted/ws.hoon diff --git a/app/app/nostrill.hoon b/app/app/nostrill.hoon index b89f7f7..b7aed19 100644 --- a/app/app/nostrill.hoon +++ b/app/app/nostrill.hoon @@ -20,7 +20,7 @@ ^- agent:gall |_ =bowl:gall +* this . - rout ~(. router:web [state bowl]) + rout ~(. router:web [state bowl]) cards ~(. cards:lib bowl) mutan ~(. mutations-nostr [state bowl]) mutat ~(. mutations-trill [state bowl]) @@ -56,15 +56,13 @@ |^ ~& nostrill-on-poke=mark ?+ mark `this - %noun - ~& vase=q.vase - handle-comms - %json on-ui - %handle-http-request handle-shim - %websocket-thread handle-ws-thread + %noun handle-comms + %json on-ui %websocket-client-message handle-relay-ws %websocket-handshake handle-ws-handshake %websocket-server-message handle-ws-msg + :: %websocket-thread handle-ws-thread + :: :: %handle-http-request handle-shim == +$ ws-msg [@ud websocket-message:eyre] ++ handle-ws-thread @@ -77,16 +75,18 @@ ++ handle-relay-ws ^- (quip card:agent:gall agent:gall) =/ msg !<(ws-msg vase) - ~& handle-relay-ws=-.msg + =/ wid -.msg + ~& handle-relay-ws=wid + =/ relay (~(get by relays) wid) + ?~ relay ~& >>> "wid not found in relays state" `this =/ m=websocket-message:eyre +.msg - ?~ message.m `this + ?~ message.m ~& "empty message" `this =/ =octs u.message.m =/ urelay-msg (parse-body:nclient q.octs) - ?~ urelay-msg `this - ~& >> urelay-msg - =/ relay-url (get-url:ws -.msg bowl) - =^ cards state (handle-ws:mutan relay-url u.urelay-msg) + ?~ urelay-msg ~& "msg parse error" `this + =^ cards state (handle-ws:mutan wid u.relay u.urelay-msg) [cards this] + ++ handle-ws-handshake ^- (quip card:agent:gall agent:gall) =/ order !<([@ inbound-request:eyre] vase) @@ -119,7 +119,9 @@ ^- (quip card:agent:gall agent:gall) =/ cs (ui-ws-res:lib -.order wsdata) [cs this] + ++ handle-nostr-client-ws + :: We are the server here ^- (quip card:agent:gall agent:gall) =/ jsonm (de:json:html wsdata) ?~ jsonm `this @@ -144,23 +146,6 @@ %eng (handle-eng:coms +.pok) == [cs this] - :: DEPRECATED - ++ handle-shim - ^- (quip card:agent:gall agent:gall) - =/ order !<(order:web vase) - ~& request.req.order - ?: .=(url.request.req.order '/nostr-shim') - =/ msg (parse-msg:nclient order) - ?~ msg `this - :: =^ cards state (handle-shim-msg:mutat u.msg) - =/ relay-url '' - =^ cards state (handle-ws:mutan relay-url u.msg) - [cards this] - - :: - =/ cards (rout:rout order) - [cards this] - :: ++ on-ui =/ jon=json !<(json vase) @@ -173,8 +158,8 @@ %prof (handle-prof +.u.upoke) %rela (handle-rela +.u.upoke) %post =^ cs state - (handle-post:mutat +.u.upoke) - [cs this] + (handle-post:mutat +.u.upoke) + [cs this] == ++ handle-cycle-keys =/ ks (gen-keys:nostr-keys eny.bowl) @@ -213,10 +198,14 @@ == ++ handle-rela |= poke=relay-poke:ui:sur ?- -.poke - %add =. relays (~(put by relays) +.poke *relay-stats:nsur) - `this - %del =. relays (~(del by relays) +.poke) - `this + %add + :_ this + :: TODO good UI for this + :~ (connect:ws +.poke bowl) + == + %del + =^ cs state (unset-relay:mutan +.poke) + [cs this] :: %sync =^ cs state get-posts:nclient [cs this] @@ -237,15 +226,38 @@ ++ debug |= noun=* ?+ noun `this %iris + =/ endpoint 'ws://localhost:8888' :_ this - =/ =task:iris [%websocket-connect dap.bowl 'ws://localhost:8888'] - :~ [%pass /iris-test %arvo %i task] + :~ (connect:ws endpoint bowl) == - %wsted - :: =/ relay-url 'ws://localhost:8888' - =/ relay-url 'wss://nos.lol' - =^ cs state (test-connection:nclient relay-url) + %iris2 + =/ endpoint 'wss://nos:lol' + :_ this + :~ (connect:ws endpoint bowl) + == + %wstest + :: =/ url 'ws://localhost:8888' + =/ url 'wss://nos.lol' + =^ cs state (test-connection:nclient url) [cs this] + %wsl + =/ l (list-connected:ws bowl) + ~& > ws-connections=l + `this + %wsc + =. relays ~ + `this + %ws-close + =/ sockets .^((map @ud websocket-connection:iris) %ix /(scot %p our.bowl)/ws/(scot %da now.bowl)) + ~& iris-sockets=sockets + :_ this + =/ inc-subs ~(tap by sup.bowl) + =/ ws-paths %+ roll inc-subs |= [i=[=duct =ship =path] acc=(list path)] + ?. ?=([%websocket-client *] path.i) acc + ~& bitt=i + [path.i acc] + :~ [%give %fact ws-paths %disconnect !>(~)] + == %irisf :_ this =/ inc-subs ~(tap by sup.bowl) @@ -267,6 +279,28 @@ =/ res (check-connected:ws 'ws://localhost:8888' bowl) ~& res `this + %nostr + =/ rls ~(tap by relays) + =/ m |- ?~ rls ~ + =/ stats=relay-stats:nsur +.i.rls + ~& > ws-endpoint=url.stats + ~& >> conn=start.stats + =/ reqs ~(tap by reqs.stats) + =/ mm |- ?~ reqs ~ + =/ sub -.i.reqs + ~& event-stats=+.i.reqs + $(reqs t.reqs) + $(rls t.rls) + ~& > "nostr feed" + =/ nf (tap:norm:sur nostr-feed) + =/ nff |- ?~ nf ~ + =/ ev=event:nsur +.i.nf + ~& meta=[kind=kind.ev id=id.ev pubkey=pubkey.ev ts=created-at.ev] + ~& >> ev-txt=content.ev + + $(nf t.nf) + + `this %wtf =/ lol=(unit @) ~ =/ l ~| "wtf" (need lol) @@ -383,7 +417,9 @@ ~& on-watch=`path`pole ?+ pole !! [%http-response *] `this - [%websocket-client wids=@t ~] `this + [%websocket-client wids=@t ~] + =^ cs state (set-relay:mutan (slav %ud wids.pole)) + [cs this] [%websocket-server *] `this [%follow ~] :_ this (give-feed:coms pole) [%beg %feed ~] @@ -445,6 +481,9 @@ |~ [wire=(pole knot) =sign-arvo] ^- (quip card:agent:gall agent:gall) ~& >> on-arvo=[`path`wire -.sign-arvo +<.sign-arvo] + ?: ?=(%iris -.sign-arvo) + :: ~& > +.sign-arvo + `this ?+ wire `this [%ws %to-nostr-relay *] ?> ?=([%khan %arow *] sign-arvo) diff --git a/app/lib/json/nostrill.hoon b/app/lib/json/nostrill.hoon index 266a6c8..ed8f0a8 100644 --- a/app/lib/json/nostrill.hoon +++ b/app/lib/json/nostrill.hoon @@ -25,12 +25,13 @@ (event:en:nostr ev) ++ en-relays - |= r=(map @t relay-stats:nsur) ^- json + |= r=(map @ relay-stats:nsur) ^- json %- pairs %+ turn ~(tap by r) - |= [url=@t rs=relay-stats:nsur] - :- url %- pairs - :~ :- %connected ?~ connected.rs ~ (time u.connected.rs) - :- %reqs (relay-stats reqs.rs) + |= [wid=@ud rs=relay-stats:nsur] + :- url.rs %- pairs + :~ :- %start (time start.rs) + :- %wid (numb wid) + :- %reqs (relay-stats reqs.rs) == ++ relay-stats |= rm=(map @t event-stats:nsur) %- pairs %+ turn ~(tap by rm) |= [sub-id=@t es=event-stats:nsur] @@ -83,6 +84,7 @@ %post (postfact +.f) %enga (enga +.f) %fols (fols +.f) + %hark (hark +.f) == ++ fols |= ff=fols-fact:ui:sur ^- json %+ frond -.ff @@ -103,9 +105,50 @@ (post-wrapper +.pf) ++ enga |= [pw=post-wrapper:sur reaction=*] + :: TODO ^- json ~ + ++ hark |= =notif:sur + ^- json + %+ frond -.notif + ?- -.notif + %prof (prof-notif +.notif) + %fols (pairs :~(['user' (user user.notif)] ['accepted' %b accepted.notif] ['msg' %s msg.notif])) + %fans (user p.notif) + %beg (beg-notif +.notif) + %post (post-notif +.notif) + == + ++ prof-notif |= [u=user:sur prof=user-meta:nsur] + %- pairs + :~ user+(user u) + profile+(user-meta:en:nostr prof) + == + ++ beg-notif |= [beg=begs-poke:ui:sur accepted=? msg=@t] + ^- json + %+ frond -.beg + %- pairs + :~ ['accepted' %b accepted] + ['msg' %s msg] + ?- -.beg + %feed ['ship' %s (scot %p +.beg)] + %thread ['post' (pid:en:trill +.beg)] + == + == + ++ post-notif |= [pid=[@p @da] u=user:sur p=post-notif:sur] + ^- json + %- pairs + :~ ['post' (pid:en:trill pid)] + ['user' (user u)] + :- -.p + ?- -.p + %reply (poast:en:trill +.p) + %quote (poast:en:trill +.p) + %reaction [%s +.p] + %rp ~ + %del ~ + == + == ++ post-wrapper |= p=post-wrapper:sur %- pairs :~ post+(poast:en:trill post.p) @@ -233,7 +276,7 @@ ++ ui-relay %- of :~ add+so - del+so + del+de-atom-id sync+ul send+de-relay-send == diff --git a/app/lib/mutations/nostr.hoon b/app/lib/mutations/nostr.hoon index 154bed9..4657784 100644 --- a/app/lib/mutations/nostr.hoon +++ b/app/lib/mutations/nostr.hoon @@ -8,10 +8,29 @@ njs=json-nostr, postlib=trill-post, nostr-client, - sr=sortug + sr=sortug, + ws=websockets |_ [=state:sur =bowl:gall] +$ card card:agent:gall +:: relay state +++ set-relay |= wid=@ud + ^- (quip card _state) + =/ socket (get-url:ws wid bowl) + ?~ socket ~& "socket wid not in iris" !! + ?. ?=(%accepted status.u.socket) ~& "socket status in iris unsync" !! + =/ relay=relay-stats:nsur [now.bowl url.u.socket ~] + =. relays.state (~(put by relays.state) wid relay) + `state + +++ unset-relay |= wid=@ud + ^- (quip card _state) + =. relays.state (~(del by relays.state) wid) + :_ state + :~ (disconnect:ws wid) + == + + :: events ++ handle-client-event |= [wid=@ =event:nsur] ^- (quip card _state) ~& handling-client-event=event @@ -54,44 +73,28 @@ =^ cards state (get-profiles:nclient pubkeys) [cards state] -++ handle-msg |= msg=relay-msg:nsur - ^- (quip card _state) - ?+ -.msg `state - %event - (handle-event '' sub-id.msg event.msg) - %eose - `state - %closed - `state - %auth ~& >> auth=+.msg :: TODO handle auth challenges? - `state - %notice ~& >> notice=+.msg :: TODO pass to UI? - `state - == -++ handle-ws |= [relay=@t msg=relay-msg:nsur] - =/ rs (~(get by relays.state) relay) - ?~ rs :: TODO do we really - `state +++ handle-ws |= [wid=@ud relay=relay-stats:nsur msg=relay-msg:nsur] + |^ =^ cards state - ~& handle-ws=-.msg + ~& >>> "HANDLING-WS-FROM-SERVER" + ~& > handle-ws=-.msg + ~& >>> "**************" ?- -.msg - %ok (handle-ok relay +.msg) - %event - =. relays.state (update-relay-stats relay sub-id.msg) - (handle-event relay sub-id.msg event.msg) - + :: This gets returned when we post a message to a relay + %ok (handle-ok url.relay +.msg) + %event (handle-event sub-id.msg event.msg) %eose :: TODO do unsub for replaceable/addressable events - =/ creq (~(get by reqs.u.rs) +.msg) + =/ creq (~(get by reqs.relay) +.msg) ?~ creq `state :: =. reqs.u.rs (~(del by reqs.u.rs) +.msg) :: =. relays.state (~(put by relays.state) relay u.rs) =/ cardslib ~(. cards:lib bowl) =/ c (update-ui:cardslib [%nostr nostr-feed.state]) :_ state :~(c) - %closed =. reqs.u.rs (~(del by reqs.u.rs) sub-id.msg) - =. relays.state (~(put by relays.state) relay u.rs) + %closed =. reqs.relay (~(del by reqs.relay) sub-id.msg) + =. relays.state (~(put by relays.state) wid relay) `state %auth ~& >> auth=+.msg :: TODO handle auth challenges? `state @@ -115,128 +118,120 @@ :: [ncards this] :: `state -++ update-relay-stats - |= [relay=@t sub-id=@t] ^+ relays.state - - =/ cur (~(get by relays.state) relay) - =/ curr ?~ cur *relay-stats:nsur u.cur - =? connected.curr ?=(%~ connected.curr) (some now.bowl) - =/ creq (~(get by reqs.curr) sub-id) - ?~ creq relays.state :: bail - =/ nreq u.creq(received +(received.u.creq)) - =. reqs.curr (~(put by reqs.curr) sub-id nreq) - (~(put by relays.state) relay curr) - -++ handle-ok |= [relay=@t event-id=@ux accepted=? msg=@t] - ^- (quip card _state) - :: TODO pass to UI - `state - + ++ handle-ok |= [relay=@t event-id=@ux accepted=? msg=@t] + ^- (quip card _state) + :: TODO pass to UI + `state -++ handle-event - |= [relay=@t sub-id=@t =event:nsur] - ^- (quip card _state) - |^ - ~& parsing-nostr-event=kind.event -:: https://nostrdata.github.io/kinds/ - ?: .=(kind.event 666) :: one_off subs eose cf. 999 - parse-relay-oneose - ?: .=(kind.event 0) :: user metadata - parse-metadata - ?: .=(kind.event 1) :: apparently a poast - parse-poast - ?: .=(kind.event 3) :: follow list - parse-follow - :: ?: .=(kind.event 5) :: delete - ?: .=(kind.event 6) :: RT - parse-follow - ?: .=(kind.event 7) :: Reaction - parse-follow + ++ handle-event + |= [sub-id=@t =event:nsur] + ^- (quip card _state) + ~& > handle-event-sub=sub-id + =/ req (~(get by reqs.relay) sub-id) + ?~ req ~& "sub id not found in relay state" `state + =. received.u.req +(received.u.req) + =. reqs.relay (~(put by reqs.relay) sub-id u.req) + |^ + ~& parsing-nostr-event=kind.event + :: https://nostrdata.github.io/kinds/ + ?: .=(kind.event 666) :: one_off subs eose cf. 999 + parse-relay-oneose + ?: .=(kind.event 0) :: user metadata + parse-metadata + ?: .=(kind.event 1) :: apparently a poast + parse-poast + ?: .=(kind.event 3) :: follow list + parse-follow + :: ?: .=(kind.event 5) :: delete + ?: .=(kind.event 6) :: RT + parse-follow + ?: .=(kind.event 7) :: Reaction + parse-follow + + `state + + ++ parse-metadata + ^- (quip card _state) + =/ jstring content.event + =/ ujon (de:json:html jstring) + ?~ ujon ~& failed-parse-metadata=ujon `state + =/ umeta (user-meta:de:njs u.ujon) + ?~ umeta ~& >> failed-dejs-metadata=ujon `state + =. profiles.state (~(put by profiles.state) [%nostr pubkey.event] u.umeta) + `state + + + ++ parse-poast + ^- (quip card _state) + =. nostr-feed.state (put:norm:sur nostr-feed.state created-at.event event) + :: =/ uprof (~(get by profiles.state) pubkey.event) + :: ?~ uprof + :: =/ shimm ~(. shim [state bowl]) + :: =^ cards state (get-profiles:shimm (silt ~[pubkey.event])) + :: [cards state] + + + :: =/ fid (~(get by following.state) pubkey.event) + :: ?~ fid `state :: don't save post if we don't follow the fucker + + :: =/ cl (tokenize:postlib content.event) + + :: =/ ts (from-unix:jikan:sr created-at.event) + :: :: TODO wtf + :: =/ cm=content-map:post (init-content-map:postlib cl ts) + + :: =/ p=post:post :* + :: id=ts + :: host=`@p`pubkey.event + :: author=`@p`pubkey.event + :: thread=ts + :: parent=~ + :: children=~ + :: contents=cm + :: read=*lock:gate + :: write=*lock:gate + :: *engagement:post + :: 0v0 + :: *signature:post + :: tags=~ + :: == + :: =/ nfid (put:orm:feed u.fid ts p) + :: =. following.state (~(put by following.state) pubkey.event nfid) `state - - ++ parse-metadata - ^- (quip card _state) - =/ jstring content.event - =/ ujon (de:json:html jstring) - ?~ ujon ~& failed-parse-metadata=ujon `state - =/ umeta (user-meta:de:njs u.ujon) - ?~ umeta ~& >> failed-dejs-metadata=ujon `state - =. profiles.state (~(put by profiles.state) [%nostr pubkey.event] u.umeta) + ++ parse-follow + ^- (quip card _state) + =/ following (~(get by follow-graph.state) [%nostr pubkey.event]) + =/ follow-set ?~ following *(set follow:sur) u.following + |- ?~ tags.event `state + =/ t=tag:nsur i.tags.event + :: ?. .=('p' key.t) $(tags.event t.tags.event) + :: =/ pubkeys value.t + :: =/ pubkey (slaw:sr %ux pubkeys) + :: ?~ pubkey ~& "parsing hex error" $(tags.event t.tags.event) + :: =/ relay (snag 0 rest.t) + :: =/ rel ?: .=(relay '') ~ (some relay) + :: =/ nickname (snag 1 rest.t) + :: =/ meta=follow:sur [u.pubkey nickname rel] + :: =. follow-set (~(put in follow-set) meta) + :: =. follow-graph.state (~(put by follow-graph.state) pubkey.event follow-set) + $(tags.event t.tags.event) + :: + ++ parse-relay-oneose + ^- (quip card _state) + =. reqs.relay (~(del by reqs.relay) sub-id) + =. relays.state (~(put by relays.state) wid relay) `state - - - ++ parse-poast - ^- (quip card _state) - =. nostr-feed.state (put:norm:sur nostr-feed.state created-at.event event) - :: =/ uprof (~(get by profiles.state) pubkey.event) - :: ?~ uprof - :: =/ shimm ~(. shim [state bowl]) - :: =^ cards state (get-profiles:shimm (silt ~[pubkey.event])) - :: [cards state] - - - :: =/ fid (~(get by following.state) pubkey.event) - :: ?~ fid `state :: don't save post if we don't follow the fucker - - :: =/ cl (tokenize:postlib content.event) - - :: =/ ts (from-unix:jikan:sr created-at.event) - :: :: TODO wtf - :: =/ cm=content-map:post (init-content-map:postlib cl ts) - - :: =/ p=post:post :* - :: id=ts - :: host=`@p`pubkey.event - :: author=`@p`pubkey.event - :: thread=ts - :: parent=~ - :: children=~ - :: contents=cm - :: read=*lock:gate - :: write=*lock:gate - :: *engagement:post - :: 0v0 - :: *signature:post - :: tags=~ - :: == - :: =/ nfid (put:orm:feed u.fid ts p) - :: =. following.state (~(put by following.state) pubkey.event nfid) - `state - ++ parse-follow - ^- (quip card _state) - =/ following (~(get by follow-graph.state) [%nostr pubkey.event]) - =/ follow-set ?~ following *(set follow:sur) u.following - |- ?~ tags.event `state - =/ t=tag:nsur i.tags.event - :: ?. .=('p' key.t) $(tags.event t.tags.event) - :: =/ pubkeys value.t - :: =/ pubkey (slaw:sr %ux pubkeys) - :: ?~ pubkey ~& "parsing hex error" $(tags.event t.tags.event) - :: =/ relay (snag 0 rest.t) - :: =/ rel ?: .=(relay '') ~ (some relay) - :: =/ nickname (snag 1 rest.t) - :: =/ meta=follow:sur [u.pubkey nickname rel] - :: =. follow-set (~(put in follow-set) meta) - :: =. follow-graph.state (~(put by follow-graph.state) pubkey.event follow-set) - $(tags.event t.tags.event) - ++ parse-relay-oneose - ^- (quip card _state) - =/ rs (~(get by relays.state) relay) - ?~ rs `state - =. reqs.u.rs (~(del by reqs.u.rs) sub-id) - =. relays.state (~(put by relays.state) relay u.rs) - `state + -- -- - -++ handle-prof-fact |= pf=prof-fact:comms - ^- (quip card _state) - =/ =user:sur [%urbit src.bowl] - ?- -.pf - %prof =. profiles.state (~(put by profiles.state) user +.pf) - :: TODO kinda wanna send it to the UI - `state - %keys `state - :: TODO really need a way to keep track of everyone's pubkeys - == + ++ handle-prof-fact |= pf=prof-fact:comms + ^- (quip card _state) + =/ =user:sur [%urbit src.bowl] + ?- -.pf + %prof =. profiles.state (~(put by profiles.state) user +.pf) + :: TODO kinda wanna send it to the UI + `state + %keys `state + :: TODO really need a way to keep track of everyone's pubkeys + == -- diff --git a/app/lib/mutations/trill.hoon b/app/lib/mutations/trill.hoon index 653a493..d5cfb67 100644 --- a/app/lib/mutations/trill.hoon +++ b/app/lib/mutations/trill.hoon @@ -41,6 +41,7 @@ =/ profile (~(get by profiles.state) [%urbit our.bowl]) =/ pubkey pub.i.keys.state =/ crds ~(. cards:lib bowl) + :: TODO UI notifications [%hark ] ?- -.poke %del =. feed.state =< + (del:orm:feed feed.state id.poke) diff --git a/app/lib/nostr/client.hoon b/app/lib/nostr/client.hoon index 1cda3e3..f0d12a2 100644 --- a/app/lib/nostr/client.hoon +++ b/app/lib/nostr/client.hoon @@ -28,27 +28,32 @@ :: :: build http card :: =/ [url=@t rs=relay-stats:nsur] i.rls :: :: mutate relays stats -:: =/ es=event-stats:nsur [fs 0] -:: =/ nreqs (~(put by reqs.rs) sub-id es) :: =/ nrs rs(reqs nreqs) :: =. relays.state (~(put by relays.state) url nrs) :: $(urls [url urls], rls t.rls) ++ send-req |= fs=(list filter:nsur) ^- (quip card _state) - =/ rls ~(tap by relays.state) =/ sub-id (gen-sub-id:nostr-keys eny.bowl) =/ req=client-msg:nsur [%req sub-id fs] =/ rls ~(tap by relays.state) ?~ rls !! - =/ url -.i.rls + :: TODO not how this should work + =/ rs=relay-stats:nsur +.i.rls + =/ wid -.i.rls + =/ url url.rs + =/ es=event-stats:nsur [fs 0] + =. reqs.rs (~(put by reqs.rs) sub-id es) + =. relays.state (~(put by relays.state) wid rs) + ~& > sending-ws-req=sub-id :- :~ (send url req) == state ++ get-posts ^- (quip card _state) =/ kinds (silt ~[1]) - =/ last-week (sub now.bowl ~d1) + :: =/ last-week (sub now.bowl ~d7) + =/ last-week (sub now.bowl ~m2) :: =/ since (to-unix-secs:jikan:sr last-week) =/ =filter:nsur [~ ~ `kinds ~ `last-week ~ ~] (send-req ~[filter]) @@ -105,48 +110,12 @@ =/ octs (json-to-octs:server req-body) =/ wmsg=websocket-message:eyre [1 `octs] ~& >> sup=sup.bowl - :: =/ conn (check-connected:ws relay-url bowl) - :: ~& >>> send-client-conn=conn - :: ?~ conn :: if no ws connection we start a thread which will connect first, then send the message - :: =/ pat /to-nostr-relay - :: [%pass (weld /ws pat) %arvo %k %fard dap.bowl %ws %noun !>([relay-url wmsg])] + =/ conn (check-connected:ws relay-url bowl) + ~& >>> send-client-conn=conn + ?~ conn :: if no ws connection we start a thread which will connect first, then send the message + !! + :: =/ =task:iris [%websocket-connect dap.bowl relay-url] + :: [%pass /ws-req/nostrill %arvo %i task] :: - :: (give-ws-payload-client:ws id.u.conn wmsg) - :: (give-ws-payload-client:ws wid wmsg) - - =/ =task:iris [%websocket-connect dap.bowl relay-url] - [%pass /ws-req/nostrill %arvo %i task] - - -:: ++ send-http -:: |= req=http-req:shim:nsur -:: ^- card:agent:gall -:: =/ req-body (http-req:en:js req) -:: :: ~& shim-req-json=(en:json:html req-body) -:: =/ host .^(hart:eyre %e /(scot %p our.bowl)/host/(scot %da now.bowl)) -:: =/ origin %- crip (head:en-purl:html host) -:: =/ headers :~ -:: [key='content-type' value='application/json'] -:: [key='origin' value=origin] -:: == -:: =/ =request:http [%'POST' url:shim:nsur headers `(json-body:web req-body)] -:: [%pass /http/[sub-id.req] %arvo %k %fard dap.bowl %fetch %noun !>(request)] -:: :: -:: :: HTTP -:: :: - -:: ++ get-profiles-http -:: |= pubkeys=(set @ux) -:: ^- (quip card _state) -:: =/ relays ~(key by relays.state) -:: :: TODO make a function to use most reliable -:: =/ relay (head ~(tap in relays)) -:: ~& http=relay -:: =/ sub-id (gen-sub-id:nostr-keys eny.bowl) -:: =/ kinds (silt ~[0]) -:: =/ total=filter:nsur [~ `pubkeys `kinds ~ ~ ~ ~] -:: =/ req=http-req:shim:nsur [relay http-delay:constants sub-id ~[total]] -:: =/ =card (send-http req) -:: :- :~(card) state - + (give-ws-payload-client:ws wid.u.conn wmsg) -- diff --git a/app/lib/nostrill.hoon b/app/lib/nostrill.hoon index 1f5db40..32099b2 100644 --- a/app/lib/nostrill.hoon +++ b/app/lib/nostrill.hoon @@ -5,22 +5,18 @@ :: ++ default-state |= =bowl:gall ^- state:sur =/ s *state-0:sur - =/ l public-relays:nsur - :: =/ l (scag 1 l) :: =/ l ~['wss://relay.damus.io' 'wss://nos.lol'] - =/ rl %+ turn l |= t=@t [t *relay-stats:nsur] - :: =/ l ~[['wss://relay.damus.io' ~]] =/ key (gen-keys:nostr-keys eny.bowl) =/ keyl [key ~] - s(relays (malt rl), keys keyl) + s(keys keyl) ++ print-relay-stats - |= rm=(map @t relay-stats:nsur) + |= rm=(map @ relay-stats:nsur) =/ l ~(tap by rm) |- ?~ l ~ - =/ [url=@t rs=relay-stats:nsur] i.l - ~& relay=url - ~& connected=connected.rs + =/ [wid=@ rs=relay-stats:nsur] i.l + ~& relay-url=url.rs + ~& connected=start.rs ~& sub-count=~(wyt by reqs.rs) =/ total-received %+ roll ~(tap by reqs.rs) diff --git a/app/lib/nostrill/follows.hoon b/app/lib/nostrill/follows.hoon index 942a876..fb477d6 100644 --- a/app/lib/nostrill/follows.hoon +++ b/app/lib/nostrill/follows.hoon @@ -33,8 +33,10 @@ ++ handle-follow-res |= =res:comms ?- -.res - %ng :: bruh - `state + %ng + :_ state + =/ =fact:ui:sur [%hark %fols [%urbit src.bowl] .n msg.res] + =/ c (update-ui:cards:lib fact) :~(c) %ok ?- -.p.res %feed (handle-follow-ok [%urbit src.bowl] fc.+.p.res profile.+.p.res) diff --git a/app/lib/websockets.hoon b/app/lib/websockets.hoon index 8e6d45c..ae48775 100644 --- a/app/lib/websockets.hoon +++ b/app/lib/websockets.hoon @@ -1,4 +1,15 @@ |% + ++ connect |= [endpoint=@t =bowl:gall] + ^- card:agent:gall + =/ =task:iris [%websocket-connect dap.bowl endpoint] + [%pass /ws-connect %arvo %i task] + + ++ disconnect |= wid=@ud + ^- card:agent:gall + =/ =path /websocket-client/(scot %ud wid) + =/ ws-paths :~(path) + [%give %fact ws-paths %disconnect !>(~)] + :: ++ give-ws-payload-client |= [wid=@ msg=websocket-message:eyre] ^- card:agent:gall @@ -32,15 +43,18 @@ :~ (give-ws-payload-server wid response) == - +:: %iris scries + +$ socket [wid=@ud url=@t status=$?(%accepted %pending)] ++ get-url - |= [wid=@ud =bowl:gall] ^- @t + |= [wid=@ud =bowl:gall] ^- (unit socket) =/ scry-path=path /(scot %p our.bowl)/ws/(scot %da now.bowl)/id/(scot %ud wid) - =/ conn .^(websocket-connection:iris %ix scry-path) - url.conn + .^((unit socket) %ix scry-path) ++ check-connected - |= [url=@t =bowl:gall] ^- (unit websocket-connection:iris) + |= [url=@t =bowl:gall] ^- (unit socket) =/ scry-path=path /(scot %p our.bowl)/ws/(scot %da now.bowl)/url/[url] - =/ conn .^((unit websocket-connection:iris) %ix scry-path) - conn + .^((unit socket) %ix scry-path) + ++ list-connected + |= =bowl:gall ^- (list socket) + =/ scry-path=path /(scot %p our.bowl)/ws/(scot %da now.bowl)/app + .^((list socket) %ix scry-path) -- diff --git a/app/sur/nostr.hoon b/app/sur/nostr.hoon index f449899..2f8296b 100644 --- a/app/sur/nostr.hoon +++ b/app/sur/nostr.hoon @@ -28,7 +28,8 @@ $: name=@t other=(map @t json) == +$ relay-stats -$: connected=(unit @da) +$: start=@da + url=@t reqs=(map sub-id event-stats) == +$ event-stats diff --git a/app/sur/nostrill.hoon b/app/sur/nostrill.hoon index 92a0876..136547b 100644 --- a/app/sur/nostrill.hoon +++ b/app/sur/nostrill.hoon @@ -4,7 +4,7 @@ +$ state-0 $: %0 :: nostr config - relays=(map @t relay-stats:nostr) + relays=(map @ud relay-stats:nostr) :: key is the websocket id keys=(lest keys:nostr) :: cycled, i.keys is current one :: own feed feed=feed:trill @@ -18,6 +18,8 @@ following2=feed:trill follow-graph=(map user (set user)) :: TODO global feed somehow? + :: TODO use %hark agent instead? + :: notifications=((mop @da notif) gth) == +$ nostr-feed ((mop @ud event:nostr) gth) @@ -34,6 +36,21 @@ $: pub=(unit @ux) +$ user $%([%urbit p=@p] [%nostr p=@ux]) +$ follow [pubkey=@ux name=@t relay=(unit @t)] ++$ notif + $% [%prof =user prof=user-meta:nostr] :: profile change + [%fols =user accepted=? msg=@t] :: follow response + [%beg beg=begs-poke:ui accepted=? msg=@t] :: feed/post data request response + [%fans p=user] :: someone folowed me + [%post =pid:tp =user action=post-notif] :: someone replied, reacted etc. + == ++$ post-notif +$% [%reply p=post:tp] + [%quote p=post:tp] + [%reaction reaction=@t] + :: [%rt id=@ux pubkey=@ux relay=@t] :: NIP-18 + [%rp ~] :: NIP-18 + [%del ~] +== ++ ui |% +$ poke @@ -43,6 +60,7 @@ $: pub=(unit @ux) [%prof prof-poke] [%keys ~] :: cycle-keys [%rela relay-poke] + :: [%notif @da] :: dismiss notification == +$ begs-poke $% [%feed p=@p] @@ -67,7 +85,7 @@ $: pub=(unit @ux) == +$ relay-poke $% [%add p=@t] - [%del p=@t] + [%del p=@ud] :: [%sync ~] :: send event for... relaying @@ -79,6 +97,7 @@ $: pub=(unit @ux) [%post post-fact] [%enga p=post-wrapper reaction=*] [%fols fols-fact] + [%hark =notif] == +$ post-fact $% [%add post-wrapper] diff --git a/app/ted/ws.hoon b/app/ted/ws.hoon deleted file mode 100644 index 9f9c298..0000000 --- a/app/ted/ws.hoon +++ /dev/null @@ -1,47 +0,0 @@ -/- spider, nsur=nostr -/+ strandio -=, strand=strand:spider -^- thread:spider -|= arg=vase -=/ m (strand ,vase) -^- form:m -:: =/ [url=@t req=client-msg:nsur] (need !<((unit [@t client-msg:nsur]) arg)) -=/ [url=@t wmsg=websocket-message:eyre] !<([@t websocket-message:eyre] arg) -~& > url=url -~& > req=wmsg -;< =bowl:spider bind:m get-bowl:strandio -=/ desk q.byk.bowl -=/ =task:iris [%websocket-connect desk url] -=/ =card:agent:gall [%pass /ws-req/nostrill %arvo %i task] -;< ~ bind:m (send-raw-card:strandio card) -;< res=(pair wire sign-arvo) bind:m take-sign-arvo:strandio -~& > res=res -:: confirm connection was established -?. ?=([%iris %websocket-response id=@ud websocket-event:eyre] q.res) - (strand-fail:strand %bad-sign ~) -~& > ted-ws-res=+>+<.q.res -?. ?=(%accept +>+<.q.res) - (pure:m !>([%ng ''])) - :: (strand-fail:strand %bad-sign ~) - -~& "ws connection accepted, sending ws msg" -~& >>> "sleeping" -;< ~ bind:m (sleep:strandio ~s3) -~& >>> "slept" -=/ card2=card:agent:gall - [%pass /ws/proxy %agent [our.bowl desk] %poke %websocket-thread !>([id.q.res wmsg])] -;< ~ bind:m (send-raw-card:strandio card2) -;< res2=(pair wire sign-arvo) bind:m take-sign-arvo:strandio - - -:: =/ subwire=path /websocket-server/(scot %ud id.q.res) -:: =/ =cage [%websocket-response !>(+>.q.res)] -:: =/ gf=gift:agent:gall [%fact :~(subwire) cage] -:: =/ =card:agent:gall [%give gf] -:: ~& >> ws-ted-ok-sending-msg=id.q.res -:: ;< ~ bind:m (send-raw-card:strandio card) -:: ;< res2=(pair wire sign-arvo) bind:m take-sign-arvo:strandio -:: ?. ?=([%iris %websocket-response id=@ud %message wm=websocket-message:eyre] q.res2) -:: (strand-fail:strand %bad-sign ~) -:: =/ wm=websocket-message:eyre +>+>.q.res2 -(pure:m !>([%ok id.q.res])) -- cgit v1.2.3