summaryrefslogtreecommitdiff
path: root/desk
diff options
context:
space:
mode:
authorpolwex <polwex@sortug.com>2025-09-17 12:24:41 +0700
committerpolwex <polwex@sortug.com>2025-09-17 12:24:41 +0700
commit387af8fc1603805b02ce03f8adba4fa73a954f7c (patch)
tree6ac4fe9c33a14d9da418a97955a38efb9338d869 /desk
parent31a47ce72255bb56920e417d250541b04be82648 (diff)
relay much more robust
Diffstat (limited to 'desk')
-rw-r--r--desk/NOTES.md39
-rw-r--r--desk/app/nostril.hoon204
-rw-r--r--desk/app/nostrill.hoon254
-rw-r--r--desk/desk.bill2
-rw-r--r--desk/desk.docket-02
-rw-r--r--desk/desk.ship2
-rw-r--r--desk/lib/constants.hoon3
-rw-r--r--desk/lib/json/common.hoon3
-rw-r--r--desk/lib/json/nostr.hoon141
-rw-r--r--desk/lib/json/nostrill.hoon (renamed from desk/lib/json/nostril.hoon)32
-rw-r--r--desk/lib/nostr.hoon24
-rw-r--r--desk/lib/nostril.hoon28
-rw-r--r--desk/lib/nostril/mutations.hoon117
-rw-r--r--desk/lib/nostrill.hoon55
-rw-r--r--desk/lib/nostrill/mutations.hoon251
-rw-r--r--desk/lib/shim.hoon112
-rw-r--r--[l---------]desk/lib/sortug.hoon147
-rw-r--r--desk/sur/nostr.hoon80
-rw-r--r--desk/sur/nostrill.hoon (renamed from desk/sur/nostril.hoon)22
-rw-r--r--desk/ted/fetch.hoon5
-rw-r--r--desk/web/assets/favicon.icobin15406 -> 14830 bytes
-rw-r--r--desk/web/components/navbar.hoon2
-rw-r--r--desk/web/pages/index.hoon2
-rw-r--r--desk/web/router.hoon4
24 files changed, 1052 insertions, 479 deletions
diff --git a/desk/NOTES.md b/desk/NOTES.md
deleted file mode 100644
index 730a478..0000000
--- a/desk/NOTES.md
+++ /dev/null
@@ -1,39 +0,0 @@
-# NIPS to implement
-
-
-- NIP-2 for follow lists
-- NIP-25 for reactions (with content), kind 7. kind 17 with content
-
-- NIP-17 for private DMs
-https://github.com/nostr-protocol/nips/blob/master/17.md
-
-- NIP-10 for mentions and replies ("marked e tags")
-
-- NIP-18 for Quotes and RTs
-
-- NIP-57 lightning zaps
-
-- NIP-51 lists?
-- NIP-22 replies?
-# Relay discovery
-
-https://nostr.watch/
-
-# Tag specs
-https://nostr-nips.com/#standardized-tags
-
-- 'e' for event,
-- 'p' for people,
-- 't' for hashtag
-- 'r' for relays
-- 'd' for identifier # wtf?
-- 'm' for mime type
-- 'a' for event coordinates
-- 'g' for geohash
-
-
-# TODO
-
-- Default keypair that of groundwire comet?
-
-lol forget the frontend make it work for Primal
diff --git a/desk/app/nostril.hoon b/desk/app/nostril.hoon
deleted file mode 100644
index 51f9965..0000000
--- a/desk/app/nostril.hoon
+++ /dev/null
@@ -1,204 +0,0 @@
-/- sur=nostril, nsur=nostr
-/+ lib=nostril, nlib=nostr, sr=sortug,
- shim, dbug, muta=nostril-mutations, jsonlib=json-nostril,
- trill=trill-post
-/= web /web/router
-|%
-+$ versioned-state $%(state-0:sur)
---
-=| versioned-state
-=* state -
-%- agent:dbug
-^- agent:gall
-|_ =bowl:gall
-+* this .
- rout ~(. router:web [state bowl])
- cards ~(. cards:lib bowl)
- mutat ~(. muta [state bowl])
-++ on-init
- ^- (quip card:agent:gall agent:gall)
- :_ this(state default:sur)
- :~ shim-binding:cards
- ==
-::
-++ on-save
- ^- vase
- !>(state)
-::
-++ on-load
- |~ old-state=vase
- ^- (quip card:agent:gall agent:gall)
- =/ old-state !<(versioned-state old-state)
- ?- -.old-state
- %0 `this(state old-state)
- ==
-::
-++ on-poke
- |~ [=mark =vase]
- ^- (quip card:agent:gall agent:gall)
- ~& >> on-poke-nostril=mark
- |^
- ?+ mark `this
- %noun debug
- %json on-ui
- %handle-http-request serve
- ==
- :: handling shim events
- ++ serve
- =/ order !<(order:web vase)
- :: ~& request.req.order
- ?: .=(url.request.req.order '/nostr-shim')
- =/ msg (handle:shim order)
- ?~ msg `this
- ~& "msg processed"
- =/ relay (~(get by relays) url.u.msg)
- =/ nevents=(list event:nsur) ?~ relay [event.u.msg ~] [event.u.msg u.relay]
- =/ nevents2 (scag 100 nevents)
- =. relays (~(put by relays) url.u.msg nevents2)
- =/ response (ebail:rout id.order)
- [response this]
-
- ::
- :_ this (rout:rout order)
-
- ::
- ++ on-ui
- =/ jon=json !<(json vase)
- ~& > on-ui-jon=jon
- =/ upoke=(unit poke:ui:sur) (ui:de:jsonlib jon)
- ?~ upoke ~& bad-ui-poke=jon `this
- ?- -.u.upoke
- %fols (handle-fols +.u.upoke)
- %prof (handle-prof +.u.upoke)
- %keys (handle-keys +.u.upoke)
- %post (handle-post +.u.upoke)
- %rela (handle-rela +.u.upoke)
- ==
- ++ handle-post |= poke=post-poke:ui:sur
- ?- -.poke
- %add
- =/ sp (build-sp:trill our.bowl our.bowl content.poke)
- =/ p (build-post:trill now.bowl pubkey.poke sp)
- =. state (add-to-feed:mutat p)
- `this
- %rt `this
- %del `this
- ==
- ++ handle-fols |= poke=fols-poke:ui:sur
- `this
- ++ handle-prof |= poke=prof-poke:ui:sur
- ?- -.poke
- %add
- =. profiles (~(put by profiles) +<.poke +>.poke)
- `this
- %del
- =. profiles (~(del by profiles) +.poke)
- `this
- ==
- ++ handle-keys |= poke=keys-poke:ui:sur
- ?- -.poke
- %add
- =/ ks (gen-keys:nlib eny.bowl)
- =. keys (~(put by keys) -.ks +.ks)
- ~& new-keys=keys
- `this
- %del
- =. profiles (~(del by profiles) +.poke)
- `this
- ==
- ++ handle-rela |= poke=relay-poke:ui:sur
- ?- -.poke
- %send
- =/ upoast (get-poast:mutat host.poke id.poke)
- ?~ upoast `this
- :_ this :_ ~
- =/ keylist ~(tap by keys)
- =/ key (snag 0 keylist)
- =/ event (post-to-event:lib key eny.bowl u.upoast)
- =/ =req:shim:nsur [%post event relays.poke]
- (send:shim dap.bowl req)
- ==
-
- ::
- ++ debug
- =/ noun !<(* vase)
- ?+ -.noun `this
- %wtf
- =/ lol=(unit @) ~
- =/ l ~| "wtf" (need lol)
- `this
- %genkey
- =/ keys (gen-keys:nlib eny.bowl)
- ~& keys=keys
- `this
- %printkey
- =/ keylist ~(tap by keys)
- =/ key (snag 0 keylist)
- ~& pub=(scow:sr %ux -.key)
- ~& priv=(scow:sr %ux +.key)
- `this
- %feed
- =/ lol debug-own-feed:mutat
- `this
- %rt :: relay test
- :_ this :_ ~
- :: khan
- =/ =req:shim:nsur :- %get
- %+ turn ~(tap by relays)
- |= [url=@t *]
- =/ kinds ~[0 1 6 7]
- =/ =filter:nsur [~ ~ kinds ~ ~ ~ `5]
- [url ~[filter]]
- (send:shim dap.bowl req)
- ::
- %rt2
- =/ rls ~(tap by relays)
- =/ lol
- |- ?~ rls ~
- =/ rl i.rls
- ~& > relay=[-.rl (lent +.rl)]
- $(rls t.rls)
- `this
- ==
- ::
- --
-::
-++ on-watch
-|= =(pole knot)
- ?> .=(our.bowl src.bowl)
- ?+ pole !!
- [%ui ~]
- :_ this
- =/ jon (state:en:jsonlib state)
- [%give %fact ~ [%json !>(jon)]]^~
- ==
-::
-++ on-leave
- |~ =(pole knot)
- ^- (quip card:agent:gall agent:gall)
- `this
-::
-++ on-peek
- |~ =(pole knot)
- ^- (unit (unit cage))
- ~& > on-peek=pole
- ?+ pole ~
- [%j %feed rest=*] ~
- [%j %post rest=*] ~
- ==
-::
-++ on-agent
- |~ [wire sign:agent:gall]
- ^- (quip card:agent:gall agent:gall)
- `this
-::
-++ on-arvo
- |~ [wire =sign-arvo]
- ^- (quip card:agent:gall agent:gall)
- `this
-::
-++ on-fail
- |~ [term tang]
- ^- (quip card:agent:gall agent:gall)
- `this
---
diff --git a/desk/app/nostrill.hoon b/desk/app/nostrill.hoon
new file mode 100644
index 0000000..575fa3e
--- /dev/null
+++ b/desk/app/nostrill.hoon
@@ -0,0 +1,254 @@
+/- sur=nostrill, nsur=nostr
+/+ lib=nostrill, nlib=nostr, sr=sortug,
+ shim, dbug, muta=nostrill-mutations, jsonlib=json-nostrill,
+ trill=trill-post
+/= web /web/router
+|%
++$ versioned-state $%(state-0:sur)
+--
+=| versioned-state
+=* state -
+%- agent:dbug
+^- agent:gall
+|_ =bowl:gall
++* this .
+ rout ~(. router:web [state bowl])
+ cards ~(. cards:lib bowl)
+ mutat ~(. muta [state bowl])
+ shimm ~(. shim [state bowl])
+++ on-init
+ ^- (quip card:agent:gall agent:gall)
+ =/ default (default-state:lib bowl)
+ :_ this(state default)
+ :~ shim-binding:cards
+ ==
+::
+++ on-save
+ ^- vase
+ !>(state)
+::
+++ on-load
+ |~ old-state=vase
+ ^- (quip card:agent:gall agent:gall)
+ =/ old-state !<(versioned-state old-state)
+ ?- -.old-state
+ %0 `this(state old-state)
+ ==
+::
+++ on-poke
+ |~ [=mark =vase]
+ ^- (quip card:agent:gall agent:gall)
+ |^
+ ?+ mark `this
+ %noun debug
+ %json on-ui
+ %handle-http-request handle-shim
+ ==
+ :: handling shim events
+ ++ handle-shim
+ =/ order !<(order:web vase)
+ :: ~& request.req.order
+ ?: .=(url.request.req.order '/nostr-shim')
+ =/ msg (parse-msg:shim order)
+ ?~ msg `this
+ ?> ?=(%ws -.u.msg)
+ :: =^ cards state (handle-shim-msg:mutat u.msg)
+ =^ cards state (handle-ws:mutat +.u.msg)
+ [cards this]
+
+ ::
+ :_ this (rout:rout order)
+
+ ::
+ ++ on-ui
+ =/ jon=json !<(json vase)
+ ~& > on-ui-jon=jon
+ =/ upoke=(unit poke:ui:sur) (ui:de:jsonlib jon)
+ ?~ upoke ~& bad-ui-poke=jon `this
+ ?- -.u.upoke
+ %keys handle-cycle-keys
+ %fols (handle-fols +.u.upoke)
+ %prof (handle-prof +.u.upoke)
+ %post (handle-post +.u.upoke)
+ %rela (handle-rela +.u.upoke)
+ ==
+ ++ handle-cycle-keys
+ =/ ks (gen-keys:nlib eny.bowl)
+ =. keys [ks keys]
+ :: =/ nkeys keys(i ks, t `(list keys:nsur)`keys)
+ :: :: =. keys nkeys
+ ~& new-keys=keys
+ `this
+
+ ++ handle-post |= poke=post-poke:ui:sur
+ ?- -.poke
+ %add
+ =/ sp (build-sp:trill our.bowl our.bowl content.poke)
+ =/ p (build-post:trill now.bowl pubkey.poke sp)
+ =. state (add-to-feed:mutat p)
+ `this
+ %rt `this
+ %del `this
+ ==
+ ++ handle-fols |= poke=fols-poke:ui:sur
+ `this
+ ++ handle-prof |= poke=prof-poke:ui:sur
+ ?- -.poke
+ %add
+ =. profiles (~(put by profiles) +<.poke +>.poke)
+ `this
+ %del
+ =. profiles (~(del by profiles) +.poke)
+ `this
+ ==
+ ++ handle-rela |= poke=relay-poke:ui:sur
+ ?- -.poke
+ %send
+ =/ upoast (get-poast:mutat host.poke id.poke)
+ ?~ upoast `this
+ =/ event (post-to-event:lib i.keys eny.bowl u.upoast)
+ =/ req=bulk-req:shim:nsur [relays.poke %event event]
+ =/ cards :~((send:shimm req))
+ [cards this]
+ ==
+
+
+ ::
+ ++ debug
+ =/ noun !<(* vase)
+ ?+ noun `this
+ %wtf
+ =/ lol=(unit @) ~
+ =/ l ~| "wtf" (need lol)
+ `this
+ %genkey
+ =/ keys (gen-keys:nlib eny.bowl)
+ ~& keys=keys
+ `this
+ %printkey
+ =/ key i.keys
+ ~& pub=(scow:sr %ux -.key)
+ ~& priv=(scow:sr %ux +.key)
+ `this
+ %feed
+ =/ lol debug-own-feed:mutat
+ `this
+ %nstats
+ ~& nostr-feed=~(wyt by nostr-feed)
+ ~& profiles=~(wyt in ~(key by profiles))
+ =/ lol (print-relay-stats:lib relays)
+
+ `this
+ %http
+ ~& pending=pending
+ `this
+ %rt :: relay test
+ =^ cards state get-posts:shimm
+ [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:mutat -.ids)
+ :: (get-profiles:shimm +.ids)
+ :: (get-engagement:shimm -.ids)
+ [cards this]
+ %rt1
+ =/ l ~(tap by pending)
+ =/ l (scag 1 l)
+ =| 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:nlib 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:mutat pks)
+ [cards this]
+ ==
+
+ ::
+ --
+::
+++ on-watch
+|= =(pole knot)
+ ?> .=(our.bowl src.bowl)
+ ?+ pole !!
+ [%ui ~]
+ :_ this
+ =/ jon (state:en:jsonlib state)
+ [%give %fact ~ [%json !>(jon)]]^~
+ ==
+::
+++ on-leave
+ |~ =(pole knot)
+ ^- (quip card:agent:gall agent:gall)
+ `this
+::
+++ on-peek
+ |~ =(pole knot)
+ ^- (unit (unit cage))
+ ~& > on-peek=pole
+ ?+ pole ~
+ [%j %feed rest=*] ~
+ [%j %post rest=*] ~
+ ==
+::
+++ on-agent
+ |~ [wire sign:agent:gall]
+ ^- (quip card:agent:gall agent:gall)
+ `this
+::
+++ on-arvo
+ |~ [wire=(pole knot) =sign-arvo]
+ ^- (quip card:agent:gall agent:gall)
+ ?+ wire `this
+ [%http sub-id=@t *]
+ ?> ?=([%khan %arow *] sign-arvo)
+ ?: ?=(%| -.p.sign-arvo) `this
+ =/ jstring !<(@ +>.p.sign-arvo)
+ =/ msg (parse-body:shimm jstring)
+ ?~ msg ~& `@t`jstring `this
+ ?> ?=(%http -.u.msg)
+ =^ cards state (handle-http:mutat sub-id.wire +.u.msg)
+ `this
+ ==
+::
+++ on-fail
+ |~ [term tang]
+ ^- (quip card:agent:gall agent:gall)
+ `this
+--
diff --git a/desk/desk.bill b/desk/desk.bill
index 9611612..ddea07e 100644
--- a/desk/desk.bill
+++ b/desk/desk.bill
@@ -1,2 +1,2 @@
-:~ %nostril
+:~ %nostrill
==
diff --git a/desk/desk.docket-0 b/desk/desk.docket-0
index 1eee1d5..e30a841 100644
--- a/desk/desk.docket-0
+++ b/desk/desk.docket-0
@@ -8,4 +8,4 @@
image+'https://s3.sortug.com/img/nostril-icon.png'
base+'nostril'
glob-http+['https://s3.sortug.com/globs/glob-0v1.862v7.o85ao.krj6r.v1dgc.ek27l.glob' 0v1.862v7.o85ao.krj6r.v1dgc.ek27l]
-==
+== \ No newline at end of file
diff --git a/desk/desk.ship b/desk/desk.ship
index 56a71f3..2d56596 100644
--- a/desk/desk.ship
+++ b/desk/desk.ship
@@ -1 +1 @@
-~polwex
+~polwex \ No newline at end of file
diff --git a/desk/lib/constants.hoon b/desk/lib/constants.hoon
new file mode 100644
index 0000000..c7f72b7
--- /dev/null
+++ b/desk/lib/constants.hoon
@@ -0,0 +1,3 @@
+|%
+++ http-delay 3.000
+--
diff --git a/desk/lib/json/common.hoon b/desk/lib/json/common.hoon
index 64d4b03..0ed54cd 100644
--- a/desk/lib/json/common.hoon
+++ b/desk/lib/json/common.hoon
@@ -5,7 +5,8 @@
|%
++ cord |= s=@t ^- json s+s
++ hex |= h=@ux ^- json
- [%s (crip (scow:sr %ux h))]
+ =/ scoww scow:sr
+ [%s (crip (scoww(min-chars 64) %ux h))]
++ b64 |= h=@uv ^- json
[%s (crip (scow:sr %uv h))]
++ ud |= n=@ ^- json
diff --git a/desk/lib/json/nostr.hoon b/desk/lib/json/nostr.hoon
index aa5952a..9c36eb0 100644
--- a/desk/lib/json/nostr.hoon
+++ b/desk/lib/json/nostr.hoon
@@ -2,29 +2,39 @@
/+ common=json-common, sr=sortug
|%
++ en
-=, enjs:format
+=, enjs:format
|%
:: shim comms
- ++ req |= =req:shim:sur ^- json
- %+ frond -.req
- ?- -.req
- %get (get +.req)
- %post (post +.req)
- ==
- ++ get |= rs=get:shim:sur
- :- %a %+ turn rs |= [r=@t fs=(list filter:sur)]
+ ++ bulk-req |= [relays=(list @t) r=req:shim:sur] ^- json
+ %+ frond %ws
%: pairs
- relay+s+r
- filters+a+(turn fs filter)
+ relays+a+(turn relays cord:en:common)
+ req+(req r)
~
==
- ::
- ++ post |= p=post:shim:sur
+ ++ http-req |= [relay=@t delay=@ud sub-id=@t fs=(list filter:sur)]
+ %+ frond %http
%: pairs
- event+(event event.p)
- relays+a+(turn relays.p cord:en:common)
- ~
+ relay+s+relay
+ delay+(numb delay)
+ ['subscription_id' %s sub-id]
+ filters+a+(turn fs filter)
+ ~
==
+ ++ req |= =req:shim:sur ^- json
+ :- %a :- s+(crip (cuss (trip -.req)))
+ ?- -.req
+ %req (enreq +.req)
+ %event :_ ~ (event +.req)
+ %auth :_ ~ (event +.req)
+ %close :_ ~ [%s +.req]
+ ==
+++ enreq
+ |= [sub-id=@t fs=(list filter:sur)]
+ ^- (list json)
+ :- [%s sub-id]
+ %+ turn fs filter
+
::
++ raw-event |= raw-event:sur
:: WTF nostr doesn't want the prefix on the pubkey
@@ -64,33 +74,82 @@
++ filter
|= f=filter:sur ^- json
=| l=(list [key=@t jon=json])
- =. l ?~ ids.f l :_ l ['ids' [%a (turn ids.f hex:en:common)]]
- =. l ?~ authors.f l :_ l ['authors' [%a (turn authors.f hex:en:common)]]
- =. l ?~ kinds.f l :_ l ['kinds' [%a (turn kinds.f numb)]]
- =. l ?~ since.f l :_ l ['since' (numb u.since.f)]
- =. l ?~ until.f l :_ l ['until' (numb u.until.f)]
+ =. l ?~ ids.f l :_ l ['ids' %a (turn ~(tap in u.ids.f) hex:en:common)]
+ =. l ?~ authors.f l :_ l ['authors' %a (turn ~(tap in u.authors.f) hex:en:common)]
+ =. l ?~ kinds.f l :_ l ['kinds' %a (turn ~(tap in u.kinds.f) numb)]
+ =. l ?~ tags.f l %+ weld l (tags u.tags.f)
+
+ =. l ?~ since.f l :_ l ['since' (sect u.since.f)]
+ =. l ?~ until.f l :_ l ['until' (sect u.until.f)]
=. l ?~ limit.f l :_ l ['limit' (numb u.limit.f)]
+ ::
%- pairs l
+
+
+ ++ tags
+ |= tm=(map @t (set @t)) ^- (list [@t json]) :: entries to the filter obeject
+ %+ turn ~(tap by tm) |= [key=@t values=(set @t)]
+ =/ nkey (cat 3 '#' key)
+ [nkey %a (turn ~(tap in values) cord:en:common)]
+
++ user-meta
|= meta=user-meta:sur
- =/ other %+ turn ~(tap by other.meta) |= [key=@t val=@t]
- [key %s val]
%: pairs
name+s+name.meta
picture+s+picture.meta
about+s+about.meta
- other
+ other+o+other.meta
+ ~
==
--
++ de
=, dejs-soft:format
|%
:: shim
+ ++ shim-res
+ %- of :~
+ http+(ar relay-msg)
+ ws+msg
+ ==
++ msg
%- ot :~
relay+so
+ msg+relay-msg
+ ==
+ ++ relay-msg
+ %- of :~
+ event+event-sub
+ ok+relay-ok
+ eose+so
+ closed+closed
+ notice+so
+ error+so
+ ==
+
+
+ :: | { event: { subscription_id: string; event: NostrEvent } }
+ :: | { ok: { event_id: string; accepted: boolean; message: string } }
+ :: | { eose: string }
+ :: | { closed: { subscription_id: string; message: string } }
+ :: | { notice: string }
+ :: // this is ours
+ :: | { error: string };
+ ++ event-sub
+ %- ot :~
+ ['subscription_id' so]
event+event
==
+ ++ relay-ok
+ %- ot :~
+ ['event_id' hex:de:common]
+ accepted+bo
+ message+so
+ ==
+ ++ closed
+ %- ot :~
+ ['subscription_id' so]
+ message+so
+ ==
++ event
%- ot :~
id+hex:de:common
@@ -103,14 +162,30 @@
==
++ user-meta |= jon=json
^- (unit user-meta:sur)
- =/ all ((om so) jon)
- ?~ all ~
- =/ base=(unit [name=@t about=@t picture=@t]) %. jon %- ot :~
- name+so
- about+so
- picture+so
- ==
- ?~ base ~
- `[name.u.base about.u.base picture.u.base u.all]
+ ?. ?=(%o -.jon) ~
+ =| um=user-meta:sur
+ =/ fields ~(tap by p.jon)
+ |- ?~ fields (some um)
+ =/ k -.i.fields
+ =/ jn=json +.i.fields
+ ?+ k
+ =/ ot (~(put by other.um) k jn)
+ =. um um(other ot) $(fields t.fields)
+ %'name'
+ =/ crd (so jn)
+ ?~ crd $(fields t.fields) $(fields t.fields, um um(name u.crd))
+ %'display_name'
+ =/ crd (so jn)
+ ?~ crd $(fields t.fields) $(fields t.fields, um um(name u.crd))
+ %'displayName'
+ =/ crd (so jn)
+ ?~ crd $(fields t.fields) $(fields t.fields, um um(name u.crd))
+ %'about'
+ =/ crd (so jn)
+ ?~ crd $(fields t.fields) $(fields t.fields, um um(picture u.crd))
+ %'picture'
+ =/ crd (so jn)
+ ?~ crd $(fields t.fields) $(fields t.fields, um um(picture u.crd))
+ ==
--
--
diff --git a/desk/lib/json/nostril.hoon b/desk/lib/json/nostrill.hoon
index 16792a9..43f7708 100644
--- a/desk/lib/json/nostril.hoon
+++ b/desk/lib/json/nostrill.hoon
@@ -1,4 +1,4 @@
-/- sur=nostril, nsur=nostr, feed=trill-feed
+/- sur=nostrill, nsur=nostr, feed=trill-feed
/+ sr=sortug, common=json-common, trill=json-trill, nostr=json-nostr
|%
++ en
@@ -8,18 +8,33 @@
++ state |= state-0:sur ^- json
%: pairs
relays+(en-relays relays)
- keys+a+(turn ~(tap in ~(key by keys)) hex:en:common)
+ key+(hex:en:common pub.i.keys)
profiles+(en-profiles profiles)
+ :: TODO proper cursors
feed+(feed-with-cursor:en:trill feed ~ ~)
+ nostr+(en-nostr-feed nostr-feed)
following+(enfollowing following)
['followGraph' (engraph follow-graph)]
~
==
+ ++ en-nostr-feed
+ |= feed=nostr-feed:sur ^- json
+ :- %a %+ turn (tap:norm:sur feed) |= [id=@ud ev=event:nsur]
+ (event:en:nostr ev)
+
++ en-relays
- |= r=(map @t (list event:nsur)) ^- json
+ |= r=(map @t relay-stats:nsur) ^- json
%- pairs %+ turn ~(tap by r)
- |= [url=@t events=(list event:nsur)]
- :- url :- %a %+ turn events event:en:nostr
+ |= [url=@t rs=relay-stats:nsur]
+ :- url %- pairs
+ :~ :- %connected ?~ connected.rs ~ (time u.connected.rs)
+ :- %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]
+ :: TODO do we even need this
+ :- sub-id (numb received.es)
+
++ en-profiles |= m=(map @ux user-meta:nsur)
%- pairs
%+ turn ~(tap by m) |= [key=@ux p=user-meta:nsur]
@@ -51,9 +66,9 @@
:: ui
++ ui
%- of :~
+ keys+ul
fols+ui-fols
prof+ui-prof
- keys+ui-keys
post+ui-post
rela+ui-relay
==
@@ -71,11 +86,6 @@
pubkey+hex:de:common
meta+user-meta:de:nostr
==
-++ ui-keys
- %- of :~
- add+ul
- del+hex:de:common
- ==
++ ui-post
%- of :~
add+de-post
diff --git a/desk/lib/nostr.hoon b/desk/lib/nostr.hoon
index c05b0eb..90eb563 100644
--- a/desk/lib/nostr.hoon
+++ b/desk/lib/nostr.hoon
@@ -1,6 +1,8 @@
/- sur=nostr
-/+ js=json-nostr
+/+ js=json-nostr, sr=sortug
|%
+++ gen-sub-id |= eny=@ ^- @t
+ %- crip (scag 60 (scow:sr %uw eny))
++ gen-keys |= eny=@ ^- keys:sur
=, secp256k1:secp:crypto
=/ privkey
@@ -26,4 +28,24 @@
++ sign-event |= [priv=@ux hash=@ux eny=@]
=^ sed eny (raws eny 256)
(sign:schnorr:secp256k1:secp:crypto priv hash sed)
+
+
+::
+++ validate-pubkey |= pubkey=@ux ^- ?
+ =/ tap (scow:sr %ux pubkey)
+ .= (lent tap) 64
+::
+++ diff-filters
+|= [a=filter:sur b=filter:sur] ^- filter:sur
+ =/ ids (unit-set-dif ids.a ids.b)
+ =/ authors (unit-set-dif authors.a authors.b)
+ =/ kinds (unit-set-dif kinds.a kinds.b)
+ =/ tags ~
+ =/ since ~
+ =/ until ~
+ =/ limit ~ :: TODO
+ [ids authors kinds tags since until limit]
+++ unit-set-dif
+ |* [a=(unit) b=(unit)]
+ %^ clap a b |* [x=(set) y=(set)] (~(dif in x) y)
--
diff --git a/desk/lib/nostril.hoon b/desk/lib/nostril.hoon
deleted file mode 100644
index 48d4eb7..0000000
--- a/desk/lib/nostril.hoon
+++ /dev/null
@@ -1,28 +0,0 @@
-/- post=trill-post, nsur=nostr
-/+ trill=trill-post, nostr, sr=sortug
-|%
-::
-++ 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))
- =/ ts (to-unix-secs:jikan:sr id.p)
- =/ raw=raw-event:nsur [pub.keys ts 1 ~ string]
- =/ event-id (hash-event:nostr raw)
- =/ signature (sign-event:nostr priv.keys event-id eny)
- ~& hash-and-signed=[event-id signature]
- =/ =event:nsur :*
- event-id
- pub.keys
- created-at.raw
- kind.raw
- tags.raw
- content.raw
- signature
- ==
- event
-++ cards
-|_ =bowl:gall
- ++ shim-binding ^- card:agent:gall
- [%pass /binding %arvo %e %connect [~ /nostr-shim] dap.bowl]
- --
---
diff --git a/desk/lib/nostril/mutations.hoon b/desk/lib/nostril/mutations.hoon
deleted file mode 100644
index f7de23b..0000000
--- a/desk/lib/nostril/mutations.hoon
+++ /dev/null
@@ -1,117 +0,0 @@
-/- sur=nostril, nsur=nostr,
- post=trill-post, gate=trill-gate, feed=trill-feed
-
-/+ appjs=json-nostril,
- njs=json-nostr,
- postlib=nostril-post,
- sr=sortug
-
-|_ [=state:sur =bowl:gall]
-++ debug-own-feed
- =/ postlist (tap:orm:feed feed.state)
- =/ lol
- |- ?~ postlist ~
- ~& >> poast=+.i.postlist
- $(postlist t.postlist)
- ~
-:: TODO not a mutation but fuck it
-++ get-poast |= [host=@p id=@] ^- (unit post:post)
- =/ poast ?: .=(host our.bowl)
- (get:orm:feed feed.state id)
- ~
- poast
-
-:: state
-++ add-to-feed |= p=post:post
- =. feed.state (put:orm:feed feed.state id.p p)
- state
-:: events
-++ process-events ^- (quip card _state)
- :: =/ l events.state
- :: =| cards=(list card:agent:gall)
- :: |- ?~ l [cards state]
- :: =/ n (event-parsing i.l)
- :: $(cards -.n, state +.n, l t.l)
- :: TODO
- `state
-
-++ event-parsing
- |= =event:nsur
- ^- (quip card _state)
- |^
-:: https://nostrdata.github.io/kinds/
- ?: .=(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 !!
- =/ umeta (user-meta:de:njs u.ujon)
- ?~ umeta `state
- =. profiles.state (~(put by profiles.state) pubkey.event u.umeta)
- `state
-
-
- ++ parse-poast
- ^- (quip card _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) 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)
- --
---
diff --git a/desk/lib/nostrill.hoon b/desk/lib/nostrill.hoon
new file mode 100644
index 0000000..c7e940c
--- /dev/null
+++ b/desk/lib/nostrill.hoon
@@ -0,0 +1,55 @@
+/- post=trill-post, nsur=nostr, sur=nostrill
+/+ trill=trill-post, nostr, sr=sortug
+|%
+::
+++ 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 eny.bowl)
+ =/ keyl [key ~]
+ s(relays (malt rl), keys keyl)
+
+++ print-relay-stats
+ |= rm=(map @t relay-stats:nsur)
+ =/ l ~(tap by rm)
+ |- ?~ l ~
+ =/ [url=@t rs=relay-stats:nsur] i.l
+ ~& relay=url
+ ~& connected=connected.rs
+ ~& sub-count=~(wyt by reqs.rs)
+ =/ total-received
+ %+ roll ~(tap by reqs.rs)
+ |= [[* es=event-stats:nsur] acc=@ud]
+ %+ add acc received.es
+ ~& >> total=total-received
+ $(l t.l)
+
+::
+++ 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))
+ =/ ts (to-unix-secs:jikan:sr id.p)
+ =/ raw=raw-event:nsur [pub.keys ts 1 ~ string]
+ =/ event-id (hash-event:nostr raw)
+ =/ signature (sign-event:nostr priv.keys event-id eny)
+ ~& hash-and-signed=[event-id signature]
+ =/ =event:nsur :*
+ event-id
+ pub.keys
+ created-at.raw
+ kind.raw
+ tags.raw
+ content.raw
+ signature
+ ==
+ event
+++ cards
+|_ =bowl:gall
+ ++ shim-binding ^- card:agent:gall
+ [%pass /binding %arvo %e %connect [~ /nostr-shim] dap.bowl]
+ --
+--
diff --git a/desk/lib/nostrill/mutations.hoon b/desk/lib/nostrill/mutations.hoon
new file mode 100644
index 0000000..4dda095
--- /dev/null
+++ b/desk/lib/nostrill/mutations.hoon
@@ -0,0 +1,251 @@
+/- sur=nostrill, nsur=nostr,
+ post=trill-post, gate=trill-gate, feed=trill-feed
+
+/+ appjs=json-nostrill,
+ njs=json-nostr,
+ postlib=trill-post,
+ shim,
+ sr=sortug
+
+|_ [=state:sur =bowl:gall]
++$ card card:agent:gall
+++ debug-own-feed
+ =/ postlist (tap:orm:feed feed.state)
+ =/ lol
+ |- ?~ postlist ~
+ ~& >> poast=+.i.postlist
+ $(postlist t.postlist)
+ ~
+:: TODO not a mutation but fuck it
+++ get-poast |= [host=@p id=@] ^- (unit post:post)
+ =/ poast ?: .=(host our.bowl)
+ (get:orm:feed feed.state id)
+ ~
+ poast
+
+:: state
+++ add-to-feed |= p=post:post
+ =. feed.state (put:orm:feed feed.state id.p p)
+ state
+:: events
+++ process-events ^- (quip card _state)
+ :: =/ l events.state
+ :: =| cards=(list card:agent:gall)
+ :: |- ?~ l [cards state]
+ :: =/ n (event-parsing i.l)
+ :: $(cards -.n, state +.n, l t.l)
+ :: TODO
+ `state
+
+:: ++ parse-events
+:: |= evs=(list event:nsur)
+:: ^- (quip card _state)
+:: =| cards=(list card)
+:: =^ cards state
+:: |- ?~ evs [cards state]
+:: =^ cards state (handle-event i.evs)
+:: $(evs t.evs)
+:: [cards state]
+
+++ populate-profiles
+ |= pubkeys=(set @ux)
+ ^- (quip card _state)
+ =/ shimm ~(. shim [state bowl])
+ =^ cards state (get-profiles-http:shimm pubkeys)
+ [cards state]
+
+
+
+
+:: ++ handle-shim-msg |= msg=res:shim:nsur
+:: ^- (quip card _state)
+:: ?- -.msg
+:: %ws (handle-ws +.msg)
+:: %http (handle-http +.msg)
+:: ==
+
+++ handle-http
+ |= [sub-id=@t msgs=(list relay-msg:nsur)]
+ ~& handling-http=[sub-id (lent msgs)]
+ =| cards=(list card)
+ |- ?~ msgs [cards state]
+ =^ cards state (handle-msg i.msgs)
+ $(msgs t.msgs)
+
+
+++ 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
+ %error ~& >>> relay-error=+.msg
+ `state
+ ==
+
+++ handle-ws |= [relay=@t msg=relay-msg:nsur]
+ =/ rs (~(get by relays.state) relay)
+ ?~ rs `state
+ =^ cards state
+ ?- -.msg
+ %ok (handle-ok relay +.msg)
+ %event
+ =. relays.state (update-relay-stats relay sub-id.msg)
+ (handle-event relay sub-id.msg event.msg)
+
+ %eose
+ :: TODO do unsub for replaceable/addressable events
+ :: =/ creq (~(get by reqs.u.rs) +.msg)
+ :: ?~ creq `state
+ :: =. reqs.u.rs (~(del by reqs.u.rs) +.msg)
+ :: =. relays.state (~(put by relays.state) relay u.rs)
+ `state
+ %closed =. reqs.u.rs (~(del by reqs.u.rs) sub-id.msg)
+ =. relays.state (~(put by relays.state) relay u.rs)
+ `state
+ %auth ~& >> auth=+.msg :: TODO handle auth challenges?
+ `state
+ %notice ~& >> notice=+.msg :: TODO pass to UI?
+ `state
+ %error ~& >>> relay-error=+.msg
+ =. relays.state (~(del by relays.state) relay)
+ `state
+ ==
+ [cards state]
+
+
+ :: =^ cards state (handle-event:mutat url.u.msg sub-id.u.msg event.u.msg)
+ :: :: TODO not just stash events
+ :: =/ relay (~(get by relays) url.u.msg)
+ :: =/ nevents=(list event:nsur) ?~ relay [event.u.msg ~] [event.u.msg u.relay]
+ :: =/ nevents2 (scag 100 nevents)
+
+ :: =. relays (~(put by relays) url.u.msg nevents2)
+ :: :: TODO respond better
+ :: =/ response (ebail:rout id.order)
+ :: =/ ncards (weld cards response)
+
+ :: [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-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-shim-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) 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-follow
+ ^- (quip card _state)
+ =/ following (~(get by follow-graph.state) 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-shim-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
+ --
+--
diff --git a/desk/lib/shim.hoon b/desk/lib/shim.hoon
index be95b70..4afdf2b 100644
--- a/desk/lib/shim.hoon
+++ b/desk/lib/shim.hoon
@@ -1,23 +1,115 @@
-/- sur=nostr
-/+ js=json-nostr
+/- sur=nostrill, nsur=nostr
+/+ js=json-nostr, sr=sortug, nlib=nostr, constants
/= web /web/router
-|%
+|_ [=state:sur =bowl:gall]
-++ handle
++$ card card:agent:gall
+++ parse-msg
|= [eyre-id=@ta req=inbound-request:eyre]
- ^- (unit [url=@ event=event:sur])
+ ^- (unit res:shim:nsur)
?~ body.request.req ~
=/ jstring q.u.body.request.req
+ (parse-body jstring)
+++ parse-body |= jstring=@t
=/ ures (de:json:html jstring)
?~ ures ~
- (msg:de:js u.ures)
+ (shim-res:de:js u.ures)
+:: __
+++ get-req |= fs=(list filter:nsur)
+ ^- [bulk-req:shim:nsur _state]
+ =/ rls ~(tap by relays.state)
+ =| urls=(list @t)
+ =/ sub-id (gen-sub-id:nlib eny.bowl)
+ =/ =req:shim:nsur [%req sub-id fs]
+ |- ?~ rls [[urls req] state]
+ :: 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)
+
+++ get-posts
+ ^- (quip card _state)
+ =/ kinds (silt ~[1])
+ =/ last-week (sub now.bowl ~d7)
+ :: =/ since (to-unix-secs:jikan:sr last-week)
+ =/ =filter:nsur [~ ~ `kinds ~ `last-week ~ ~]
+ =^ req=bulk-req:shim:nsur state (get-req ~[filter])
+ :- :~((send req)) state
+
+++ get-profiles
+ |= pubkeys=(set @ux)
+ ^- (quip card _state)
+ =/ kinds (silt ~[0])
+ =/ =filter:nsur [~ `pubkeys `kinds ~ ~ ~ ~]
+ =^ req=bulk-req:shim:nsur state (get-req ~[filter])
+ :- :~((send req)) state
+
+++ get-engagement
+ |= post-ids=(set @ux)
+ ^- (quip card _state)
+ =/ post-strings %- ~(run in post-ids) |= id=@ux (crip (scow:sr %ux id))
+ =/ =filter:nsur
+ =/ kinds (silt ~[6 7])
+ =/ tags (malt :~([%e post-strings]))
+ [~ ~ `kinds `tags ~ ~ ~]
+ =^ req state (get-req ~[filter])
+ :- :~((send req)) state
+
+++ 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])]))
+ =/ =filter:nsur [~ ~ `kinds `tags ~ ~ ~]
+ =^ req state (get-req ~[filter])
+ :- :~((send req)) state
+
+
++ send
- |= [desk=@tas =req:shim:sur] ^- card:agent:gall
- =/ req-body (req:en:js req)
+ |= req=bulk-req:shim:nsur ^- card:agent:gall
+ =/ req-body (bulk-req:en:js req)
+ :: ~& shim-req-json=(en:json:html req-body)
=/ headers :~
[key='content-type' value='application/json']
==
- =/ =request:http [%'POST' url:shim:sur headers `(json-body:web req-body)]
+ =/ =request:http [%'POST' url:shim:nsur headers `(json-body:web req-body)]
=/ pat /shim
- [%pass (weld /ws pat) %arvo %k %fard desk %fetch %noun !>(request)]
+ [%pass (weld /ws pat) %arvo %k %fard dap.bowl %fetch %noun !>(request)]
+
+++ 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)
+ =/ headers :~
+ [key='content-type' value='application/json']
+ ==
+ =/ =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:nlib eny.bowl)
+ =/ kinds (silt ~[0])
+ =/ total=filter:nsur [~ `pubkeys `kinds ~ ~ ~ ~]
+ =/ chunk (silt (scag 10 ~(tap in pubkeys)))
+ =/ =filter:nsur [~ `chunk `kinds ~ ~ ~ ~]
+ =. pending.state (~(put by pending.state) sub-id [total *filter:nsur])
+ =/ req=http-req:shim:nsur [relay http-delay:constants sub-id ~[total]]
+ =/ =card (send-http req)
+ :- :~(card) state
+
--
diff --git a/desk/lib/sortug.hoon b/desk/lib/sortug.hoon
index dad4203..eec99ae 120000..100644
--- a/desk/lib/sortug.hoon
+++ b/desk/lib/sortug.hoon
@@ -1 +1,146 @@
-/home/y/code/urbit/sortug/lib/sortug.hoon \ No newline at end of file
+:: Painstakingly built utility functions by Sortug Development Ltd.
+:: There's more where it came from
+|%
+++ jikan
+|%
+++ from-unix |= ts=@ ^- @da
+ (from-unix:chrono:userlib ts)
+++ to-unix-ms |= da=@da ^- @ud
+ (unm:chrono:userlib da)
+++ to-unix-secs |= da=@da ^- @ud
+ (unt:chrono:userlib da)
+--
+++ b64 (bass 64 (plus siw:ab))
+++ b16 (bass 16 (plus six:ab))
+++ scow
+=| min-chars=@ud
+|= [mod=@tas a=@] ^- tape
+ ?+ mod ""
+ %s (signed-scow a)
+ %ud (a-co:co a)
+ %ux ((x-co:co min-chars) a)
+ %uv ((v-co:co min-chars) a)
+ %uw ((w-co:co min-chars) a)
+ ==
+++ signed-scow |= a=@s ^- tape
+ =/ old (old:si a)
+ =/ num (scow %ud +.old)
+ =/ sign=tape ?: -.old "" "-"
+ "{sign}{num}"
+++ slaw
+ |= [mod=@tas txt=@t] ^- (unit @)
+ ?+ mod ~
+ %ud (rush txt dem)
+ %ux (rush txt b16)
+ %uv (rush txt vum:ag)
+ %uw (rush txt b64)
+ ==
+++ csplit |* =rule
+ (more rule (cook crip (star ;~(less rule next))))
+:: List utils
+++ foldi
+ |* [a=(list) b=* c=_|=(^ +<+)]
+ =| i=@ud
+ |- ^+ b
+ ?~ a b
+ =/ nb (c i i.a b)
+ $(a t.a, b nb, i +(i))
+++ parsing
+ |%
+ ++ link auri:de-purl:html
+ ++ para
+ |%
+ ++ eof ;~(less next (easy ~))
+ ++ white (mask "\09 ")
+ ++ blank ;~(plug (star white) (just '\0a'))
+ ++ hard-wrap (cold ' ' ;~(plug blank (star white)))
+ ++ one-space (cold ' ' (plus white))
+ ++ empty
+ ;~ pose
+ ;~(plug blank (plus blank))
+ ;~(plug (star white) eof)
+ ;~(plug blank (star white) eof)
+ ==
+ ++ para
+ %+ ifix
+ [(star white) empty]
+ %- plus
+ ;~ less
+ empty
+ next
+ ==
+ --
+ ++ trim para:para :: from whom/lib/docu
+ ++ youtube
+ ;~ pfix
+ ;~ plug
+ (jest 'https://')
+ ;~ pose
+ (jest 'www.youtube.com/watch?v=')
+ (jest 'youtube.com/watch?v=')
+ (jest 'youtu.be/')
+ ==
+ ==
+ ;~ sfix
+ (star aln)
+ (star next)
+ ==
+ ==
+ ++ twatter
+ ;~ pfix
+ ;~ plug
+ (jest 'https://')
+ ;~ pose
+ (jest 'x.com/')
+ (jest 'twitter.com/')
+ ==
+ (star ;~(less fas next))
+ (jest '/status/')
+ ==
+ ;~ sfix
+ (star nud)
+ (star next)
+ ==
+ ==
+ ++ img-set
+ %- silt
+ :~ ~.webp
+ ~.png
+ ~.jpeg
+ ~.jpg
+ ~.svg
+ ==
+ ++ is-img
+ |= t=@ta
+ (~(has in img-set) t)
+ ++ is-image
+ |= url=@t ^- ?
+ =/ u=(unit purl:eyre) (de-purl:html url)
+ ?~ u .n
+ =/ ext p.q.u.u
+ ?~ ext .n
+ (~(has in img-set) u.ext)
+ --
+++ string
+|%
+++ replace
+ |= [bit=tape bot=tape =tape]
+ ^- ^tape
+ |-
+ =/ off (find bit tape)
+ ?~ off tape
+ =/ clr (oust [(need off) (lent bit)] tape)
+ $(tape :(weld (scag (need off) clr) bot (slag (need off) clr)))
+ ::
+++ split
+ |= [str=tape delim=tape]
+ ^- (list tape)
+ (split-rule str (jest (crip delim)))
+ ++ split-rule
+ |* [str=tape delim=rule]
+ ^- (list tape)
+ %+ fall
+ (rust str (more delim (star ;~(less delim next))))
+ [str ~]
+--
+--
diff --git a/desk/sur/nostr.hoon b/desk/sur/nostr.hoon
index 78c00ab..ff5ad6b 100644
--- a/desk/sur/nostr.hoon
+++ b/desk/sur/nostr.hoon
@@ -25,23 +25,81 @@ $: pubkey=@ux :: 32bytes
$: name=@t
about=@t
picture=@t
- other=(map @t @t)
+ other=(map @t json)
+==
++$ relay-stats
+$: connected=(unit @da)
+ reqs=(map sub-id event-stats)
+==
++$ event-stats
+ [filters=(list filter) received=event-count]
++$ sub-id @t
++$ event-count @ud
+
++$ relay-req
+$: sub-id=@t
+ filters=(list filter)
==
:: Relay comms
+$ filter
-$: ids=(list @ux)
- authors=(list @ux)
- kinds=(list @ud)
- tag=(unit [key=@ values=(list @t)])
- since=(unit @ud)
- until=(unit @ud)
- limit=(unit @ud)
+$: ids=(unit (set @ux))
+ authors=(unit (set @ux))
+ kinds=(unit (set @ud))
+ tags=(unit (map @t (set @t)))
+ since=(unit @da)
+ until=(unit @da)
+ limit=(unit @ud)
+==
+:: messages from relay
+++ relay-msg
+$% [%event sub-id=@t =event]
+ [%ok id=@ux accepted=? msg=@t]
+ [%eose sub-id=@t]
+ [%closed sub-id=@t msg=@t]
+ [%notice msg=@t]
+ [%auth challenge=@t]
+ :: from our shim
+ [%error msg=@t]
==
++ shim
|%
++ url 'http://localhost:8888/shim'
- +$ get (list [relay=@t filters=(list filter)])
- +$ post [=event relays=(list @t)]
- +$ req $%([%get get] [%post post])
+ +$ req
+ $% [%req relay-req]
+ [%event =event]
+ [%auth =event]
+ [%close sub-id=@t]
+ ==
+ +$ bulk-req [relays=(list @t) =req]
+ +$ http-req [relay=@t delay=@ud sub-id=@t filters=(list filter)]
+ +$ res $%([%http p=(list relay-msg)] [%ws relay=@t msg=relay-msg])
--
+
+:: https://github.com/sesseor/nostr-relays-list/blob/main/relays.txt
+++ public-relays ^- (list @t)
+ :~ 'wss://nos.lol'
+ :: 'wss://relay.damus.io'
+ :: 'wss://nostr.wine'
+ :: 'wss://offchain.pub'
+ ==
+ :: 'wss://knostr.neutrine.com'
--
+:: event: {
+:: content: "😂",
+:: created_at: 1758049319,
+:: id: "36c8a0bb6a9a1ff3ca3e6868fdf2c055a09aea39b1c078b75c38f5a7b580da87",
+:: kind: 7,
+:: pubkey: "26d6a946675e603f8de4bf6f9cef442037b70c7eee170ff06ed7673fc34c98f1",
+:: sig: "7b5a9c799776935f959eccfd311af6152db6a1360296c9790b35544d0b83a8d75f8937ad1ad6f5da3e0d3e2bdb1bfb92686adbde42c3ef53ca06771080d08153",
+:: tags: [
+:: [ "e", "091d00811bb9a57088ab7c1d39697b0ed9bbbe05dae135b406f3560290fba311",
+:: "wss://relay.nostr.band/", "root", "26d6a946675e603f8de4bf6f9cef442037b70c7eee170ff06ed7673fc34c98f1"
+:: ], [ "e", "1cd926b58a1bac70adcedf38212d72ee1380e17dad1aef6bbc18782c5c540236",
+:: "wss://relay.nostr.band/", "reply", "3252715543f6e43be086465129b030d47d76cf8cead4798e48864563c3375083"
+:: ], [ "p", "26d6a946675e603f8de4bf6f9cef442037b70c7eee170ff06ed7673fc34c98f1",
+:: "wss://nostr.bitcoiner.social/"
+:: ], [ "p", "3252715543f6e43be086465129b030d47d76cf8cead4798e48864563c3375083",
+:: "ws://relay.snort.social/"
+:: ], [ "e", "b9a0c3b28a291d80bcb41ee730f2c48366fd2fefba0e68f9fb928bb9ca96f757" ], [ "p", "3252715543f6e43be086465129b030d47d76cf8cead4798e48864563c3375083" ]
+:: ],
+:: },
diff --git a/desk/sur/nostril.hoon b/desk/sur/nostrill.hoon
index a1cc5ee..ad82661 100644
--- a/desk/sur/nostril.hoon
+++ b/desk/sur/nostrill.hoon
@@ -4,22 +4,24 @@
+$ state-0
$: %0
:: nostr config
- relays=(map @t (list event:nostr))
- keys=(map @ux @ux) :: pubkey to privkey
+ relays=(map @t relay-stats:nostr)
+ keys=(lest keys:nostr) :: cycled, i.keys is current one
:: own feed
feed=feed:trill
+ :: nostr feed from relays
+ =nostr-feed
+ :: profiles
profiles=(map @ux user-meta:nostr)
following=(map @ux =feed:trill)
follow-graph=(map @ux (set follow))
+ :: for http requests
+ pending=(map @t [pending=filter:nostr done=filter:nostr])
:: TODO global feed somehow?
==
++$ nostr-feed ((mop @ud event:nostr) gth)
+++ norm ((on @ud event:nostr) gth)
+$ follow [pubkey=@ux name=@t relay=(unit @t)]
-++ default ^- state-0
- =/ s *state-0
- =/ l ~[['wss://relay.damus.io' ~] ['wss://nos.lol' ~]]
- s(relays (malt l))
-
++ ui
|%
+$ poke
@@ -27,7 +29,7 @@
[%post post-poke]
:: [%reac reac-poke]
[%prof prof-poke]
- [%keys keys-poke]
+ [%keys ~] :: cycle-keys
[%rela relay-poke]
==
+$ post-poke
@@ -43,10 +45,6 @@
$% [%add pubkey=@ux meta=user-meta:nostr]
[%del pubkey=@ux]
==
- +$ keys-poke
- $% [%add ~]
- [%del pubkey=@ux]
- ==
+$ relay-poke
$% [%send host=@p id=@ relays=(list @t)]
==
diff --git a/desk/ted/fetch.hoon b/desk/ted/fetch.hoon
index 6444ca7..e876511 100644
--- a/desk/ted/fetch.hoon
+++ b/desk/ted/fetch.hoon
@@ -6,7 +6,6 @@
^- thread:spider
|= arg=vase
=/ request ;;(request:http q.arg)
- ~& req=request
=/ m (strand ,vase) ^- form:m
:: =/ m (strand ,json) ^- form:m
;< ~ bind:m (send-request:strandio request)
@@ -19,6 +18,4 @@
::
?~ full-file.res (strand-fail:strand %no-body ~)
=/ body=@t q.data.u.full-file.res
- :: ~& resbody=body
- =/ json [%s body]
- (pure:m !>(json))
+ (pure:m !>(body))
diff --git a/desk/web/assets/favicon.ico b/desk/web/assets/favicon.ico
index 0369d8a..110004a 100644
--- a/desk/web/assets/favicon.ico
+++ b/desk/web/assets/favicon.ico
Binary files differ
diff --git a/desk/web/components/navbar.hoon b/desk/web/components/navbar.hoon
index 46b93d4..0c87f80 100644
--- a/desk/web/components/navbar.hoon
+++ b/desk/web/components/navbar.hoon
@@ -1,4 +1,4 @@
-/- sur=nostril
+/- sur=nostrill
/= sig /web/components/sigil/sigil
::
|_ [=state:sur =bowl:gall]
diff --git a/desk/web/pages/index.hoon b/desk/web/pages/index.hoon
index f385df7..99e49d0 100644
--- a/desk/web/pages/index.hoon
+++ b/desk/web/pages/index.hoon
@@ -1,4 +1,4 @@
-/- sur=nostril
+/- sur=nostrill
/= comps /web/components/components
|_ [=state-0:sur =bowl:gall]
++ $
diff --git a/desk/web/router.hoon b/desk/web/router.hoon
index 0782b7d..3cd5b5e 100644
--- a/desk/web/router.hoon
+++ b/desk/web/router.hoon
@@ -1,5 +1,5 @@
-/- sur=nostril
-/+ lib=nostril, sr=sortug
+/- sur=nostrill
+/+ lib=nostrill, sr=sortug
/+ server
:: pages and components
/= layout /web/layout