diff options
| -rw-r--r-- | app/app/nostrill.hoon | 121 | ||||
| -rw-r--r-- | app/lib/json/nostr.hoon | 11 | ||||
| -rw-r--r-- | app/lib/json/nostrill.hoon | 13 | ||||
| -rw-r--r-- | app/lib/mutations/nostr.hoon | 157 | ||||
| -rw-r--r-- | app/lib/nostr/client.hoon | 91 | ||||
| -rw-r--r-- | app/lib/nostr/events.hoon | 81 | ||||
| -rw-r--r-- | app/lib/nostrill/follows.hoon | 12 | ||||
| -rw-r--r-- | app/sur/nostr.hoon | 10 | ||||
| -rw-r--r-- | app/sur/nostrill.hoon | 16 | ||||
| -rw-r--r-- | app/ted/ws.hoon | 55 |
10 files changed, 369 insertions, 198 deletions
diff --git a/app/app/nostrill.hoon b/app/app/nostrill.hoon index 230f72f..ca5314a 100644 --- a/app/app/nostrill.hoon +++ b/app/app/nostrill.hoon @@ -27,7 +27,6 @@ scry ~(. scri [state bowl]) coms ~(. commlib [state bowl]) fols ~(. followlib [state bowl]) - nclient ~(. nostr-client [state bowl]) ++ on-init ^- (quip card:agent:gall agent:gall) =/ default (default-state:lib bowl) @@ -81,7 +80,7 @@ =/ m=websocket-message:eyre +.msg ?~ message.m ~& "empty message" `this =/ =octs u.message.m - =/ urelay-msg (parse-body:nclient q.octs) + =/ urelay-msg (parse-body:nostr-client q.octs) ?~ urelay-msg ~& "msg parse error" `this =^ cards state (handle-ws:mutan wid u.relay u.urelay-msg) [cards this] @@ -196,33 +195,22 @@ `this == ++ handle-rela |= poke=relay-poke:ui:sur - ?- -.poke - %add - :_ this - :: TODO good UI for this + :: TODO fix this somehow + =^ cs state + ?+ -.poke (handle-rela:mutan poke) + %add :_ state :~ (connect:ws +.poke bowl) == - %del - =^ cs state (unset-relay:mutan +.poke) - [cs this] - :: - %sync =^ cs state get-posts:nclient - [cs this] - :: - %send - =/ upoast (get-poast:scry host.poke id.poke) - ?~ upoast `this - =/ event (post-to-event:evlib i.keys eny.bowl u.upoast) - :: TODO URGENT - :: =/ req=bulk-req:shim:nsur [relays.poke %event event] - :: =/ cards :~((send:nclient req)) - :: [cards this] - `this + %del (unset-relay:mutan +.poke) == - - + [cs this] :: ++ debug |= noun=* + =/ rl get-relay:mutan + ?~ rl ~& >>> "no relay!!!!" `this + =/ wid -.u.rl + =/ relay +.u.rl + =/ nclient ~(. nostr-client [state bowl wid relay]) ?+ noun `this %iris =/ endpoint 'ws://localhost:8888' @@ -234,15 +222,11 @@ :_ this :~ (connect:ws endpoint bowl) == - %wscancel - =/ wid 1 - :_ this - :~ (cancel-connect:ws wid) - == %wstest :: =/ url 'ws://localhost:8888' - =/ url 'wss://nos.lol' - =^ cs state (test-connection:nclient url) + :: =/ url 'wss://nos.lol' + =^ cs relay test-connection:nclient + =. relays (~(put by relays) wid relay) [cs this] %wsl =/ l (list-connected:ws bowl) @@ -250,16 +234,24 @@ `this %wsc =. relays ~ - `this - %ws-close + =. nostr-feed ~ =/ sockets .^((map @ud websocket-connection:iris) %ix /(scot %p our.bowl)/ws/(scot %da now.bowl)) ~& iris-sockets=sockets + =/ wids ~(key by sockets) + =/ ws-paths %+ turn ~(tap in wids) |= wid=@ ^- path /websocket-client/(scot %ud wid) + ~& ws-paths=ws-paths + :_ this + ?~ ws-paths ~ + :~ [%give %fact ws-paths %disconnect !>(~)] + == + %ws-close :_ 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] + ?~ ws-paths ~ :~ [%give %fact ws-paths %disconnect !>(~)] == %irisf @@ -292,7 +284,7 @@ =/ reqs ~(tap by reqs.stats) =/ mm |- ?~ reqs ~ =/ sub -.i.reqs - ~& event-stats=+.i.reqs + ~& event-stats=[sub-id=sub +.i.reqs] $(reqs t.reqs) $(rls t.rls) ~& > "nostr feed" @@ -318,13 +310,6 @@ $(pfs t.pfs) `this - [%prof @] - =/ pubkey=(unit @ux) (slaw:sr %ux +.noun) - ~& pubkey=pubkey - ?~ pubkey ~& "pubkey not valid hex. take out the 0x maybe" !! - =^ cs state (get-profile:nclient u.pubkey) - [cs this] - %wtf =/ lol=(unit @) ~ =/ l ~| "wtf" (need lol) @@ -359,59 +344,13 @@ %http `this %rt :: relay test - =^ cards state get-posts:nclient + =^ cards relay get-posts:nclient + =. relays (~(put by relays) wid relay) [cards this] %rt0 - =/ ids - %+ roll (tap:norm:sur nostr-feed) |= [[@ ev=event:nsur] acc=[(set @ux) (set @ux)]] - ?. .=(kind.ev 1) acc - %= acc - - (~(put in -.acc) id.ev) - + (~(put in +.acc) pubkey.ev) - == - =^ cards state (populate-profiles:mutan -.ids) - :: (get-profiles:shimm +.ids) - :: (get-engagement:shimm -.ids) + =^ cards relay get-profiles:nclient + =. relays (~(put by relays) wid relay) [cards this] - :: %rt1 - :: =| cards=(list card:agent:gall) - :: |- - :: ?~ l - :: ~& cards=(lent cards) [cards this] - :: =/ [sub-id=@t pf=filter:nsur done=filter:nsur] i.l - :: =/ diff (diff-filters:nlib pf done) - :: :: ~& > diff=diff - :: ?~ authors.pf $(l t.l) - :: =^ cs state (populate-profiles:mutat u.authors.pf) - - :: $(l t.l, cards (weld cards cs)) - %rt2 - - =/ poasts (tap:norm:sur nostr-feed) - =/ pcount (lent poasts) - =| invalid=(list @t) - |- ?~ poasts - ~& >>> invalid=invalid - `this - =/ p=event:nsur +.i.poasts - =/ valid (validate-pubkey:nostr-keys pubkey.p) - ?. valid - =/ ids (crip (scow:sr %ux id.p)) - ~& ids - ~& content.p - $(invalid [ids invalid], poasts t.poasts) - $(poasts t.poasts) - %rt3 - =/ poasts (tap:norm:sur nostr-feed) - =| pubkeys=(set @ux) - =/ pks=(set @ux) - |- ?~ poasts pubkeys - =/ p=event:nsur +.i.poasts - =/ npks (~(put in pubkeys) pubkey.p) - $(poasts t.poasts, pubkeys npks) - :: - =^ cards state (populate-profiles:mutan pks) - [cards this] %ui =/ =fact:ui:sur [%post %add *post-wrapper:sur] =/ card (update-ui:cards fact) diff --git a/app/lib/json/nostr.hoon b/app/lib/json/nostr.hoon index ca4ed43..0b1a79a 100644 --- a/app/lib/json/nostr.hoon +++ b/app/lib/json/nostr.hoon @@ -77,10 +77,10 @@ ++ tags - |= tm=(map @t (set @t)) ^- (list [@t json]) :: entries to the filter obeject - %+ turn ~(tap by tm) |= [key=@t values=(set @t)] + |= tm=(map @t (list @t)) ^- (list [@t json]) :: entries to the filter obeject + %+ turn ~(tap by tm) |= [key=@t values=(list @t)] =/ nkey (cat 3 '#' key) - [nkey %a (turn ~(tap in values) cord:en:common)] + [nkey %a (turn values cord:en:common)] ++ user-meta |= meta=user-meta:sur @@ -212,9 +212,8 @@ :: :: anything else is a tag =/ vl ((ar so) +.entry) ?~ vl f - =/ ctags ?~ tags.f *(map @t (set @t)) u.tags.f - =/ values (silt u.vl) - =/ ntags (~(put by ctags) -.entry values) + =/ ctags ?~ tags.f *(map @t (list @t)) u.tags.f + =/ ntags (~(put by ctags) -.entry u.vl) f(tags `ntags) $(entries t.entries) diff --git a/app/lib/json/nostrill.hoon b/app/lib/json/nostrill.hoon index ed8f0a8..01cdb13 100644 --- a/app/lib/json/nostrill.hoon +++ b/app/lib/json/nostrill.hoon @@ -80,12 +80,21 @@ %+ frond %fact %+ frond -.f ?- -.f - %nostr (en-nostr-feed +.f) + %nostr (en-nostr +.f) %post (postfact +.f) %enga (enga +.f) %fols (fols +.f) %hark (hark +.f) == + ++ en-nostr |= nf=nostr-fact:ui:sur ^- json + %+ frond -.nf + ?- -.nf + %feed (en-nostr-feed +.nf) + %user (en-nostr-feed +.nf) + %thread (en-nostr-feed +.nf) + %event (event:en:nostr +.nf) + %relays (en-relays +.nf) + == ++ fols |= ff=fols-fact:ui:sur ^- json %+ frond -.ff ?- -.ff @@ -278,6 +287,8 @@ add+so del+de-atom-id sync+ul + user+hex:de:common + thread+hex:de:common send+de-relay-send == ++ de-relay-send %- ot :~ diff --git a/app/lib/mutations/nostr.hoon b/app/lib/mutations/nostr.hoon index 232fcea..66fdc35 100644 --- a/app/lib/mutations/nostr.hoon +++ b/app/lib/mutations/nostr.hoon @@ -11,12 +11,18 @@ postlib=trill-post, nostr-client, sr=sortug, + scri, ws=websockets |_ [=state:sur =bowl:gall] -+* nclient ~(. nostr-client [state bowl]) ++* cardslib ~(. cards:lib bowl) +$ card card:agent:gall :: relay state +++ get-relay ^- (unit [wid=@ud relay=relay-stats:nsur]) + =/ rls ~(tap by relays.state) + ?~ rls ~ + `i.rls + ++ set-relay |= wid=@ud ^- (quip card _state) =/ socket (get-url:ws wid bowl) @@ -24,13 +30,17 @@ ?. ?=(%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 + :_ state + =/ ui-card (update-ui:cardslib [%nostr %relays relays.state]) + :~(ui-card) ++ unset-relay |= wid=@ud ^- (quip card _state) =. relays.state (~(del by relays.state) wid) + =/ ui-card (update-ui:cardslib [%nostr %relays relays.state]) :_ state :~ (disconnect:ws wid) + ui-card == @@ -69,15 +79,8 @@ :: $(evs t.evs) :: [cards state] -++ populate-profiles - |= pubkeys=(set @ux) - ^- (quip card _state) - =/ nclient ~(. nostr-client [state bowl]) - =^ cards state get-profiles:nclient - [cards state] - - ++ handle-ws |= [wid=@ud relay=relay-stats:nsur msg=relay-msg:nsur] + =/ nclient ~(. nostr-client [state bowl wid relay]) |^ =^ cards state ~& > handle-ws=-.msg @@ -120,32 +123,39 @@ ++ handle-event |= [sub-id=@t =event:nsur] ^- (quip card _state) - ~& > handle-event-sub=sub-id :: increment event count in relay state + ~& >> parsing-nostr-event=kind.event + ~& >> sub-id=sub-id + ~& > relay-subs=~(key by reqs.relay) =/ req (~(get by reqs.relay) sub-id) - ?~ req ~& "sub id not found in relay state" `state + ?~ 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) =. relays.state (~(put by relays.state) wid relay) :: |^ - ~& 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 - + =/ cs1=(list card) + ?~ ongoing.u.req ~ + ?. u.ongoing.u.req ~ + :: If it's an ongoing request and %eose has been reached we pass the individual event to the UI as is + =/ c (update-ui:cardslib [%nostr %event event]) + :~(c) + =^ cs state + ?: .=(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 + [(weld cs1 cs) state] ++ parse-metadata ^- (quip card _state) @@ -161,6 +171,14 @@ ++ parse-poast ^- (quip card _state) =. nostr-feed.state (put:norm:sur nostr-feed.state created-at.event event) + =/ user-feed (~(get by following.state) [%nostr pubkey.event]) + =? following.state ?=(^ user-feed) + =/ pw (event-to-post:evlib event ~ ~) + =/ poast=post:post -.pw + =/ nf (put:orm:feed u.user-feed id.poast poast) + (~(put by following.state) [%nostr pubkey.event] nf) + :_ state + ~ :: =/ uprof (~(get by profiles.state) pubkey.event) :: ?~ uprof :: =/ shimm ~(. shim [state bowl]) @@ -194,7 +212,6 @@ :: == :: =/ 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]) @@ -213,11 +230,6 @@ :: =. 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 -- ++ handle-eose |= sub-id=@t @@ -228,26 +240,54 @@ ?~ creq ~& >>> "sub id not found! on eose" `state ~& >> eose=u.creq ~& >>> "**************" + :: :: if there's a queue we setup the next subscription - =^ cards state - =/ is-feed (is-feed:evlib filters.u.creq) - ?. is-feed [~ state] - =/ cardslib ~(. cards:lib bowl) - =/ c (update-ui:cardslib [%nostr nostr-feed.state]) - =^ mc state get-profiles:nclient - [[c mc] state] - =^ cards2 state - ?~ chunked.u.creq [~ state] + =^ cards relay + ?: (is-feed:evlib filters.u.creq) + =/ c (update-ui:cardslib [%nostr %feed nostr-feed.state]) + =^ mc relay get-profiles:nclient + [[c mc] relay] + :: + =/ users=(set @ux) (user-req:evlib filters.u.creq) + ?: (gth ~(wyt in users) 0) + =/ poasts (tap:norm:sur nostr-feed.state) + =/ subset %+ skim poasts |= [* ev=event:nsur] (~(has in users) pubkey.ev) + =/ f (gas:norm:sur *nostr-feed:sur subset) + =/ c (update-ui:cardslib [%nostr %user f]) + =^ mc relay get-profiles:nclient + [[c mc] relay] + =/ thread-id (thread-req:evlib filters.u.creq) + ?^ thread-id + =/ poasts (tap:norm:sur nostr-feed.state) + =/ subset %+ skim poasts |= [* ev=event:nsur] + ?| .=(u.thread-id id.ev) + =/ refs (get-references:evlib ev) + (~(has in refs) u.thread-id) + == + =/ f (gas:norm:sur *nostr-feed:sur subset) + =/ c (update-ui:cardslib [%nostr %thread f]) + =^ mc relay get-profiles:nclient + [[c mc] relay] + :: + [~ relay] + :: + =^ cards2 relay + ?~ chunked.u.creq [~ relay] =/ head i.chunked.u.creq =/ tail t.chunked.u.creq =/ ncreq=event-stats:nsur [filters.u.creq received.u.creq ongoing.u.creq ~] =. reqs.relay (~(put by reqs.relay) sub-id ncreq) - =. relays.state (~(put by relays.state) wid relay) (send-req:nclient :~(head) ongoing.u.creq tail) - =^ cards3 state - ?: ongoing.u.creq [~ state] - (close-sub:nclient sub-id wid relay) - :: + :: + =^ cards3 relay + ?~ ongoing.u.creq + ~& >>> closing-relay-sub=[sub-id filters.u.creq] + (close-sub:nclient sub-id wid relay) + =/ ncreq=event-stats:nsur [filters.u.creq received.u.creq `.y ~] + =. reqs.relay (~(put by reqs.relay) sub-id ncreq) + [~ relay] + :: + =. relays.state (~(put by relays.state) wid relay) :_ state (weld (weld cards cards2) cards3) -- @@ -261,4 +301,27 @@ %keys `state :: TODO really need a way to keep track of everyone's pubkeys == + ++ handle-rela |= rh=relay-handling:ui:sur + ^- (quip card _state) + =/ rl get-relay + ?~ rl ~& >>> "no relay!!!!" `state + =/ wid=@ud -.u.rl + =/ relay=relay-stats:nsur +.u.rl + =/ nclient ~(. nostr-client [state bowl wid relay]) + ?: ?=(%send -.rh) + =/ scry ~(. scri [state bowl]) + =/ upoast (get-poast:scry host.rh id.rh) + ?~ upoast `state + =/ event (post-to-event:evlib i.keys.state eny.bowl u.upoast) + =/ cs :~((send:nclient url.relay [%event event])) + [cs state] + =^ cs relay + ?- -.rh + %sync get-posts:nclient + %user (get-user-feed:nclient +.rh) + %thread (get-thread:nclient +.rh) + :: + == + =. relays.state (~(put by relays.state) -.u.rl relay) + [cs state] -- diff --git a/app/lib/nostr/client.hoon b/app/lib/nostr/client.hoon index 9c732bb..259852e 100644 --- a/app/lib/nostr/client.hoon +++ b/app/lib/nostr/client.hoon @@ -1,7 +1,7 @@ /- sur=nostrill, nsur=nostr /+ js=json-nostr, sr=sortug, seq, nostr-keys, constants, server, ws=websockets /= web /web/router -|_ [=state:sur =bowl:gall] +|_ [=state:sur =bowl:gall wid=@ud relay=relay-stats:nsur] +$ card card:agent:gall ++ parse-msg @@ -10,6 +10,7 @@ ?~ body.request.req ~ =/ jstring q.u.body.request.req (parse-body jstring) + ++ parse-body |= jstring=@t =/ ures (de:json:html jstring) ?~ ures ~ @@ -18,119 +19,123 @@ ur :: __ -++ get-relay - =/ rls ~(tap by relays.state) ^- [@ud relay-stats:nsur] - ?~ rls !! - :: TODO not how this should work - =/ wid -.i.rls - =/ rs=relay-stats:nsur +.i.rls - [wid rs] - ++ close-sub |= [sub-id=@t wid=@ud relay=relay-stats:nsur] - ^- (quip card _state) + ^- (quip card _relay) =. reqs.relay (~(del by reqs.relay) sub-id) - =. relays.state (~(put by relays.state) wid relay) =/ req=client-msg:nsur [%close sub-id] - =/ rl get-relay - =/ relay +.rl - =/ url url.relay - :- :~ (send url req) == state + :- :~ (send url.relay req) == relay -++ send-req |= [fs=(list filter:nsur) ongoing=? chunked=(list filter:nsur)] - ^- (quip card _state) +++ send-req |= [fs=(list filter:nsur) ongoing=(unit ?) chunked=(list filter:nsur)] + ^- (quip card _relay) =/ sub-id (gen-sub-id:nostr-keys eny.bowl) =/ req=client-msg:nsur [%req sub-id fs] =/ es=event-stats:nsur [fs 0 ongoing chunked] - =/ rl get-relay - =/ wid -.rl - =/ relay +.rl =/ url url.relay =. reqs.relay (~(put by reqs.relay) sub-id es) - =. relays.state (~(put by relays.state) wid relay) ~& > sending-ws-req=sub-id - :- :~ (send url req) == state + :- :~ (send url req) == relay ++ get-posts - ^- (quip card _state) =/ kinds (silt ~[1]) :: =/ last-week (sub now.bowl ~d7) - =/ last-week (sub now.bowl ~m2) + =/ last-week (sub now.bowl ~m1) :: =/ since (to-unix-secs:jikan:sr last-week) =/ =filter:nsur [~ ~ `kinds ~ `last-week ~ ~] - (send-req ~[filter] .y ~) - + (send-req ~[filter] `.n ~) +:: ++ get-user-feed |= pubkey=@ux - ^- (quip card _state) =/ kinds (silt ~[1]) :: =/ since (to-unix-secs:jikan:sr last-week) =/ pubkeys (silt ~[pubkey]) =/ =filter:nsur [~ `pubkeys `kinds ~ ~ ~ ~] - (send-req ~[filter] .y ~) + (send-req ~[filter] `.n ~) + +++ get-thread |= id=@ux + =/ kinds (silt ~[1]) + =/ ids (silt :~(id)) + =/ f1=filter:nsur [`ids ~ `kinds ~ ~ ~ ~] + =/ ids=(list @t) :~((crip (scow:parsing:sr %ux id))) + =/ tag ['e' ids] + =/ tags=(map @t (list @t)) (malt :~(tag)) + =/ f2=filter:nsur [~ ~ `kinds `tags ~ ~ ~] + (send-req ~[f1 f2] `.n ~) + +++ get-post |= id=@ux + =/ kinds (silt ~[1]) + =/ ids (silt :~(id)) + =/ =filter:nsur [`ids ~ `kinds ~ ~ ~ ~] + (send-req ~[filter] ~ ~) +++ get-replies |= id=@ux + =/ kinds (silt ~[1]) + =/ ids=(list @t) :~((crip (scow:parsing:sr %ux id))) + =/ tag ['e' ids] + =/ tags=(map @t (list @t)) (malt :~(tag)) + =/ =filter:nsur [~ ~ `kinds `tags ~ ~ ~] + (send-req ~[filter] `.n ~) +:: ++ get-profile |= pubkey=@ux =/ kinds (silt ~[0]) :: =/ since (to-unix-secs:jikan:sr last-week) =/ pubkeys (silt ~[pubkey]) =/ =filter:nsur [~ `pubkeys `kinds ~ ~ ~ ~] - (send-req ~[filter] .n ~) + (send-req ~[filter] ~ ~) ++ get-profiles - ^- (quip card _state) + ~& >>> "getting profiles" =/ npoasts (tap:norm:sur nostr-feed.state) =| missing-profs=(set @ux) =/ pubkeys=(set @ux) |- ?~ npoasts missing-profs =/ poast=event:nsur +.i.npoasts =/ have (~(has by profiles.state) [%nostr pubkey.poast]) - =. missing-profs ?: have missing-profs (~(put in missing-profs) pubkey.poast) + =? missing-profs !have (~(put in missing-profs) pubkey.poast) $(npoasts t.npoasts) =/ kinds (silt ~[0]) =/ chunk-size 300 + ~& >> fetching-profiles=~(wyt in pubkeys) ?. (gth ~(wyt in pubkeys) chunk-size) =/ =filter:nsur [~ `pubkeys `kinds ~ ~ ~ ~] - (send-req ~[filter] .n ~) + (send-req ~[filter] ~ ~) :: =/ chunks=(list (list @ux)) (chunk-by-size:seq ~(tap in pubkeys) chunk-size) - ?~ chunks ~& >>> "error chunking pubkeys" `state + ?~ chunks ~& >>> "error chunking pubkeys" `relay =/ queue=(list filter:nsur) %+ turn t.chunks |= l=(list @ux) ^- filter:nsur =/ pubkeys=(set @ux) (silt l) [~ `pubkeys `kinds ~ ~ ~ ~] =/ pubkeys=(set @ux) (silt i.chunks) =/ =filter:nsur [~ `pubkeys `kinds ~ ~ ~ ~] - (send-req ~[filter] .n queue) + (send-req ~[filter] ~ queue) ++ get-engagement |= post-ids=(set @ux) - ^- (quip card _state) - =/ post-strings %- ~(run in post-ids) |= id=@ux (crip (scow:sr %ux id)) + =/ post-strings %+ turn ~(tap in post-ids) |= id=@ux (crip (scow:sr %ux id)) =/ =filter:nsur =/ kinds (silt ~[6 7]) =/ tags (malt :~([%e post-strings])) [~ ~ `kinds `tags ~ ~ ~] - (send-req ~[filter] .y ~) + (send-req ~[filter] `.n ~) ++ get-quotes |= post-id=@ux - ^- (quip card _state) =/ post-string (crip (scow:sr %ux post-id)) =/ kinds (silt ~[1]) - =/ tags (malt :~([%q (silt ~[post-string])])) + =/ tags (malt :~([%q ~[post-string]])) =/ =filter:nsur [~ ~ `kinds `tags ~ ~ ~] - (send-req ~[filter] .y ~) + (send-req ~[filter] `.n ~) :: ++ test-connection - |= relay-url=@t =/ kinds (silt ~[1]) =/ since (sub now.bowl ~m10) =/ =filter:nsur [~ ~ `kinds ~ `since ~ ~] =/ sub-id (gen-sub-id:nostr-keys eny.bowl) =/ req=client-msg:nsur [%req sub-id ~[filter]] - :- :~ (send relay-url req) == state + :- :~ (send url.relay req) == relay ++ send |= [relay-url=@t req=client-msg:nsur] ^- card @@ -138,10 +143,10 @@ =/ req-body=json (req:en:js req) =/ 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 + ~& >>> "no connection!!" !! :: =/ =task:iris [%websocket-connect dap.bowl relay-url] :: [%pass /ws-req/nostrill %arvo %i task] diff --git a/app/lib/nostr/events.hoon b/app/lib/nostr/events.hoon index 6f287a7..16beabc 100644 --- a/app/lib/nostr/events.hoon +++ b/app/lib/nostr/events.hoon @@ -1,6 +1,7 @@ /- sur=nostrill, nsur=nostr, post=trill-post, gate=trill-gate /+ js=json-nostr, sr=sortug, trill=trill-post, nostr-keys |% +:: filters ++ is-feed |= fs=(list filter:nsur) ^- ? |- ?~ fs .n =/ filter i.fs @@ -13,16 +14,92 @@ == .y $(fs t.fs) +++ user-req |= fs=(list filter:nsur) ^- (set @ux) + =| pubkeys=(set @ux) + |- ?~ fs pubkeys + =/ filter i.fs + ?~ kinds.filter ~ + ?~ authors.filter ~ + ?: (~(has in u.kinds.filter) 0) ~ + =? pubkeys + ?& (~(has in u.kinds.filter) 1) + ?=(%~ ids.filter) + == (~(uni in pubkeys) u.authors.filter) + $(fs t.fs) +++ posts-req |= fs=(list filter:nsur) ^- (set @ux) + =| ids=(set @ux) + |- ?~ fs ids + =/ filter i.fs + ?~ kinds.filter ~ + ?~ ids.filter ~ + =? ids (~(has in u.kinds.filter) 1) (~(uni in ids) u.ids.filter) + $(fs t.fs) + +++ replies-req |= fs=(list filter:nsur) ^- (set @ux) + =| ids=(set @ux) + |- ?~ fs ids + =/ filter i.fs + =/ parent (replies-filter filter) + =? ids ?=(^ parent) (~(put in ids) u.parent) + $(fs t.fs) + +++ thread-req |= fs=(list filter:nsur) ^- (unit @ux) + =| parent=(unit @ux) + |- ?~ fs ~ + =/ filter i.fs + ?~ parent + =/ upid (post-filter filter) + $(fs t.fs, parent upid) + =/ replies-parent (replies-filter i.fs) + ?: ?& ?=(^ replies-parent) + .=(u.replies-parent u.parent) + == parent + $(fs t.fs) + +++ post-filter |= =filter:nsur ^- (unit @ux) + ?~ kinds.filter ~ + ?~ ids.filter ~ + =/ post-filter (silt ~[1]) + ?. .=(u.kinds.filter post-filter) ~ + =/ idl ~(tap in u.ids.filter) + ?~ idl ~ + ?. .=(1 (lent idl)) ~ + `i.idl + +++ replies-filter |= =filter:nsur ^- (unit @ux) + ?~ kinds.filter ~ + ?~ tags.filter ~ + =/ post-filter (silt ~[1]) + ?. .=(u.kinds.filter post-filter) ~ + =/ tag (~(get by u.tags.filter) 'e') + ?~ tag ~ + ?~ u.tag ~ + =/ reference (slaw:sr %ux i.u.tag) + reference + ++ is-posts-no-prof |= fs=(list filter:nsur) ^- ? =/ has-posts .n |- ?~ fs has-posts =/ filter i.fs ?~ kinds.filter .n ?: (~(has in u.kinds.filter) 0) .n - =. has-posts - ?: (~(has in u.kinds.filter) 1) .y has-posts + =? has-posts (~(has in u.kinds.filter) 1) .y $(fs t.fs) + +:: events +++ get-references |= ev=event:nsur ^- (set @ux) + =| ids=(set @ux) + =/ tags tags.ev + |- ?~ tags ids + =/ tag i.tags + ?~ tag $(tags t.tags) + ?. .=('e' i.tag) $(tags t.tags) + ?~ t.tag $(tags t.tags) + =/ ref (slaw:sr %ux i.t.tag) + =? ids ?=(^ ref) (~(put in ids) u.ref) + $(tags t.tags) + ++ post-to-event |= [=keys:nsur eny=@ p=post:post] ^- event:nsur =/ cl (latest-post-content:trill contents.p) =/ string (crip (content-list-to-md:trill cl)) diff --git a/app/lib/nostrill/follows.hoon b/app/lib/nostrill/follows.hoon index fb477d6..a1af70a 100644 --- a/app/lib/nostrill/follows.hoon +++ b/app/lib/nostrill/follows.hoon @@ -1,19 +1,25 @@ /- sur=nostrill, nsur=nostr, comms=nostrill-comms, feed=trill-feed -/+ lib=nostrill, js=json-nostr, nostr-client, sr=sortug, constants, gatelib=trill-gate, feedlib=trill-feed, jsonlib=json-nostrill +/+ lib=nostrill, js=json-nostr, nostr-client, sr=sortug, constants, gatelib=trill-gate, feedlib=trill-feed, jsonlib=json-nostrill, mutations-nostr |_ [=state:sur =bowl:gall] ++ handle-add |= =user:sur ^- (quip card:agent:gall _state) ?- -.user %urbit =/ c (urbit-watch +.user) :- :~(c) state - %nostr =/ nclient ~(. nostr-client [state bowl]) + %nostr =/ mutan ~(. mutations-nostr [state bowl]) + =/ rl get-relay:mutan + ?~ rl ~& >>> "no relay!" `state + =/ wid -.u.rl + =/ relay +.u.rl + =/ nclient ~(. nostr-client [state bowl wid relay]) :: TODO now or on receival? =. following.state (~(put by following.state) user *feed:feed) =/ graph (~(get by follow-graph.state) [%urbit our.bowl]) =/ follows ?~ graph (silt ~[user]) (~(put in u.graph) user) =. follow-graph.state (~(put by follow-graph.state) [%urbit our.bowl] follows) - =^ cards state (get-user-feed:nclient +.user) + =^ cards relay (get-user-feed:nclient +.user) + =. relays.state (~(put by relays.state) wid relay) [cards state] == ++ handle-del |= =user:sur diff --git a/app/sur/nostr.hoon b/app/sur/nostr.hoon index b363cb9..b8f1e7d 100644 --- a/app/sur/nostr.hoon +++ b/app/sur/nostr.hoon @@ -33,9 +33,13 @@ $: start=@da reqs=(map sub-id event-stats) == +$ event-stats - :: if not ongoing we kill the subscription on %eose +$: filters=(list filter) + received=event-count + :: if not ongoing we kill the subscription on %eose. If ongoing we turn to .y after %eose + ongoing=(unit ?) :: if chunked we trigger a new subscription on %eose - [filters=(list filter) received=event-count ongoing=? chunked=(list filter)] + chunked=(list filter) +== +$ sub-id @t +$ event-count @ud @@ -48,7 +52,7 @@ $: sub-id=@t $: ids=(unit (set @ux)) authors=(unit (set @ux)) kinds=(unit (set @ud)) - tags=(unit (map @t (set @t))) + tags=(unit (map @t (list @t))) since=(unit @da) until=(unit @da) limit=(unit @ud) diff --git a/app/sur/nostrill.hoon b/app/sur/nostrill.hoon index c06c20c..b6aeb3a 100644 --- a/app/sur/nostrill.hoon +++ b/app/sur/nostrill.hoon @@ -88,18 +88,30 @@ $% [%reply p=post:tp] $% [%add p=@t] [%del p=@ud] :: - [%sync ~] + relay-handling + == + +$ relay-handling + $% [%sync ~] + [%user pubkey=@ux] + [%thread id=@ux] :: send event for... relaying [%send host=@p id=@ relays=(list @t)] == :: facts +$ fact - $% [%nostr feed=nostr-feed] + $% [%nostr nostr-fact] [%post post-fact] [%enga p=post-wrapper reaction=*] [%fols fols-fact] [%hark =notif] == + +$ nostr-fact + $% [%feed feed=nostr-feed] + [%user feed=nostr-feed] + [%thread feed=nostr-feed] + [%event event:nostr] + [%relays (map @ relay-stats:nostr)] + == +$ post-fact $% [%add post-wrapper] [%del post-wrapper] diff --git a/app/ted/ws.hoon b/app/ted/ws.hoon new file mode 100644 index 0000000..ac8a672 --- /dev/null +++ b/app/ted/ws.hoon @@ -0,0 +1,55 @@ +/- 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)) +=/ ujon !<((unit json) arg) +:: ~& ujon=ujon +?~ ujon (pure:m !>(bail)) +:: =/ req (ui:de:jsonlib u.ujon) +=/ jstring (en:json:html u.ujon) +~& >> jstring=jstring +:: ;< =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])) + ++ bail ^- json + %+ frond:enjs:format %error + s+'error' +-- |
