Init commit

This commit is contained in:
bonbud-macryg 2024-01-30 13:22:04 +00:00
commit 2669a16b10
221 changed files with 19780 additions and 0 deletions

756
app/bedrock.hoon Normal file
View File

@ -0,0 +1,756 @@
:: app/bedrock.hoon
:: - all data is scoped by /path, with a corresponding peers list
:: - ship-to-frontend syncing of data uses chat-db model of /db
:: subscribe wire and /x/db/start-ms/[unix ms].json
:: - %db provides a data layer only. business logic and permissioning
:: must be checked by the %app that uses it (unless it can be fit
:: within the database permissions and constraints system)
:: - custom data types work by %apps specifying the schema for the type
::
:: TO USE:
:: - create a path with a list of peers with %create-path
:: ex: :db &db-action [%create-path /example %host ~ ~ ~ ~[[~zod %host] [~bus %member]]]
:: - create a data-row of a custom or pre-defined type
:: you are required to provide a schema when you first create a row of a new custom-type
:: but if the schema is already there for that type,
:: you can just pass ~ in that spot
/- *db, sstore=spaces-store, vstore=visas
/+ dbug, db
=| state-2
=* state -
=<
%- agent:dbug
|_ =bowl:gall
+* this .
core ~(. +> [bowl ~])
::
++ on-init
^- (quip card _this)
=/ default-state=state-2 *state-2
:: make sure the relay table exists on-init
=. tables.default-state
(~(gas by *^tables) ~[[relay-type:common *pathed-table] [vote-type:common *pathed-table] [react-type:common *pathed-table]])
=/ default-cards
:~ [%pass /spaces %agent [our.bowl %spaces] %watch /updates]
[%pass /selfpoke %agent [our.bowl dap.bowl] %poke %db-action !>([%create-initial-spaces-paths ~])]
[%pass /timer %arvo %b %wait next-refresh-time:core]
[%pass /keep-alive-timer %arvo %b %wait next-keep-alive-time:core]
==
[default-cards this(state default-state)]
++ on-save !>(state)
++ on-load
|= old-state=vase
^- (quip card _this)
=/ uold=(unit versioned-state)
(mole |.(!<(versioned-state old-state)))
=/ old=versioned-state
?~ uold
:: types failed to nest, so fallback to empty tables,
:: same paths and peers
=/ old-paths-and-peers !<(minimal-state old-state)
?- -.old-paths-and-peers
%0
=/ default-state=state-0 *state-0
=. paths.default-state paths.old-paths-and-peers
=. peers.default-state peers.old-paths-and-peers
=. tables.default-state
(~(gas by *tables-0) ~[[%relay *pathed-table-0] [%vote *pathed-table-0] [%react *pathed-table-0]])
default-state
%1
=/ default-state=state-1 *state-1
=. paths.default-state paths.old-paths-and-peers
=. peers.default-state peers.old-paths-and-peers
=. tables-1.default-state
(~(gas by *tables-1) ~[[relay-type:common *pathed-table-1] [vote-type:common *pathed-table-1] [react-type:common *pathed-table-1]])
default-state
%2
=/ default-state=state-2 *state-2
=. paths.default-state paths.old-paths-and-peers
=. peers.default-state peers.old-paths-and-peers
=. tables.default-state
(~(gas by *^tables) ~[[relay-type:common *pathed-table] [vote-type:common *pathed-table] [react-type:common *pathed-table]])
default-state
==
:: types DO nest, so just read it out
!<(versioned-state old-state)
:: do a quick check to make sure we are subbed to /updates in %spaces
=/ cards
:- [%pass /timer %arvo %b %rest next-refresh-time:core]
:- [%pass /timer %arvo %b %wait next-refresh-time:core]
:- [%pass /keep-alive-timer %arvo %b %rest next-keep-alive-time:core]
:: keep-alive every time we on-load. it'll go back to normal
:: cadence on its own
:- [%pass /keep-alive-timer %arvo %b %wait s1-from-now:core]
:- [%pass /selfpoke %agent [our.bowl dap.bowl] %poke %db-action !>([%create-initial-spaces-paths ~])]
?: (~(has by wex.bowl) [/spaces our.bowl %spaces])
~
[%pass /spaces %agent [our.bowl %spaces] %watch /updates]~
?- -.old
%0
=/ new-state=state-1 [
%1
(transform-tables-0-to-tables:db tables.old schemas.old)
(transform-schemas-0-to-schemas:db schemas.old)
(transform-paths-0-to-paths:db paths.old)
peers.old
(transform-del-log-0-to-del-log:db del-log.old schemas.old)
hide-logs.old
]
(on-load !>(new-state))
%1
=/ new-state=state-2 [
%2
(transform-tables-1-to-tables:db tables-1.old)
schemas.old
paths.old
peers.old
del-log.old
hide-logs.old
]
[cards this(state new-state)]
%2
[cards this(state old)]
==
::
++ on-poke
|= [=mark =vase]
^- (quip card _this)
?> ?=(%db-action mark)
=/ act !<(action vase)
=^ cards state
?- -.act :: each handler function here should return [(list card) state]
%create-path
(create-path:db +.act state bowl)
%create-from-space
(create-from-space:db +.act state bowl)
%edit-path
(edit-path:db +.act state bowl)
%remove-path
(remove-path:db +.act state bowl)
%add-peer
(add-peer:db +.act state bowl)
%kick-peer
(kick-peer:db +.act state bowl)
%keep-alive
(keep-alive:db +.act state bowl)
%get-path
(get-path:db +.act state bowl)
%delete-path
(delete-path:db +.act state bowl)
%put-path
(put-path:db +.act state bowl)
%refresh-path
(refresh-path:db +.act state bowl)
%create
(create:db +.act state bowl)
%create-many
=| cards=(list card)
|-
?~ args.act
[cards state]
=^ cadz state
(create:db i.args.act state bowl)
$(args.act t.args.act, cards (weld cadz cards))
%edit
(edit:db +.act state bowl)
%remove
(remove:db +.act state bowl)
%remove-many
(remove-many:db +.act state bowl)
%remove-before
(remove-before:db +.act state bowl)
%relay
(relay:db +.act state bowl)
%handle-changes
(handle-changes:db +.act state bowl)
%create-initial-spaces-paths
(create-initial-spaces-paths:db state bowl)
%refresh-chat-paths
(refresh-chat-paths:db state bowl)
%toggle-hide-logs
(toggle-hide-logs:db +.act state bowl)
==
[cards this]
::
:: endpoints for clients to keep in sync with our ship
:: /db
:: /path/[path]
:: endpoints for other ships to keep in sync with us
:: /next/@da/[path]
++ on-watch
|= =path
^- (quip card _this)
=/ cards=(list card)
:: each path should map to a list of cards
?+ path !!
::
[%db ~] :: the "everything" path
?> =(our.bowl src.bowl)
~ :: we are not "priming" this subscription with anything, since the client can just scry if they need. the sub is for receiving new updates
::
[%db %common ~] :: the "common-types only" path
?> =(our.bowl src.bowl)
~ :: we are not "priming" this subscription with anything, since the client can just scry if they need. the sub is for receiving new updates
:: /path/the/actual/path/
[%path *] :: the "path" path, subscribe by path explicitly
?> =(our.bowl src.bowl)
=/ thepathrow (~(got by paths.state) t.path)
=/ peerslist (~(got by peers.state) t.path)
=/ thechange
:: TODO also dump all the rows here
db-changes+!>([[%add-path thepathrow] (turn peerslist |=(p=peer [%add-peer p]))])
:~ [%give %fact ~ thechange]
==
:: /next/@da/the/actual/path/
[%next @ *] :: the "next" path, for other ships to get the next update on a particular path
?< =(our.bowl src.bowl) :: this path should only be used by NOT us
=/ t=@da (slav %da i.t.path)
=/ thepathrow (~(got by paths.state) t.t.path)
:: if the @da they passed was behind, %give them the current version, and %kick them
?: (gth updated-at.thepathrow t)
:: ~& >>> "{<src.bowl>} tried to sub on old @da {<t>}, %kicking them from {<t.t.path>}"
=/ thepeers (~(got by peers.state) t.t.path)
=/ tbls (tables-by-path:db tables.state t.t.path)
=/ dels=(list [@da db-del-change])
(dels-by-path:db t.t.path state)
:~ [%give %fact ~ db-path+!>([thepathrow thepeers tbls schemas.state dels])]
[%give %kick [path ~] `src.bowl]
==
:: else, don't give them anything. we will give+kick when a new version happens
::=/ thepathrow (~(get by paths-table.state) t.t.path)
:::~ [%give %fact ~ chat-path-row+!>(thepathrow)]
::==
::~& > "{(scow %p src.bowl)} subbed to {(spud path)}"
~
:: /vent/~zod/~2000.1.1
[%vent @ @ ~] :: poke response comes on this path
=/ src=ship (slav %p i.t.path)
?> =(src src.bowl)
~
==
[cards this]
::
:: endpoints for clients syncing with their own ship
:: /x/db.json
:: /x/db/path/[path].json
:: /x/db/start-ms/[unix ms].json
++ on-peek
|= =path
^- (unit (unit cage))
?+ path !!
::
[%x %db ~]
``db-state+!>(state)
::
:: full information about a given path
[%x %db %path *]
=/ thepath t.t.t.path
=/ thepathrow (~(got by paths.state) thepath)
=/ thepeers (~(got by peers.state) thepath)
=/ tbls (tables-by-path:db tables.state thepath)
=/ dels=(list [@da db-del-change])
(dels-by-path:db thepath state)
``db-path+!>([thepathrow thepeers tbls schemas.state dels])
::
:: all rows from a given table
:: /db/table/realm-note/0v6.539qr.dv1ns.thh70.fnqol.fb2us.json
[%x %db %table *]
=/ tblname=^path t.t.t.path
=/ typ=type:common (path-to-type:core tblname)
``db-table+!>([typ (~(got by tables.state) typ) schemas.state])
::
:: all rows from a given table and path (as a pathed-table in noun form)
:: /db/table-by-path/chat/<hash>/<path>.json
[%x %db %table-by-path @ @ *]
=/ tblname=@tas i.t.t.t.path
=/ typ=type:common [tblname (slav %uv i.t.t.t.t.path)]
=/ dbpath t.t.t.t.t.path
=/ tbl (get-tbl:db typ dbpath state)
?~ tbl
``db-table+!>([typ *pathed-table schemas.state])
``db-table+!>([typ (~(put by *pathed-table) dbpath u.tbl) schemas.state])
::
:: a specific row from a given table, by id
:: /row/message/0v12jdlk.asdf.12e.s/~zod/~2000.1.1.json
[%x %row @ @ @ @ ~]
=/ tblname=@tas i.t.t.path
=/ typ=type:common [tblname (slav %uv i.t.t.t.path)]
=/ ship=@p `@p`(slav %p i.t.t.t.t.path)
=/ t=@da `@da`(slav %da i.t.t.t.t.t.path)
=/ therow=row (~(got by (ptbl-to-tbl:db (~(got by tables.state) typ))) [ship t])
``db-row+!>([therow schemas.state])
::
:: test existence of specific row from a given table, by id
:: /loobean/row/message/~zod/~2000.1.1/<path>.json
[%x %loobean %row @ @ @ @ *]
=/ tblname=@tas i.t.t.t.path
=/ typ=type:common [tblname (slav %uv i.t.t.t.t.path)]
=/ ship=@p `@p`(slav %p i.t.t.t.t.t.path)
=/ t=@da `@da`(slav %da i.t.t.t.t.t.t.path)
=/ dbpath t.t.t.t.t.t.t.path
=/ therow=(unit row) (get-db:db typ dbpath [ship t] state)
?~ therow
``ud+!>(1) :: false
``ud+!>(0) :: true, because the pathrow exsits
::
:: host of a given path
[%x %host %path *]
=/ thepath t.t.t.path
=/ thepathrow (~(got by paths.state) thepath)
``ship+!>(host.thepathrow)
::
:: test existence of given path
[%x %loobean %path *]
=/ thepath t.t.t.path
=/ thepathrow (~(get by paths.state) thepath)
?~ thepathrow
``ud+!>(1) :: false
``ud+!>(0) :: true, because the pathrow exsits
:: test existence of given type
::
[%x %loobean %table @ @ ~]
=/ tblname=@tas i.t.t.t.path
=/ typ=type:common [tblname (slav %uv i.t.t.t.t.path)]
=/ thetbl (~(get by tables.state) typ)
?~ thetbl
``ud+!>(1) :: false
``ud+!>(0) :: true, because the pathrow exsits
::
:: test existence of given type
[%x %loobean %table @ @ ~]
=/ tblname=@tas i.t.t.t.path
=/ typ=type:common [tblname (slav %uv i.t.t.t.t.path)]
=/ thetbl (~(get by tables.state) typ)
?~ thetbl
``ud+!>(1) :: false
``ud+!>(0) :: true, because the pathrow exsits
::
:: /x/db/start-ms/[unix ms].json
:: all tables, but only with received-at after <time>
[%x %db %start-ms @ ~]
=/ timestamp=@da (di:dejs:format n+i.t.t.t.path)
``db-state+!>((after-time:db state timestamp))
==
::
++ on-agent
|= [=wire =sign:agent:gall]
^- (quip card _this)
?+ wire ~&(wire ~&(sign !!))
[%remote-scry %callback ~]
::~& > "remote-scry/callback on-agent {<-.sign>}"
::~& +.sign
`this
[%dbpoke ~]
?+ -.sign `this
%poke-ack
?~ p.sign `this
::~& >>> "%db: {<(spat wire)>} dbpoke failed"
::~& >>> p.sign
`this
==
[%kept-alive *]
?+ -.sign `this
%poke-ack
:: update received-at on the path row so we don't hammer
:: dead hosts
=/ dbpath=path t.wire
=/ pr=path-row (~(got by paths.state) dbpath)
=. received-at.pr now.bowl
=. paths.state (~(put by paths.state) dbpath pr)
?~ p.sign
`this(state state)
~& >>> "%db: {<(spat wire)>} kept-alive failed"
~& >>> p.sign
`this
==
[%selfpoke ~]
?+ -.sign `this
%poke-ack
?~ p.sign `this
::~& >>> "%db: {<(spat wire)>} selfpoke failed"
`this
==
[%spaces ~]
?+ -.sign !!
%watch-ack
?~ p.sign %- (slog leaf+"{<dap.bowl>}: subscribed to spaces" ~) `this
::~& >>> "{<dap.bowl>}: spaces subscription failed"
`this
%kick
::~& > "{<dap.bowl>}: spaces kicked us, resubscribing..."
:_ this
:~ [%pass /spaces %agent [our.bowl %spaces] %watch /updates]
==
%fact
?+ p.cage.sign !!
%spaces-reaction
=^ cards state
(spaces-reaction:db !<(=reaction:sstore q.cage.sign) state bowl)
[cards this]
::
%visa-reaction
=^ cards state
(visas-reaction:db !<(=reaction:vstore q.cage.sign) state bowl)
[cards this]
==
==
[%next @ *]
?- -.sign
%poke-ack
?~ p.sign `this
::~& >>> "%db: {<(spat wire)>} /next/[path] failed"
::~& >>> p.sign
`this
%watch-ack
?~ p.sign `this
::~& >>> "{<dap.bowl>}: /next/[path] subscription failed"
`this
%kick
`this
::=/ pathrow (~(get by paths.state) +.+.wire)
::?: =(~ pathrow)
::~& >>> "got a %kick on {(spud +.+.wire)} that we are ignoring because that path is not in our state"
:: `this
::=/ newpath (weld /next/(scot %da updated-at:(need pathrow)) path:(need pathrow))
::~& >>> "{<dap.bowl>}: /next/[path] kicked us, resubbing {(spud newpath)}"
:::_ this
:::~
:: [%pass newpath %agent [src.bowl dap.bowl] %watch newpath]
::==
%fact
:: handle the update by updating our local state and
:: pushing db-changes out to our subscribers
=^ cards state
^- (quip card state-2)
=/ dbpath=path +.+.wire
=/ factmark -.+.sign
~& >>> "%fact on {(spud wire)}: {<factmark>}"
?+ factmark
:: default case:
~& >>> "UNHANDLED FACT type"
~& >>> +.sign
`state
%db-changes
=/ changes=db-changes !<(db-changes +.+.sign)
=/ result-cards *(list card)
=/ index=@ud 0
|-
?: =(index (lent changes))
:_ state
:: echo the changes out to our client subs
^- (list card)
%+ weld
result-cards
^- (list card)
[%give %fact [/db (weld /path dbpath) ~] db-changes+!>(changes)]~
=/ change (snag index changes)
=/ new-scry=(list card)
?+ -.change ~
%add-row
?. ?=(%relay name.type.row.change) ~
?> ?=(%relay -.data.row.change)
=/ uobj=(unit row) (get-db:db type.data.row.change path.data.row.change id.data.row.change state)
?~ uobj :: if we DONT have the obj already, remote-scry it
::~& >>> "asking for remote-scry"
:~ [
%pass
/remote-scry/callback
%arvo
%a
%keen
ship.id.row.change
/g/x/(scot %ud revision.data.row.change)/(scot %tas dap.bowl)//(scot %p ship.id.data.row.change)/(scot %da t.id.data.row.change)
]
==
~ :: otherwise, don't emit any cards
%upd-row
?. ?=(%relay name.type.row.change) ~
?> ?=(%relay -.data.row.change)
?: deleted.data.row.change ~ :: if the root-obj is deleted, don't remote-scry it
::~& >>> "asking for remote-scry"
:~ [
%pass
/remote-scry/callback
%arvo
%a
%keen
ship.id.row.change
/g/x/(scot %ud revision.data.row.change)/(scot %tas dap.bowl)//(scot %p ship.id.data.row.change)/(scot %da t.id.data.row.change)
]
==
==
=/ pokes=(list card)
?+ -.change ~
%upd-row
?: ?=(%relay name.type.row.change) ~
:: if it's NOT a relay, we might have to poke ourselves to update the relay
=/ our-relays=(list row) (our-matching-relays:db row.change state bowl)
?~ our-relays ~
:-
:: remote-scry-publish the new row version
[%pass /remote-scry/callback %grow /(scot %p ship.id.row.change)/(scot %da t.id.row.change) row-and-schema+[row.change schema.change]]
^- (list card)
%- zing
%+ turn
our-relays
|= rela=row
^- (list card)
?+ -.data.rela ~
%relay
:: increment the revision of all the relays
:: that we host for this changed row
=/ dat data.rela
=. revision.dat +(revision.dat)
[%pass /selfpoke %agent [our.bowl dap.bowl] %poke %db-action !>([%edit id.rela path.rela type.rela dat ~])]~
==
%del-row
?: ?=(%relay name.type.change) ~
:: if it's NOT a relay, we might have to poke ourselves to update the relay
=/ fakerow=row *row
=. id.fakerow id.change
=/ our-relays=(list row) (our-matching-relays:db fakerow state bowl)
?~ our-relays ~
=/ snagged-first=row (snag 0 `(list row)`our-relays)
?> ?=(%relay -.data.snagged-first)
:-
:: remote-scry-cull all the revisions of this
:: deleted object
[%pass /remote-scry/cullback %cull [%ud revision.data.snagged-first] /(scot %p ship.id.change)/(scot %da t.id.change)]
^- (list card)
%- zing
%+ turn
our-relays
|= rela=row
^- (list card)
?+ -.data.rela ~
%relay
:: signal that the relayed object was deleted
=/ dat data.rela
=. deleted.dat %.y
[%pass /selfpoke %agent [our.bowl dap.bowl] %poke %db-action !>([%edit id.rela path.rela type.rela dat ~])]~
==
==
=. state
?: ?& ?=(%upd-row -.change)
?=(%relay name.type.row.change)
?=(%relay -.data.row.change)
=(%.y deleted.data.row.change)
==
::~& >>> "{<our.bowl>} is del-db ing {<type.data.row.change>} {<ship.id.data.row.change>} {<t.id.data.row.change>}"
(del-db:db type.data.row.change path.data.row.change id.data.row.change state (add now.bowl index))
state
$(index +(index), state (process-db-change:db dbpath change state bowl), result-cards (weld (weld result-cards new-scry) pokes))
%db-path
:: TODO logging ~& to indicate that we are recieving a
:: fullpath instead of just a single change
:: |ames-cong 5 100.000
=/ full=fullpath !<(fullpath +.+.sign)
~& >>> "getting fullpath for {<path.path-row.full>}"
:: insert pathrow
=. received-at.path-row.full now.bowl
=. paths.state (~(put by paths.state) dbpath path-row.full)
:: insert peers
=. peers.full
%+ turn
peers.full
|= p=peer
=. received-at.p now.bowl
p
=. peers.state (~(put by peers.state) dbpath peers.full)
:: update schemas
=. schemas.state (~(gas by schemas.state) ~(tap by schemas.full))
:: update del-log
=. del-log.state (~(gas by del-log.state) dels.full)
:: update tables
=/ keys=(list type:common) ~(tap in ~(key by tables.full))
=/ index=@ud 0
|-
?: =(index (lent keys))
:_ state
:: echo the changes out to our client subs
[%give %fact [/db (weld /path dbpath) ~] db-path+!>(full)]~
=/ key (snag index keys)
=/ maybe-pt (~(get by tables.state) key)
=. tables.state
?~ maybe-pt
(~(put by tables.state) key (malt [dbpath (~(got by tables.full) key)]~))
=/ pt (~(put by (need maybe-pt)) dbpath (~(got by tables.full) key))
(~(put by tables.state) key pt)
$(index +(index))
==
[cards this]
==
==
::
++ on-leave
|= =path
^- (quip card _this)
::~& "Unsubscribe by: {<src.bowl>} on: {<path>}"
`this
::
++ on-arvo
|= [=wire =sign-arvo]
^- (quip card _this)
?+ wire !!
[%remote-scry %callback ~]
::~& > "remote-scry/callback on-arvo"
?+ -.sign-arvo `this
%ames
?+ -.+.sign-arvo `this
%tune
=/ r=(unit roar:ames) roar.+.sign-arvo
?~ r `this
=/ ro=roar:ames (need r)
?~ data=q.dat.ro `this
=/ rs=row-and-schema ;;(row-and-schema q.u.data)
=/ uobj=(unit row) (get-db:db type.row.rs path.row.rs id.row.rs state)
=/ cards=(list card)
?~ uobj :: if we DONT have the obj already, we're `add-row`ing it
[%give %fact [/db (weld /path path.row.rs) ~] db-changes+!>([%add-row row.rs schema.rs]~)]~
:: otherwise we are just `upd-row`ing it
[%give %fact [/db (weld /path path.row.rs) ~] db-changes+!>([%upd-row row.rs schema.rs]~)]~
:- cards
this(state (add-row-to-db:db row.rs schema.rs state))
==
==
[%remote-scry %cullback ~]
::~& > "remote-scry cullback we culled something"
::~& > -.sign-arvo
`this
[%timer ~]
=/ paths-we-host (skim ~(val by paths.state) |=(p=path-row =(our.bowl host.p)))
=/ refresh-pokes=(list card)
%- zing
%+ turn
paths-we-host
|= p=path-row
^- (list card)
=/ peers=(list peer) (~(got by peers.state) path.p)
%+ turn
(skip peers |=(per=peer =(ship.per our.bowl))) :: don't bother poking ourselves
|= =peer
^- card
[%pass /dbpoke %agent [ship.peer dap.bowl] %poke %db-action !>([%refresh-path updated-at.p path.p])]
[
:: we remove the old timer (if any) and add the new one, so that
:: we don't get an increasing number of timers associated with
:: this agent every time the agent gets updated
:- [%pass /timer %arvo %b %rest next-refresh-time:core]
:- [%pass /timer %arvo %b %wait next-refresh-time:core]
refresh-pokes
this
]
[%keep-alive-timer ~]
:: gets all the paths we don't host AND whose host is 'alive'
=/ paths-we-dont-host
%+ skim
~(val by paths.state)
|= p=path-row
?& ?!(=(our.bowl host.p))
:: host acked a keep-alive poke, or sent an update within
:: 1.5 timer windows, proving it's still alive and we should
:: send %keep-alive to them
(gth received-at.p (sub now.bowl ~h3))
==
=/ pokes=(list card)
%+ turn
paths-we-dont-host
|= p=path-row
^- card
[%pass (weld /kept-alive path.p) %agent [host.p dap.bowl] %poke %db-action !>([%keep-alive path.p])]
[
:: we remove the old timer (if any) and add the new one, so that
:: we don't get an increasing number of timers associated with
:: this agent every time the agent gets updated
:- [%pass /keep-alive-timer %arvo %b %rest next-keep-alive-time:core]
:- [%pass /keep-alive-timer %arvo %b %wait next-keep-alive-time:core]
pokes
this
]
[%nft-verify @ @ *]
=/ =path `path`t.t.t.wire
=/ =ship `@p`(slav %p i.t.wire)
=/ =role `@tas`(slav %tas i.t.t.wire)
?> ?=(%iris -.sign-arvo)
=/ i +.sign-arvo
?> ?=(%http-response -.i)
?> ?=(%finished -.+.i)
=/ payload full-file.client-response.i
?~ payload `this
=/ contracts=(list @t)
(parse-alchemy-json (need (de:json:html q.data.u.payload)))
=/ path-row=path-row (~(got by paths.state) path)
=/ chatrow=row (snag 0 ~(val by (need (get-tbl:db chat-type:common path state))))
?> ?=(%chat -.data.chatrow)
?> |-
?: =((lent contracts) 0)
%.n
?: =(contract:(need nft.data.chatrow) (snag 0 contracts))
~& > "found matching contract {<nft.data.chatrow>} {<(snag 0 contracts)>}"
%.y
$(contracts +.contracts)
=/ newpeer=peer [path ship role now.bowl now.bowl now.bowl]
:: local state updates
:: update paths table
=. updated-at.path-row now.bowl
=. received-at.path-row now.bowl
=. paths.state (~(put by paths.state) path path-row)
:: update peers table
=/ original-peers=(list peer) (~(got by peers.state) path)
=/ newlist=(list peer) [newpeer (skip original-peers |=(p=peer =(ship.p ship)))]
=. peers.state (~(put by peers.state) path newlist)
=/ thechange=db-changes [%add-peer newpeer]~
:: emit the change to subscribers
=/ cards=(list card)
:: poke `ship` with %get path
:- (get-path-card:db ship path-row (peers-to-ship-roles:db (~(got by peers.state) path)))
:: tell clients about the new peer
:- [%give %fact [/db (weld /path path) ~] db-changes+!>(thechange)]
:: tell subs about the new peer
%+ turn
(living-peers:db original-peers now.bowl our.bowl)
|= p=peer
^- card
(handle-changes-card:db ship.p thechange path)
[cards this]
==
::
++ on-fail
|= [=term =tang]
%- (slog leaf+"error in {<dap.bowl>}" >term< tang)
`this
--
|_ [=bowl:gall cards=(list card)]
::
++ this .
++ core .
++ next-refresh-time `@da`(add (mul (div now.bowl ~h24) ~h24) ~h24) :: TODO decide on actual timer interval
++ next-keep-alive-time `@da`(add (mul (div now.bowl ~h2) ~h2) ~h2) :: TODO decide on actual timer interval
++ s1-from-now `@da`(add (mul (div now.bowl ~s1) ~s1) ~s1)
++ path-to-type
|= p=path
^- type:common
[`@tas`(slav %tas +2:p) `@uvH`(slav %uv +6:p)]
++ parse-alchemy-json
|= jon=json
^- (list @t)
?> ?=([%o *] jon)
=/ contracts=json (~(got by p.jon) 'contracts')
?> ?=([%a *] contracts)
%+ turn p.contracts
|= jn=json
^- @t
?> ?=([%o *] jn)
=/ address=json (~(got by p.jn) 'address')
(so:dejs:format address)
--

1
desk.bill Normal file
View File

@ -0,0 +1 @@
~[%bedrock]

11
desk.docket-0 Normal file
View File

@ -0,0 +1,11 @@
:~
title+'Realm'
info+'A desktop environment for DAOs and communities.'
color+0xfe.9c4f
version+[0 9 24]
website+'https://holium.com'
license+'MIT'
base+'realm'
image+'https://holium-app-globs.nyc3.cdn.digitaloceanspaces.com/realm%2Frealm.svg'
glob-http+['https://holium-app-globs.nyc3.cdn.digitaloceanspaces.com/realm%2Fholium-com-redirect.glob' 0v4.39m1m.t5rlt.d94cv.akdr1.389ub]
==

1
desk.ship Normal file
View File

@ -0,0 +1 @@
~hostyv

545
lib/bazaar.hoon Normal file
View File

@ -0,0 +1,545 @@
/- store=bazaar-store, spaces-store, docket=bazaar-docket, treaty=bazaar-treaty
/+ docket-lib=docket, realm=realm
=< [store .]
=, store
|%
::
++ dejs
=, dejs:format
|%
++ action
|= jon=json
^- ^action
=< (decode jon)
|%
++ decode
%- of
:~
[%pin add-pin]
[%unpin rem-pin]
[%reorder-pins reorder-pins]
[%recommend add-rec]
[%unrecommend rem-rec]
[%suite-add suite-add]
[%suite-remove suite-remove]
[%install-app install-app]
[%uninstall-app uninstall-app]
[%reorder-app reorder-app]
[%initialize ul]
[%rebuild-catalog ul]
[%rebuild-stall rebuild-stall]
[%clear-stall clear-stall]
[%set-host set-host]
[%delete-catalog-entry del-cat-entry]
[%add-catalog-entry add-cat-entry]
==
::
++ install-app
%- ot
:~ [%ship (su ;~(pfix sig fed:ag))]
[%desk so]
==
::
++ uninstall-app
%- ot
:~ [%desk so]
==
::
++ reorder-app
%- ot
:~ [%desk so]
[%index ni]
==
::
++ add-pin
%- ot
:~ [%path pth]
[%app-id so]
[%index (mu ni)]
==
::
++ rem-pin
%- ot
:~ [%path pth]
[%app-id so]
==
::
++ reorder-pins
%- ot
:~ [%path pth]
[%dock (ar so)]
==
::
++ add-rec
%- ot
:~ [%app-id so]
==
::
++ rem-rec
%- ot
:~ [%app-id so]
==
::
++ suite-add
%- ot
:~ [%path pth]
[%app-id so]
[%index ni]
==
::
++ suite-remove
%- ot
:~ [%path pth]
[%index ni]
==
::
++ pth
%- ot
:~ [%ship (su ;~(pfix sig fed:ag))]
[%space so]
==
::
++ rebuild-stall
%- ot
:~ [%path pth]
[%args ul]
==
::
++ clear-stall
%- ot
:~ [%path pth]
[%args ul]
==
::
++ set-host
%- ot
:~ [%app-id so]
[%host (su ;~(pfix sig fed:ag))]
==
::
++ del-cat-entry
%- ot
:~ [%app-id so]
==
::
++ add-cat-entry
%- ot
:~ [%app-id so]
[%native-app native-app]
==
:: %- of
:: :~ [%native native-app]
:: [%web ~] :: currently not supported
:: [%urbit ~] :: currently not supported
:: ==
::
++ native-app
%- ot
:~ [%title so]
[%info so]
[%color so]
[%icon so]
[%config cfg]
==
::
++ cfg
%- ot
:~ [%size (at ~[ni ni])]
[%titlebar-border bo]
[%show-titlebar bo]
==
--
--
::
:: json
::
++ enjs
=, enjs:format
|%
++ reaction
|= rct=^reaction
^- json
%- pairs
:_ ~
^- [cord json]
:- -.rct
?- -.rct
::
%initial
%- pairs
:~ [%catalog (catalog-js:encode catalog.rct)]
[%stalls (stalls-js:encode stalls.rct)]
[%docks (docks-js:encode docks.rct)]
[%recommendations a+(turn ~(tap in recommendations.rct) |=(=app-id:store s+app-id))]
[%grid (grid-index-js:encode grid-index.rct)]
==
::
%app-install-update
(urbit-app-update:encode app-id.rct urbit-app.rct grid-index.rct)
::
%dock-update
%- pairs
:~ [%path s+(spat /(scot %p ship.path.rct)/(scot %tas space.path.rct))]
[%dock a+(turn dock.rct |=(=app-id:store s+app-id))]
==
::
%recommended
%- pairs
:~ [%id s+app-id.rct]
[%stalls (stalls-js:encode stalls.rct)]
==
::
%unrecommended
%- pairs
:~ [%id s+app-id.rct]
[%stalls (stalls-js:encode stalls.rct)]
==
::
%suite-added
%- pairs
:~ [%path s+(spat /(scot %p ship.path.rct)/(scot %tas space.path.rct))]
[%id s+app-id.rct]
[%app (app-detail:encode app-id.rct app.rct)]
[%index (numb index.rct)]
==
::
%suite-removed
%- pairs
:~ [%path s+(spat /(scot %p ship.path.rct)/(scot %tas space.path.rct))]
[%index (numb index.rct)]
==
::
%joined-bazaar
%- pairs
:~ [%path s+(spat /(scot %p ship.path.rct)/(scot %tas space.path.rct))]
[%catalog (catalog-js:encode catalog.rct)]
[%stall (stall-js:encode stall.rct)]
==
::
%stall-update
=/ data=(list [@tas json])
?~ det.rct [%none ~]~
?~ app.u.det.rct [%remove-app s+app-id.u.det.rct]~
[%add-app (app-detail:encode app-id.u.det.rct (need app.u.det.rct))]~
=/ data
%+ weld data
^- (list [@tas json])
:~ [%path s+(spat /(scot %p ship.path.rct)/(scot %tas space.path.rct))]
[%stall (stall-js:encode stall.rct)]
==
%- pairs
data
::
%treaties-loaded
%- pairs
:~ [%ship s+(scot %p ship.rct)]
==
::
%new-ally
%- pairs
:~ [%ship s+(scot %p ship.rct)]
[%desks (alliance:encode alliance.rct)]
==
::
%ally-deleted
%- pairs
:~ [%ship s+(scot %p ship.rct)]
==
::
:: %treaty-added
:: :- %treaty-added
:: %- pairs
:: :~ [%ship s+(crip "{<ship.rct>}")]
:: [%desk s+desk.rct]
:: [%docket (dkt:encode docket.rct)]
:: ==
%rebuild-catalog
%- pairs
:~ [%catalog (catalog-js:encode catalog.rct)]
[%grid (grid-index-js:encode grid-index.rct)]
==
::
%rebuild-stall
%- pairs
:~ [%path s+(spat /(scot %p ship.path.rct)/(scot %tas space.path.rct))]
[%catalog (catalog-js:encode catalog.rct)]
[%stall (stall-js:encode stall.rct)]
==
::
%clear-stall
%- pairs
:~ [%path s+(spat /(scot %p ship.path.rct)/(scot %tas space.path.rct))]
==
::
%reorder-grid-index
%- pairs
:~ [%grid (grid-index-js:encode grid-index.rct)]
==
::
==
::
++ view :: encodes for on-peek
|= vi=view:store
^- json
%- pairs
:_ ~
^- [cord json]
:- -.vi
?- -.vi
::
%catalog
(catalog-js:encode catalog.vi)
::
%installed
(catalog-js:encode catalog.vi)
::
%allies
(allies-js:encode allies.vi)
::
%treaties
(treaty-map:encode treaties.vi)
::
%app-hash
s+(scot %uv hash.vi)
::
%version
(version:encode version.vi)
::
==
--
::
++ encode
=, enjs:format
|%
::
++ grid-index-js
|= =grid-index:store
^- json
%- pairs
%+ turn ~(tap by grid-index)
|= [idx=@ud desk=@tas]
^- [cord json]
[(cord (scot %ud idx)) s+(scot %tas desk)]
::
++ urbit-app-update
|= [=app-id app=urbit-app:store =grid-index:store]
^- json
%- pairs
:~ ['appId' s+app-id]
['app' (urbit-app:encode app-id app)]
['grid' (grid-index-js:encode grid-index)]
==
::
++ merge
|= [a=json b=json]
^- json
?> &(?=(%o -.a) ?=(%o -.b))
[%o (~(uni by p.a) p.b)]
::
++ stalls-js
|= =stalls:store
^- json
%- pairs
%+ turn ~(tap by stalls)
|= [pth=space-path:spaces-store =stall:store]
=/ spc-path (spat /(scot %p ship.pth)/(scot %tas space.pth))
^- [cord json]
[spc-path (stall-js:encode stall)]
::
++ stall-js
|= =stall:store
^- json
%- pairs
:~ ['suite' (suite-js:encode suite.stall)]
['recommended' (recommended-js:encode recommended.stall)]
==
::
++ docks-js
|= =docks:store
^- json
%- pairs
%+ turn ~(tap by docks)
|= [pth=space-path:spaces-store =dock:store]
=/ spc-path (spat /(scot %p ship.pth)/(scot %tas space.pth))
^- [cord json]
[spc-path a+(turn dock |=(=app-id:store s+app-id))]
::
++ suite-js
|= =suite:store
^- json
%- pairs
%+ turn ~(tap by suite)
|= [index=@ud =app-id:store]
^- [cord json]
[(scot %ud index) s+(cord app-id)]
::
++ recommended-js
|= =recommended:store
^- json
%- pairs
:: TODO sort and only return the last 4
%+ turn ~(tap by recommended)
|= [=app-id:store =member-set:store]
^- [cord json]
[app-id (numb ~(wyt in member-set))]
::
++ catalog-js
|= [=catalog:store]
^- json
%- pairs
%+ turn ~(tap by catalog)
|= [=app-id:store app=app:store]
^- [cord json]
[app-id (app-detail:encode app-id app)]
::
++ app-detail
|= [=app-id:store =app:store]
?- -.app
::
%native
^- json
%- pairs
:~ ['id' s+app-id]
['type' s+%native]
['title' s+title.native-app.app]
['info' s+info.native-app.app]
['color' s+color.native-app.app]
['icon' s+icon.native-app.app]
['config' (config:enjs:realm config.native-app.app)]
==
::
%web
^- json
%- pairs
:~ ['id' s+app-id]
['title' s+title.web-app.app]
['href' s+href.web-app.app]
['favicon' s+favicon.web-app.app]
['config' (config:enjs:realm config.web-app.app)]
==
::
%urbit (urbit-app:encode app-id +.app)
::
==
::
++ urbit-app
|= [=app-id app=urbit-app:store]
%+ merge (dkt docket.app)
%- pairs
:~
['id' s+app-id]
['installStatus' [%s `@t`install-status.app]]
['config' (config:enjs:realm config.app)]
['host' ?~(host.app ~ s+(scot %p u.host.app))]
==
::
++ dkt
|= [=docket:docket]
^- json
%- pairs
:~ type+s+%urbit
title+s+title.docket
info+s+info.docket
color+s+(scot %ux color.docket)
href+(href href.docket)
image+?~(image.docket ~ s+u.image.docket)
version+(version version.docket)
license+s+license.docket
website+s+website.docket
==
::
++ href
|= h=href:docket
%+ frond -.h
?- -.h
%site s+(spat path.h)
%glob
%- pairs
:~ base+s+base.h
glob-reference+(glob-reference glob-reference.h)
==
==
::
++ glob-reference
|= ref=glob-reference:docket
%- pairs
:~ hash+s+(scot %uv hash.ref)
location+(glob-location location.ref)
==
::
++ glob-location
|= loc=glob-location:docket
^- json
%+ frond -.loc
?- -.loc
%http s+url.loc
%ames s+(scot %p ship.loc)
==
::
++ version
|= v=version:docket
^- json
:- %s
%- crip
"{(num major.v)}.{(num minor.v)}.{(num patch.v)}"
::
++ num
|= a=@u
^- ^tape
=/ p=json (numb a)
?> ?=(%n -.p)
(trip p.p)
::
++ allies-js
|= =allies:ally:treaty
^- json
%- pairs
%+ turn ~(tap by allies)
|= [s=^ship a=alliance:treaty]
[(scot %p s) (alliance a)]
::
++ treaty-map
|= t-map=(map [=^ship =desk] =treaty:treaty)
^- json
%- pairs
%+ turn ~(tap by t-map)
|= [[s=^ship =desk] t=treaty:treaty]
[(foreign-desk s desk) (treaty-js t)]
::
++ treaty-js
|= t=treaty:treaty
^- json
%+ merge (dkt docket.t)
%- pairs
:~ ['ship' s+(scot %p ship.t)]
['desk' s+desk.t]
['cass' (case case.t)]
['hash' s+(scot %uv hash.t)]
==
::
++ foreign-desk
|= [s=^ship =desk]
^- cord
(crip "{(scow %p s)}/{(trip desk)}")
::
++ case
|= c=^case
%+ frond -.c
?- -.c
%da s+(scot %da p.c)
%tas s+(scot %tas p.c)
%ud (numb p.c)
%uv s+(scot %uv p.c)
==
::
++ alliance
|= a=alliance:treaty
^- json
:- %a
%+ turn ~(tap in a)
|= [=^ship =desk]
^- json
s+(foreign-desk ship desk)
::
--
--

265
lib/bedrock-scries.hoon Normal file
View File

@ -0,0 +1,265 @@
/- bedrock=db, common
|%
++ our-passport
|= =bowl:gall
^- passport:common
=/ r=row:bedrock (our-passport-row bowl)
?+ -.data.r !!
%passport +.data.r
==
::
++ our-passport-row
|= =bowl:gall
^- row:bedrock
%+ snag 0
%+ skim
(all-rows-by-path-type passport-type:common /private bowl)
|= r=row:bedrock ^- ?
?+ -.data.r %.n
%passport =(ship.contact.data.r our.bowl)
==
::
++ our-passport-id
|= =bowl:gall
^- id:common
=/ r=row:bedrock
%+ snag 0
%+ skim
(all-rows-by-path-type passport-type:common /private bowl)
|= r=row:bedrock ^- ?
?+ -.data.r %.n
%passport =(ship.contact.data.r our.bowl)
==
id.r
::
++ our-contact-id
|= =bowl:gall
^- id:common
=/ r=row:bedrock
%+ snag 0
%+ skim
(all-rows-by-path-type contact-type:common /private bowl)
|= r=row:bedrock ^- ?
?+ -.data.r %.n
%contact =(ship.data.r our.bowl)
==
id.r
::
++ test-bedrock-path-existence
|= [=path =bowl:gall]
^- ?
.= %.y
.^
@ud
%gx
%+ weld
%+ weld
/(scot %p our.bowl)/bedrock/(scot %da now.bowl)/loobean/path
path
/noun
==
::
++ test-bedrock-row-existence
|= [=path =type:common id=[s=ship t=@da] =bowl:gall]
^- ?
.= %.y
.^
@ud
%gx
%+ weld
%+ weld
/(scot %p our.bowl)/bedrock/(scot %da now.bowl)/loobean/row/(scot %t name.type)/(scot %uv hash.type)/(scot %p s.id)/(scot %da t.id)
path
/noun
==
::
++ test-bedrock-table-existence
|= [=type:common =bowl:gall]
^- ?
.= %.y
.^
@ud
%gx
%+ weld
/(scot %p our.bowl)/bedrock/(scot %da now.bowl)/loobean/table
:- name.type
/(scot %uv hash.type)/noun
==
::
++ scry-bedrock-path-host
|= [=path =bowl:gall]
^- ship
.^
ship
%gx
%+ weld
%+ weld
/(scot %p our.bowl)/bedrock/(scot %da now.bowl)/host/path
path
/noun
==
::
++ scry-bedrock-path
|= [=path =bowl:gall]
^- path-row:bedrock
=/ fp
.^ fullpath:bedrock
%gx
%+ weld
%+ weld
/(scot %p our.bowl)/bedrock/(scot %da now.bowl)/db/path
path
/noun
==
path-row.fp
::
++ how-many-peers-in-path
|= [=path =bowl:gall]
^- @ud
=/ fp
.^ fullpath:bedrock
%gx
%+ weld
%+ weld
/(scot %p our.bowl)/bedrock/(scot %da now.bowl)/db/path
path
/noun
==
(lent peers.fp)
::
++ scry-first-bedrock-chat
|= [=path =bowl:gall]
^- (unit row:bedrock)
=/ all-chats=[=type:common pt=pathed-table:bedrock =schemas:bedrock]
.^
[=type:common pt=pathed-table:bedrock =schemas:bedrock]
%gx
%+ weld
%+ weld
/(scot %p our.bowl)/bedrock/(scot %da now.bowl)/db/table-by-path/chat/0v0
path
/noun
==
=/ chat=(unit table:bedrock) (~(get by pt.all-chats) path)
?~ chat ~
=/ rows=(list row:bedrock) ~(val by u.chat)
?: =(0 (lent rows)) ~
(some (snag 0 rows))
::
++ first-common
|= [=type:common =path =bowl:gall]
^- row:bedrock
=/ rows=(list row:bedrock)
(all-rows-by-path-type type path bowl)
(snag 0 rows)
::
++ all-rows-by-path-type
|= [=type:common =path =bowl:gall]
^- (list row:bedrock)
=/ all-rows=[=type:common pt=pathed-table:bedrock =schemas:bedrock]
;; [=type:common pt=pathed-table:bedrock =schemas:bedrock] :: hard-casting for efficeincy?
.^
*
%gx
%+ weld
%+ weld
/(scot %p our.bowl)/bedrock/(scot %da now.bowl)/db/table-by-path/(scot %tas name.type)/(scot %uv hash.type)
path
/noun
==
~(val by (~(got by pt.all-rows) path))
::
++ scry-bedrock-message
|= [id=[=ship t=@da] =path =bowl:gall]
^- row:bedrock
=/ rs=[=row:bedrock =schemas:bedrock]
.^
[row:bedrock schemas:bedrock]
%gx
%+ weld
%+ weld
/(scot %p our.bowl)/bedrock/(scot %da now.bowl)
/row/message/(scot %uv hash:message-type:common)/(scot %p ship.id)/(scot %da t.id)
/noun
==
row.rs
::
++ get-friend
|= [=ship =bowl:gall]
^- [=id:common =friend:common]
=/ rows=(list row:bedrock) (all-rows-by-path-type friend-type:common /private bowl)
=/ r=row:bedrock
%+ snag 0
%+ skim rows
|= r=row:bedrock
^- ?
?+ -.data.r !!
%friend =(ship.data.r ship)
==
:- id.r
?+ -.data.r !!
%friend +.data.r
==
::
++ get-friends
|= =bowl:gall
^- (list friend:common)
?. (test-bedrock-table-existence friend-type:common bowl) ~
=/ rows=(list row:bedrock) (all-rows-by-path-type friend-type:common /private bowl)
%+ turn rows
|= r=row:bedrock
^- friend:common
?+ -.data.r !!
%friend +.data.r
==
::
++ our-contacts
|= =bowl:gall
:: @da is updated-at
^- (list [id:common @da contact:common])
?. (test-bedrock-table-existence contact-type:common bowl) ~
%+ turn
(all-rows-by-path-type contact-type:common /private bowl)
|= r=row:bedrock
^- [id:common @da contact:common]
?+ -.data.r !!
%contact [id.r updated-at.r +.data.r]
==
::
++ contact-info
|= [=ship =bowl:gall]
^- (unit contact:common)
?. (test-bedrock-table-existence contact-type:common bowl) ~
=/ rows=(list row:bedrock)
%+ skim
(all-rows-by-path-type contact-type:common /private bowl)
|= r=row:bedrock ^- ?
?+ -.data.r !!
%contact =(ship ship.data.r)
==
?: =(0 (lent rows)) ~
=/ r (snag 0 rows)
%- some
?+ -.data.r !!
%contact +.data.r
==
::
++ is-friend
|= [=ship =bowl:gall]
^- ?
?. (test-bedrock-table-existence friend-type:common bowl) %.n
=/ rows=(list row:bedrock)
%+ skim
(all-rows-by-path-type friend-type:common /private bowl)
|= r=row:bedrock
^- ?
?+ -.data.r !!
%friend =(ship.data.r ship)
==
?. (gth (lent rows) 0) %.n
=/ r=row:bedrock (snag 0 rows)
?+ -.data.r %.n
%friend =(status.data.r %friend)
==
::
--

93
lib/bulletin.hoon Normal file
View File

@ -0,0 +1,93 @@
/- store=bulletin
=< [store .]
=, store
|%
++ dejs
=, dejs:format
|%
++ action
|= jon=json
^- ^action
=< (decode jon)
|%
++ decode
%- of
:~ [%set-provider set-prov]
[%add-space de-space]
[%remove-space rem-space]
==
::
++ de-space
%- ot
:~ [%path pth]
[%name so]
[%description so]
[%picture so]
[%color so]
==
::
++ set-prov
%- ot
[%provider (su ;~(pfix sig fed:ag))]~
::
++ rem-space
%- ot
[%path pth]~
::
++ pth
%- ot
:~ [%ship (su ;~(pfix sig fed:ag))]
[%space so]
==
::
--
--
::
++ enjs
=, enjs:format
|%
++ reaction
|= rct=^reaction
^- json
%- pairs
:_ ~
^- [cord json]
:- -.rct
?- -.rct
%initial
%- pairs
[%spaces (spaces-map spaces.rct)]~
%space-added
%- pairs
[%space (spc space.rct)]~
%space-removed
%- pairs
[%path s+(pat path.rct)]~
==
++ spaces-map
|= =spaces:store
^- json
%- pairs
%+ turn ~(tap by spaces)
|= [pth=space-path:store space=space-listing:store]
^- [cord json]
[(pat pth) (spc space)]
::
++ spc
|= space=space-listing:store
^- json
%- pairs
:~ ['path' s+(pat path.space)]
['name' s+name.space]
['description' s+description.space]
['picture' s+picture.space]
['color' s+color.space]
==
::
++ pat
|= path=space-path:store
^- cord
(spat /(scot %p ship.path)/(scot %tas space.path))
--
::
--

1271
lib/chat-db.hoon Normal file

File diff suppressed because it is too large Load Diff

186
lib/contact-store.hoon Normal file
View File

@ -0,0 +1,186 @@
/- sur=contact-store
/+ res=resource
=< [sur .]
=, sur
|%
++ nu :: parse number as hex
|= jon=json
?> ?=([%s *] jon)
(rash p.jon hex)
::
++ enjs
=, enjs:format
|%
++ update
|= upd=^update
^- json
%+ frond %contact-update
%- pairs
:_ ~
^- [cord json]
?- -.upd
%initial
:- %initial
%- pairs
:~ [%rolodex (rolo rolodex.upd)]
[%is-public b+is-public.upd]
==
::
%add
:- %add
%- pairs
:~ [%ship (ship ship.upd)]
[%contact (cont contact.upd)]
==
::
%remove
:- %remove
(pairs [%ship (ship ship.upd)]~)
::
%edit
:- %edit
%- pairs
:~ [%ship (ship ship.upd)]
[%edit-field (edit edit-field.upd)]
[%timestamp (time timestamp.upd)]
==
::
%allow
:- %allow
(pairs [%beings (beng beings.upd)]~)
::
%disallow
:- %disallow
(pairs [%beings (beng beings.upd)]~)
::
%set-public
[%set-public b+public.upd]
==
::
++ rolo
|= =rolodex
^- json
%- pairs
%+ turn ~(tap by rolodex)
|= [=^ship =contact]
^- [cord json]
[(scot %p ship) (cont contact)]
::
++ cont
|= =contact
^- json
%- pairs
:~ [%nickname s+nickname.contact]
[%bio s+bio.contact]
[%status s+status.contact]
[%color s+(scot %ux color.contact)]
[%avatar ?~(avatar.contact ~ s+u.avatar.contact)]
[%cover ?~(cover.contact ~ s+u.cover.contact)]
[%groups a+(turn ~(tap in groups.contact) (cork enjs-path:res (lead %s)))]
[%last-updated (time last-updated.contact)]
==
::
++ edit
|= field=edit-field
^- json
%+ frond -.field
?- -.field
%nickname s+nickname.field
%bio s+bio.field
%status s+status.field
%color s+(scot %ux color.field)
%avatar ?~(avatar.field ~ s+u.avatar.field)
%cover ?~(cover.field ~ s+u.cover.field)
%add-group s+(enjs-path:res resource.field)
%remove-group s+(enjs-path:res resource.field)
==
::
++ beng
|= =beings
^- json
?- -.beings
%ships [%a (turn ~(tap in ships.beings) |=(s=^ship s+(scot %p s)))]
%group (enjs:res resource.beings)
==
--
::
++ dejs
=, dejs:format
|%
++ update
|= jon=json
^- ^update
=< (decode jon)
|%
++ decode
%- of
:~ [%initial initial]
[%add add-contact]
[%remove remove-contact]
[%edit edit-contact]
[%allow beings]
[%disallow beings]
[%set-public bo]
==
::
++ initial
%- ot
:~ [%rolodex (op ;~(pfix sig fed:ag) cont)]
[%is-public bo]
==
::
++ add-contact
%- ot
:~ [%ship (su ;~(pfix sig fed:ag))]
[%contact cont]
==
::
++ remove-contact (ot [%ship (su ;~(pfix sig fed:ag))]~)
::
++ edit-contact
%- ot
:~ [%ship (su ;~(pfix sig fed:ag))]
[%edit-field edit]
[%timestamp di]
==
::
++ beings
%- of
:~ [%ships (as (su ;~(pfix sig fed:ag)))]
[%group dejs:res]
==
::
++ cont
%- ot
:~ [%nickname so]
[%bio so]
[%status so]
[%color nu]
[%avatar (mu so)]
[%cover (mu so)]
[%groups (as dejs:res)]
[%last-updated di]
==
::
++ edit
%- of
:~ [%nickname so]
[%bio so]
[%status so]
[%color nu]
[%avatar (mu so)]
[%cover (mu so)]
[%add-group dejs:res]
[%remove-group dejs:res]
==
--
--
::
++ share-dejs
=, dejs:format
|%
++ share
^- $-(json [%share ship])
(of share+(su ;~(pfix sig fed:ag)) ~)
--
--

119
lib/crypto-helper.hoon Normal file
View File

@ -0,0 +1,119 @@
/+ eth=ethereum
|%
++ num-to-hex num-to-hex:eth
::
++ split-sig
|= sig=@
^- [v=@ r=@ s=@]
|^
=^ v sig (take 3)
=^ s sig (take 3 32)
=^ r sig (take 3 32)
=? v (gte v 27) (sub v 27)
[v r s]
::
++ take
|= =bite
[(end bite sig) (rsh bite sig)]
--
::
++ recover-pub-key
|= [msg=@t sig=@t addr=@t] ^- @ux
=/ hashed-msg=@ux
%- keccak-256:keccak:crypto
%- as-octs:mimes:html
%- crip
^- tape
%+ weld
(trip '\19Ethereum Signed Message:\0a')
%+ weld
%- trip
(en:json:html (numb:enjs:format (lent (trip msg))))
(trip msg)
::export function hashMessage(message: Bytes | string): string {
:: if (typeof(message) === "string") { message = toUtf8Bytes(message); }
:: return keccak256(concat([
:: toUtf8Bytes(messagePrefix),
:: toUtf8Bytes(String(message.length)),
:: message]));
=/ ux-sig=@ux (hex-to-num:eth sig)
=/ vrs (split-sig ux-sig)
::SigningKey.recoverPublicKey(digest, signature)
%- serialize-point:secp256k1:secp:crypto
(ecdsa-raw-recover:secp256k1:secp:crypto hashed-msg vrs)
::
++ verify-message
|= [msg=@t sig=@t addr=@t] ^- ?
=/ pubkey=@ux (recover-pub-key msg sig addr)
:: if the passed in address equals the address for the the recovered public key of the sig, then it is verified
=((hex-to-num:eth addr) (address-from-pub:key:eth pubkey))
::
++ ether-hash-to-ux
|= str=@t
^- @ux
=/ ta=tape (cass (slag 2 (trip str)))
=/ reordered=tape ""
=/ i=@ud 0
=/ ready=tape
|-
?: =(0 (lent ta))
+.reordered
=/ b1=@t (snag 0 ta)
=/ b2=@t (snag 1 ta)
?: =(1 (mod i 2))
$(reordered ['.' b1 b2 reordered], ta +.+.ta, i +(i))
$(reordered [b1 b2 reordered], ta +.+.ta, i +(i))
|- :: handle the urbit bullshit %ux parsing rules
?: =('0' (snag 0 ready))
$(ready +.ready)
?: =('.' (snag 0 ready))
$(ready +.ready)
`@ux`(slav %ux (crip ['0' 'x' ready]))
::
++ signed-key-add-msg
|= [new-entity=@t new-key=@t nonce=@ud timestamp=@ud]
^- @t
%- crip
^- tape
:~ new-entity
' owns '
new-key
', '
(ud-to-t nonce)
', '
(ud-to-t timestamp)
==
::
++ ud-to-t
|= a=@u
^- @t
?: =(0 a) '0'
%- crip
%- flop
|- ^- tape
?:(=(0 a) ~ [(add '0' (mod a 10)) $(a (div a 10))])
::
++ check-alchemy
|= [=path patp=@p t=@da chain=@t nft-sig=[sig=@t addr=@t name=@t nonce=@ud t=@ud]]
^- (list card:agent:gall)
=/ url=@t
%- crip
:~ 'https://realm-server.holium.network/alchemy/nfts/'
chain
'/'
addr.nft-sig
==
=/ =request:http [%'GET' url ~ ~]
~& > "sending {<url>}"
:_ ~
:* %pass
%+ weld
/nft-verify/(scot %p patp)/(scot %da t)/[sig.nft-sig]/[addr.nft-sig]/[name.nft-sig]/(scot %ud nonce.nft-sig)/(scot %ud t.nft-sig)
path
%arvo
%i
%request
request
*outbound-config:iris
==
--

2869
lib/db.hoon Normal file

File diff suppressed because it is too large Load Diff

155
lib/dbug.hoon Normal file
View File

@ -0,0 +1,155 @@
:: dbug: agent wrapper for generic debugging tools
::
:: usage: %-(agent:dbug your-agent)
::
|%
+$ poke
$% [%bowl ~]
[%state grab=cord]
[%incoming =about]
[%outgoing =about]
==
::
+$ about
$@ ~
$% [%ship =ship]
[%path =path]
[%wire =wire]
[%term =term]
==
::
++ agent
|= =agent:gall
^- agent:gall
!.
|_ =bowl:gall
+* this .
ag ~(. agent bowl)
::
++ on-poke
|= [=mark =vase]
^- (quip card:agent:gall agent:gall)
?. ?=(%dbug mark)
=^ cards agent (on-poke:ag mark vase)
[cards this]
=/ dbug
!<(poke vase)
=; =tang
((%*(. slog pri 1) tang) [~ this])
?- -.dbug
%bowl [(sell !>(bowl))]~
::
%state
=? grab.dbug =('' grab.dbug) '-'
=; product=^vase
[(sell product)]~
=/ state=^vase
:: if the underlying app has implemented a /dbug/state scry endpoint,
:: use that vase in place of +on-save's.
::
=/ result=(each ^vase tang)
(mule |.(q:(need (need (on-peek:ag /x/dbug/state)))))
?:(?=(%& -.result) p.result on-save:ag)
%+ slap
(slop state !>([bowl=bowl ..zuse]))
(ream grab.dbug)
::
%incoming
=; =tang
?^ tang tang
[%leaf "no matching subscriptions"]~
%+ murn
%+ sort ~(tap by sup.bowl)
|= [[* a=[=ship =path]] [* b=[=ship =path]]]
(aor [path ship]:a [path ship]:b)
|= [=duct [=ship =path]]
^- (unit tank)
=; relevant=?
?. relevant ~
`>[path=path from=ship duct=duct]<
?: ?=(~ about.dbug) &
?- -.about.dbug
%ship =(ship ship.about.dbug)
%path ?=(^ (find path.about.dbug path))
%wire %+ lien duct
|=(=wire ?=(^ (find wire.about.dbug wire)))
%term !!
==
::
%outgoing
=; =tang
?^ tang tang
[%leaf "no matching subscriptions"]~
%+ murn
%+ sort ~(tap by wex.bowl)
|= [[[a=wire *] *] [[b=wire *] *]]
(aor a b)
|= [[=wire =ship =term] [acked=? =path]]
^- (unit tank)
=; relevant=?
?. relevant ~
`>[wire=wire agnt=[ship term] path=path ackd=acked]<
?: ?=(~ about.dbug) &
?- -.about.dbug
%ship =(ship ship.about.dbug)
%path ?=(^ (find path.about.dbug path))
%wire ?=(^ (find wire.about.dbug wire))
%term =(term term.about.dbug)
==
==
::
++ on-peek
|= =path
^- (unit (unit cage))
?. ?=([@ %dbug *] path)
(on-peek:ag path)
?+ path [~ ~]
[%u %dbug ~] ``noun+!>(&)
[%x %dbug %state ~] ``noun+!>(on-save:ag)
[%x %dbug %subscriptions ~] ``noun+!>([wex sup]:bowl)
==
::
++ on-init
^- (quip card:agent:gall agent:gall)
=^ cards agent on-init:ag
[cards this]
::
++ on-save on-save:ag
::
++ on-load
|= old-state=vase
^- (quip card:agent:gall agent:gall)
=^ cards agent (on-load:ag old-state)
[cards this]
::
++ on-watch
|= =path
^- (quip card:agent:gall agent:gall)
=^ cards agent (on-watch:ag path)
[cards this]
::
++ on-leave
|= =path
^- (quip card:agent:gall agent:gall)
=^ cards agent (on-leave:ag path)
[cards this]
::
++ on-agent
|= [=wire =sign:agent:gall]
^- (quip card:agent:gall agent:gall)
=^ cards agent (on-agent:ag wire sign)
[cards this]
::
++ on-arvo
|= [=wire =sign-arvo]
^- (quip card:agent:gall agent:gall)
=^ cards agent (on-arvo:ag wire sign-arvo)
[cards this]
::
++ on-fail
|= [=term =tang]
^- (quip card:agent:gall agent:gall)
=^ cards agent (on-fail:ag term tang)
[cards this]
--
--

223
lib/docket.hoon Normal file
View File

@ -0,0 +1,223 @@
/- *docket
|%
::
++ mime
|%
+$ draft
$: title=(unit @t)
info=(unit @t)
color=(unit @ux)
glob-http=(unit [=url hash=@uvH])
glob-ames=(unit [=ship hash=@uvH])
base=(unit term)
site=(unit path)
image=(unit url)
version=(unit version)
website=(unit url)
license=(unit cord)
==
::
++ finalize
|= =draft
^- (unit docket)
?~ title.draft ~
?~ info.draft ~
?~ color.draft ~
?~ version.draft ~
?~ website.draft ~
?~ license.draft ~
=/ href=(unit href)
?^ site.draft `[%site u.site.draft]
?~ base.draft ~
?^ glob-http.draft
`[%glob u.base hash.u.glob-http %http url.u.glob-http]:draft
?~ glob-ames.draft
~
`[%glob u.base hash.u.glob-ames %ames ship.u.glob-ames]:draft
?~ href ~
=, draft
:- ~
:* %1
u.title
u.info
u.color
u.href
image
u.version
u.website
u.license
==
::
++ from-clauses
=| =draft
|= cls=(list clause)
^- (unit docket)
=* loop $
?~ cls (finalize draft)
=* clause i.cls
=. draft
?- -.clause
%title draft(title `title.clause)
%info draft(info `info.clause)
%color draft(color `color.clause)
%glob-http draft(glob-http `[url hash]:clause)
%glob-ames draft(glob-ames `[ship hash]:clause)
%base draft(base `base.clause)
%site draft(site `path.clause)
%image draft(image `url.clause)
%version draft(version `version.clause)
%website draft(website `website.clause)
%license draft(license `license.clause)
==
loop(cls t.cls)
::
++ to-clauses
|= d=docket
^- (list clause)
%- zing
:~ :~ title+title.d
info+info.d
color+color.d
version+version.d
website+website.d
license+license.d
==
?~ image.d ~ ~[image+u.image.d]
?: ?=(%site -.href.d) ~[site+path.href.d]
=/ ref=glob-reference glob-reference.href.d
:~ base+base.href.d
?- -.location.ref
%http [%glob-http url.location.ref hash.ref]
%ames [%glob-ames ship.location.ref hash.ref]
== == ==
::
++ spit-clause
|= =clause
^- tape
%+ weld " {(trip -.clause)}+"
?+ -.clause "'{(trip +.clause)}'"
%color (scow %ux color.clause)
%site (spud path.clause)
::
%glob-http
"['{(trip url.clause)}' {(scow %uv hash.clause)}]"
::
%glob-ames
"[{(scow %p ship.clause)} {(scow %uv hash.clause)}]"
::
%version
=, version.clause
"[{(scow %ud major)} {(scow %ud minor)} {(scow %ud patch)}]"
==
::
++ spit-docket
|= dock=docket
^- tape
;: welp
":~\0a"
`tape`(zing (join "\0a" (turn (to-clauses dock) spit-clause)))
"\0a=="
==
--
::
++ enjs
=, enjs:format
|%
::
++ charge-update
|= u=^charge-update
^- json
%+ frond -.u
^- json
?- -.u
%del-charge s+desk.u
::
%initial
%- pairs
%+ turn ~(tap by initial.u)
|=([=desk c=^charge] [desk (charge c)])
::
%add-charge
%- pairs
:~ desk+s+desk.u
charge+(charge charge.u)
==
==
::
++ num
|= a=@u
^- ^tape
=/ p=json (numb a)
?> ?=(%n -.p)
(trip p.p)
::
++ version
|= v=^version
^- json
:- %s
%- crip
"{(num major.v)}.{(num minor.v)}.{(num patch.v)}"
::
++ merge
|= [a=json b=json]
^- json
?> &(?=(%o -.a) ?=(%o -.b))
[%o (~(uni by p.a) p.b)]
::
++ href
|= h=^href
%+ frond -.h
?- -.h
%site s+(spat path.h)
%glob
%- pairs
:~ base+s+base.h
glob-reference+(glob-reference glob-reference.h)
==
==
::
++ glob-reference
|= ref=^glob-reference
%- pairs
:~ hash+s+(scot %uv hash.ref)
location+(glob-location location.ref)
==
::
++ glob-location
|= loc=^glob-location
^- json
%+ frond -.loc
?- -.loc
%http s+url.loc
%ames s+(scot %p ship.loc)
==
::
++ charge
|= c=^charge
%+ merge (docket docket.c)
%- pairs
:~ chad+(chad chad.c)
==
::
++ docket
|= d=^docket
^- json
%- pairs
:~ title+s+title.d
info+s+info.d
color+s+(scot %ux color.d)
href+(href href.d)
image+?~(image.d ~ s+u.image.d)
version+(version version.d)
license+s+license.d
website+s+website.d
==
::
++ chad
|= c=^chad
%+ frond -.c
?+ -.c ~
%hung s+err.c
==
--
--

1006
lib/ethereum.hoon Normal file

File diff suppressed because it is too large Load Diff

274
lib/friends.hoon Normal file
View File

@ -0,0 +1,274 @@
:: people [realm]:
::
:: People management lib within Realm. Mostly handles [de]serialization
:: to/from json from types stored in people sur.
::
:: Permissions management is centralized in the spaces agent. People
:: agent synch's permissions with spaces. People agent also
:: synch's contacts from contact-store.
::
::
/- sur=friends
/+ res=resource
=< [sur .]
=, sur
|%
++ contact-to-friend
|= [ufriend=(unit friend:sur) =contact:sur]
^- friend:sur
=/ friend ?~(ufriend *friend:sur u.ufriend)
=/ contact-info
:* nickname.contact
bio.contact
color.contact
avatar.contact
cover.contact
:: groups.contact
==
friend(contact-info `contact-info)
::
++ rolodex-to-friends
|= [=friends:sur =rolodex:sur]
^- friends:sur
%- ~(gas by friends)
%+ turn ~(tap by rolodex)
|= [=ship =contact:sur]
^- [^ship friend:sur]
=/ ufriend (~(get by friends) ship)
[ship (contact-to-friend ufriend contact)]
::
++ purge-contact-info
|= =old=friend:sur
^- friend:sur
=| =new=friend:sur
%= new-friend
pinned pinned.old-friend
tags tags.old-friend
status status.old-friend
==
::
++ field-edit
|= [=friend:sur field=edit-field:sur]
^- friend:sur
=/ contact-info
?~ contact-info.friend *contact-info:sur
u.contact-info.friend
=/ new-contact-info
?+ -.field contact-info
%nickname contact-info(nickname nickname.field)
%bio contact-info(bio bio.field)
%color contact-info(color color.field)
%avatar contact-info(avatar avatar.field)
:: %add-group contact-info(groups (~(put in groups.contact-info) resource.field))
:: %remove-group contact-info(groups (~(del in groups.contact-info) resource.field))
%cover contact-info(cover cover.field)
==
friend(contact-info `new-contact-info)
::
++ nu :: parse number as hex
|= jon=json
?> ?=([%s *] jon)
(rash p.jon hex)
::
++ enjs
=, enjs:format
|%
++ reaction
|= rct=^reaction
^- json
%- pairs
:_ ~
^- [cord json]
?- -.rct
%friends
[%friends (frens:encode friends.rct)]
::
%friend
:- %friend
%- pairs
:~ [%ship s+(scot %p ship.rct)]
[%friend (fren:encode friend.rct)]
==
::
%new-friend
:- %new-friend
%- pairs
:~ [%ship s+(scot %p ship.rct)]
[%friend (fren:encode friend.rct)]
==
::
%bye-friend
:- %bye-friend
(pairs [%ship s+(scot %p ship.rct)]~)
==
::
++ action
|= act=^action
^- json
%+ frond %visa-action
%- pairs
:_ ~
^- [cord json]
?- -.act
::
%add-friend
:- %add-friend
%- pairs
:~ [%ship s+(scot %p ship.act)]
==
::
%edit-friend
:- %edit-friend
%- pairs
:~ [%ship s+(scot %p ship.act)]
[%pinned [%b pinned.act]]
[%tags [%a (turn ~(tap in tags.act) |=(tag=cord s+tag))]]
==
::
%remove-friend
:- %remove-friend
%- pairs
:~ [%ship s+(scot %p ship.act)]
==
::
:: Receiving
::
%be-fren
:- %be-fren
~
::
%yes-fren
:- %yes-fren
~
::
%bye-fren
:- %bye-fren
~
%set-contact
:- %set-contact
~
%share-contact
:- %set-contact
~
%set-sync
:- %set-sync
~
==
::
++ view :: encodes for on-peek
|= view=^view
^- json
?- -.view
%friends
%- pairs
:_ ~
^- [cord json]
[%friends (frens:encode friends.view)]
%contact-info
(enjs-contact-info:encode contact-info.view)
==
--
::
++ dejs
=, dejs:format
|%
++ action
|= jon=json
^- ^action
=< (decode jon)
|%
++ decode
%- of
:~ [%add-friend add-friend]
[%edit-friend edit-friend]
[%remove-friend remove-friend]
[%be-fren ul]
[%yes-fren ul]
[%bye-fren ul]
[%set-contact set-contact]
[%set-sync bo]
==
::
++ json-to-ux
=, dejs:format
|= =json
^- @ux
(scan (trip (so json)) ;~(pfix (jest '0x') hex))
::
++ add-friend
%- ot
:~ [%ship (su ;~(pfix sig fed:ag))]
==
::
++ edit-friend
%- ot
:~ [%ship (su ;~(pfix sig fed:ag))]
[%pinned bo]
[%tags (as cord)]
==
::
++ remove-friend
%- ot
:~ [%ship (su ;~(pfix sig fed:ag))]
==
::
++ set-contact
%- ot
:~ [%ship (se %p)]
[%contact-info json-to-contact-info]
==
::
++ json-to-contact-info
|= =json
^- contact-info-edit
%. json
:~ (ot ~[nickname+so:dejs-soft:format bio+so:dejs-soft:format color+(mu nu) avatar+so:dejs-soft:format cover+so:dejs-soft:format])
==
::
--
--
::
++ encode
=, enjs:format
|%
++ frens
|= =friends
^- json
%- pairs
%+ turn ~(tap by friends)
|= [=^ship =friend]
^- [cord json]
[(scot %p ship) (fren friend)]
::
++ fren
|= =friend
^- json
%- pairs:enjs:format
:~ ['pinned' b+pinned.friend]
['tags' [%a (turn ~(tap in tags.friend) |=(tag=cord s+tag))]]
['status' s+status.friend]
:- 'contactInfo'
?~ contact-info.friend ~
%- pairs
^- (list [@t json])
:~ ['nickname' s+nickname.u.contact-info.friend]
['bio' s+bio.u.contact-info.friend]
['color' s+(scot %ux color.u.contact-info.friend)]
['avatar' ?~(avatar.u.contact-info.friend ~ s+u.avatar.u.contact-info.friend)]
['cover' ?~(cover.u.contact-info.friend ~ s+u.cover.u.contact-info.friend)]
==
==
::
++ enjs-contact-info
|= =contact-info
%- pairs
^- (list [@t json])
:~ ['nickname' s+nickname.contact-info]
['bio' s+bio.contact-info]
['color' s+(scot %ux color.contact-info)]
['avatar' ?~(avatar.contact-info ~ s+u.avatar.contact-info)]
['cover' ?~(cover.contact-info ~ s+u.cover.contact-info)]
==
::
--
--

125
lib/groups.hoon Normal file
View File

@ -0,0 +1,125 @@
/- store=groups, member-store=membership, *resource, mtd=metadata-store, g=new-groups
=< [store .]
=, store
|%
:: TODO break this out into seperate gates
++ our-groups
|= [our=ship now=@da]
^- (list group-space)
=/ has-groups .^(? %gu /(scot %p our)/groups/(scot %da now)/$)
?. has-groups *(list group-space)
=/ groups .^(groups:g %gx /(scot %p our)/groups/(scot %da now)/groups/groups)
:: find ours
=/ hosted
^- (list [f=flag:g g=group-ui:g])
%+ skim ~(tap by groups)
|= [f=flag:g g=group-ui:g]
=(our -.f)
:: get metadata for each
%+ turn hosted
|= [=flag:g =group-ui:g]
^- group-space
=/ access
?: =(-.cordon.group-ui %open)
%public
%private
=/ metadata meta.group-ui
:: Get group data
=/ member-count=@u
(lent ~(tap by fleet.group-ui))
:: Get metadata
=/ title=@t title.metadata
=/ image=@t image.metadata
=/ first-char (trim 1 (trip image))
?: =(p.first-char "#")
[our +.flag title access '' image member-count]
[our +.flag title access image '' member-count]
::
++ skim-group-dms
|= [resource=[entity=ship name=@tas]]
=/ name (cord name.resource)
=/ name-da (slaw %da name)
?~ name-da %.y %.n
::
++ get-group
|= [rid=[entity=ship name=@tas] our=ship now=@da]
^- group-ui:g
=/ groups .^(groups:g %gx /(scot %p our)/groups/(scot %da now)/groups/groups)
(~(got by groups) rid)
::
:: JSON
::
++ enjs
=, enjs:format
|%
++ view :: encodes for on-peek
|= vi=view:store
^- json
%- pairs
:_ ~
^- [cord json]
:- -.vi
?- -.vi
::
%group
(group:encode group.vi)
::
%groups
(groups:encode groups.vi)
::
%members
(members:encode members.vi)
==
--
::
++ encode
=, enjs:format
|%
++ groups
|= grps=(list group-space)
^- json
%- pairs
%+ turn grps
|= grp=group-space
=/ path (spat /(scot %p creator.grp)/(scot %tas name.grp))
[path (group grp)]
::
++ group
|= grp=group-space
^- json
%- pairs
:~ ['creator' s+(scot %p creator.grp)]
['path' s+(spat /(scot %p creator.grp)/(scot %tas name.grp))]
['name' s+title.grp]
['access' s+access.grp]
['picture' s+picture.grp]
['color' s+color.grp]
['memberCount' n+(scot %u member-count.grp)]
==
::
++ members
|= fl=fleet:g
%- pairs
%+ turn ~(tap by fl)
|= [her=@p v=vessel:fleet:g]
[(scot %p her) (member-vessel v)]
++ member-vessel
|= v=vessel:fleet:g
%- pairs
=/ roles (turn ~(tap in sects.v) (lead %s))
=/ status
?~ roles
'invited'
'joined'
=? roles =(~ roles)
[s+%member]~
:~ :- 'primaryRole'
?: (~(has in (silt roles)) s+'admin')
s+'admin'
s+'member'
['status' s+status]
['alias' s+'']
[roles/a/[roles]]
==
--
--

79
lib/membership.hoon Normal file
View File

@ -0,0 +1,79 @@
/- sur=membership, spcs=spaces-store, frens-sur=friends
=< [sur .]
=, sur
|%
:: TODO add decode
++ enjs
=, enjs:format
|%
++ view :: encodes for on-peek
|= view=^view
^- json
%- pairs
:_ ~
^- [cord json]
?- -.view
::
%membership
[%membership (membership-json:encode membership.view)]
::
%members
[%members (members-json:encode members.view)]
::
%member
[%member (member-json:encode member.view)]
::
%is-member
[%is-member b+is-member.view]
==
--
++ encode
=, enjs:format
|%
::
++ membership-json
|= =membership
^- json
%- pairs
%+ turn ~(tap by membership)
|= [pth=space-path:spcs =members]
=/ spc-path (spat /(scot %p ship.pth)/(scot %tas space.pth))
^- [cord json]
[spc-path (members-json members)]
::
++ members-json
|= =members
^- json
%- pairs
%+ turn ~(tap by members)
|= [=^ship =member]
^- [cord json]
[(scot %p ship) (member-json member)]
::
++ member-json
|= =member
^- json
%- pairs
:~
['roles' (rols roles.member)]
['alias' s+alias.member]
['status' s+(scot %tas status.member)]
==
::
++ rols
|= =roles
^- json
[%a (turn ~(tap in roles) |=(rol=role s+(scot %tas rol)))]
::
++ is-mem
|= is=?
^- json
%- pairs
:~
['is-member' b+is]
==
::
--
--

49
lib/multipart.hoon Normal file
View File

@ -0,0 +1,49 @@
:: multipart: multipart/form-data request decoding
::
|%
+$ part
$: file=(unit @t) :: filename
type=(unit mite) :: content-type
code=(unit @t) :: content-transfer-encoding
body=@t :: content
==
::
++ de-request
|= [=header-list:http body=(unit octs)]
^- (unit (list [@t part]))
?~ body ~
?~ cot=(get-header:http 'content-type' header-list) ~
?. =('multipart/form-data; boundary=' (end 3^30 u.cot)) ~
%+ rush q.u.body
(dep (rsh 3^30 u.cot))
::
++ dep
|= del=@t
|^
%+ knee *(list [@t part]) |. ~+
;~ pose (cold ~ (full tip)) :: end, or
;~ pfix dim nip :: section start
;~ plug ;~ plug :: containing:
(ifix [cof doq] nom) :: name
(punt (ifix [cup doq] nod)) :: filename
(punt ;~(pfix nip cut nab)) :: content-type
(punt ;~(pfix nip cue nom)) :: con-tra-encoding
(ifix [sip nip] nag) :: content
== ^$ == == ==
::
++ cof (jest 'Content-Disposition: form-data; name="')
++ cue (jest 'Content-Transfer-Encoding: ')
++ cup (jest '; filename="')
++ cut (jest 'Content-Type: ')
++ dim (jest (cat 3 '--' del))
++ nip (jest '\0d\0a')
++ nab (more fas (cook (cury rap 3) (plus qit)))
++ nag (dine ;~(less ;~(plug nip dim) next))
++ nod (dine ;~(less doq next))
++ nom (dine alp)
++ sip ;~(plug nip nip)
++ tip ;~(plug dim hep hep nip)
::
++ dine |*(r=rule (cook (cury rep 3) (star r)))
--
--

474
lib/notif-db.hoon Normal file
View File

@ -0,0 +1,474 @@
:: notif-db [realm]:
::
/- *notif-versioned-state, sur=notif-db, chat-db
/+ cdb-lib=chat-db
|%
::
:: helpers
::
++ mark-row-unread
|= [r=notif-row:sur t=@da]
=. read.r %.n
=. updated-at.r t
r
::
++ mark-row-read
|= [r=notif-row:sur now=@da]
=. read-at.r now
=. updated-at.r now
=. read.r %.y
r
::
++ mark-app-read
|= [tbl=notifs-table:sur app=@tas now=@da]
=/ kvs (skim (tap:notifon:sur tbl) |=([k=@ud v=notif-row:sur] &(=(app app.v) =(read.v %.n))))
=/ ids=(list id:sur) (turn kvs |=([k=@ud v=notif-row:sur] k))
=/ index=@ud 0
=/ stop=@ud (lent ids)
|-
?: =(stop index)
[tbl ids]
$(index +(index), tbl (put:notifon:sur tbl (snag index ids) (mark-row-read +:(snag index kvs) now)))
::
++ mark-path-read
|= [tbl=notifs-table:sur app=@tas =path now=@da]
=/ kvs (skim (tap:notifon:sur tbl) |=([k=@ud v=notif-row:sur] &(=(path path.v) =(app app.v) =(read.v %.n))))
=/ ids=(list id:sur) (turn kvs |=([k=@ud v=notif-row:sur] k))
=/ index=@ud 0
=/ stop=@ud (lent ids)
|-
?: =(stop index)
[tbl ids]
$(index +(index), tbl (put:notifon:sur tbl (snag index ids) (mark-row-read +:(snag index kvs) now)))
::
++ toggle-dismissed
|= [r=notif-row:sur now=@da d=?]
=. dismissed-at.r now
=. updated-at.r now
=. dismissed.r d
r
::
++ mark-app-dismiss
|= [tbl=notifs-table:sur app=@tas now=@da]
=/ kvs (skim (tap:notifon:sur tbl) |=([k=@ud v=notif-row:sur] &(=(app app.v) =(dismissed.v %.n))))
=/ ids=(list id:sur) (turn kvs |=([k=@ud v=notif-row:sur] k))
=/ index=@ud 0
=/ stop=@ud (lent ids)
|-
?: =(stop index)
[tbl ids]
$(index +(index), tbl (put:notifon:sur tbl (snag index ids) (toggle-dismissed +:(snag index kvs) now %.y)))
::
++ mark-path-dismiss
|= [tbl=notifs-table:sur app=@tas =path now=@da]
=/ kvs (skim (tap:notifon:sur tbl) |=([k=@ud v=notif-row:sur] &(=(path path.v) =(app app.v) =(dismissed.v %.n))))
=/ ids=(list id:sur) (turn kvs |=([k=@ud v=notif-row:sur] k))
=/ index=@ud 0
=/ stop=@ud (lent ids)
|-
?: =(stop index)
[tbl ids]
$(index +(index), tbl (put:notifon:sur tbl (snag index ids) (toggle-dismissed +:(snag index kvs) now %.y)))
++ ids-by-path
|= [tbl=notifs-table:sur app=@tas =path]
^- (list id:sur)
%+ turn
(skim (tap:notifon:sur tbl) |=([k=@ud v=notif-row:sur] &(=(app app.v) =(path path.v))))
|=([k=@ud v=notif-row:sur] k)
::
++ ids-by-link
|= [tbl=notifs-table:sur app=@tas link=cord]
^- (list id:sur)
%+ turn
(skim (tap:notifon:sur tbl) |=([k=@ud v=notif-row:sur] &(=(app app.v) =(link link.v))))
|=([k=@ud v=notif-row:sur] k)
::
++ generate-uniq-notif-ids-to-del
|= [state=state-0 deleted-msg-id-cords=(list cord) deleted-paths=(list path)]
^- (list id:sur)
=/ notif-ids-to-del-set=(set id:sur)
%- silt
^- (list id:sur)
%+ weld
^- (list id:sur)
%- zing
%+ turn
deleted-msg-id-cords
|= =cord
^- (list id:sur)
(ids-by-link notifs-table.state %realm-chat cord)
^- (list id:sur)
%- zing
%+ turn
deleted-paths
|= =path
^- (list id:sur)
(ids-by-path notifs-table.state %realm-chat path)
~(tap in notif-ids-to-del-set)
::
::
:: poke actions
::
++ create
:: :notif-db &notif-db-poke [%create %chat-db /realm-chat/path-id %message 'Title' 'the message' '' ~ '' ~ %.n]
|= [act=create-action:sur state=state-0 =bowl:gall]
^- (quip card state-0)
=/ row=notif-row:sur [
next.state
app.act
path.act
type.act
title.act
content.act
image.act
buttons.act
link.act
metadata.act
now.bowl
now.bowl
*@da
%.n
?:(dismissed.act now.bowl *@da)
dismissed.act
]
=. notifs-table.state (put:notifon:sur notifs-table.state next.state row)
=. next.state +(next.state)
=/ thechange notif-db-change+!>((limo [[%add-row row] ~]))
=/ gives :~
[%give %fact [/db /new ~] thechange]
==
[gives state]
::
++ read-id
:: :notif-db &notif-db-poke [%read-id 0]
|= [=id:sur state=state-0 =bowl:gall]
^- (quip card state-0)
=/ row (mark-row-read (got:notifon:sur notifs-table.state id) now.bowl)
=. notifs-table.state (put:notifon:sur notifs-table.state id row)
=/ thechange notif-db-change+!>((limo [[%update-row row] ~]))
=/ gives :~
[%give %fact [/db ~] thechange]
==
[gives state]
::
++ read-app
:: :notif-db &notif-db-poke [%read-app %chat-db]
|= [app=@tas state=state-0 =bowl:gall]
^- (quip card state-0)
:: mark-result is like: [notifs-table ids]
=/ mark-result (mark-app-read notifs-table.state app now.bowl)
=. notifs-table.state -:mark-result
=/ thechange notif-db-change+!>((turn +:mark-result |=(id=@ud [%update-row (got:notifon:sur notifs-table.state id)])))
=/ gives :~
[%give %fact [/db ~] thechange]
==
[gives state]
::
++ read-path
:: :notif-db &notif-db-poke [%read-path %chat-db /realm-chat/path-id]
|= [act=[app=@tas =path] state=state-0 =bowl:gall]
^- (quip card state-0)
:: mark-result is like: [notifs-table ids]
=/ mark-result (mark-path-read notifs-table.state app.act path.act now.bowl)
=. notifs-table.state -:mark-result
=/ thechange notif-db-change+!>((turn +:mark-result |=(id=@ud [%update-row (got:notifon:sur notifs-table.state id)])))
=/ gives :~
[%give %fact [/db ~] thechange]
==
[gives state]
::
++ read-all
:: :notif-db &notif-db-poke [%read-all %.y]
|= [flag=? state=state-0 =bowl:gall]
^- (quip card state-0)
=/ t now.bowl
=. notifs-table.state (run:notifon:sur notifs-table.state |=(r=notif-row:sur ?:(flag (mark-row-read r t) (mark-row-unread r t))))
=/ thechange notif-db-change+!>((limo [[%update-all flag] ~]))
=/ gives :~
[%give %fact [/db ~] thechange]
==
[gives state]
::
++ dismiss-id
:: :notif-db &notif-db-poke [%dismiss-id 0]
|= [=id:sur state=state-0 =bowl:gall]
^- (quip card state-0)
=/ row (toggle-dismissed (got:notifon:sur notifs-table.state id) now.bowl %.y)
=. notifs-table.state (put:notifon:sur notifs-table.state id row)
=/ thechange notif-db-change+!>((limo [[%update-row row] ~]))
=/ gives :~
[%give %fact [/db ~] thechange]
==
[gives state]
::
++ dismiss-app
:: :notif-db &notif-db-poke [%dismiss-app %chat-db]
|= [app=@tas state=state-0 =bowl:gall]
^- (quip card state-0)
:: mark-result is like: [notifs-table ids]
=/ mark-result (mark-app-dismiss notifs-table.state app now.bowl)
=. notifs-table.state -:mark-result
=/ thechange notif-db-change+!>((turn +:mark-result |=(id=@ud [%update-row (got:notifon:sur notifs-table.state id)])))
=/ gives :~
[%give %fact [/db ~] thechange]
==
[gives state]
::
++ dismiss-path
:: :notif-db &notif-db-poke [%dismiss-path %chat-db /realm-chat/path-id]
|= [act=[app=@tas =path] state=state-0 =bowl:gall]
^- (quip card state-0)
:: mark-result is like: [notifs-table ids]
=/ mark-result (mark-path-dismiss notifs-table.state app.act path.act now.bowl)
=. notifs-table.state -:mark-result
=/ thechange notif-db-change+!>((turn +:mark-result |=(id=@ud [%update-row (got:notifon:sur notifs-table.state id)])))
=/ gives :~
[%give %fact [/db ~] thechange]
==
[gives state]
::
++ update
:: :notif-db &notif-db-poke [%update 0 %chat-db /realm-chat/path-id %message 'T2' 'the mes...' '' ~ '' ~]
|= [act=[=id:sur =create-action:sur] state=state-0 =bowl:gall]
^- (quip card state-0)
=/ row (got:notifon:sur notifs-table.state id.act)
=. app.row app.create-action.act
=. path.row path.create-action.act
=. type.row type.create-action.act
=. title.row title.create-action.act
=. content.row content.create-action.act
=. image.row image.create-action.act
=. buttons.row buttons.create-action.act
=. link.row link.create-action.act
=. metadata.row metadata.create-action.act
=. updated-at.row now.bowl
=. notifs-table.state (put:notifon:sur notifs-table.state id.act row)
=/ thechange notif-db-change+!>([[%update-row row] ~])
=/ gives :~
[%give %fact [/db ~] thechange]
==
[gives state]
::
++ delete
:: :notif-db &notif-db-poke [%delete 0]
|= [=id:sur state=state-0 =bowl:gall]
^- (quip card state-0)
=. notifs-table.state +:(del:notifon:sur notifs-table.state id)
=. del-log.state (put:delon:sur del-log.state now.bowl [%del-row id])
=/ thechange notif-db-change+!>((limo [[%del-row id] ~]))
=/ gives :~
[%give %fact [/db ~] thechange]
==
[gives state]
::
++ delete-old-realm-chat-notifs
|= [state=state-0 =bowl:gall]
^- (quip card state-0)
=/ del-log-kvs
%- tap:delon:chat-db
.^(del-log:chat-db %gx /(scot %p our.bowl)/chat-db/(scot %da now.bowl)/delete-log/start-ms/0/noun)
=/ deleted-msg-id-cords=(list cord)
%+ turn
%+ skim
del-log-kvs
|= [k=time v=db-change-type:chat-db]
?+ -.v %.n
%del-messages-row %.y
==
|= [k=time v=db-change-type:chat-db]
^- cord
?+ -.v !!
%del-messages-row (msg-id-to-cord:encode:cdb-lib msg-id.uniq-id.v)
==
=/ deleted-paths
%+ turn
%+ skim
del-log-kvs
|= [k=time v=db-change-type:chat-db]
?+ -.v %.n
%del-paths-row %.y
==
|= [k=time v=db-change-type:chat-db]
^- path
?+ -.v !!
%del-paths-row path.v
==
=/ notif-ids-to-del=(list id:sur)
(generate-uniq-notif-ids-to-del state deleted-msg-id-cords deleted-paths)
=/ index=@ud 0
=/ changes=db-change:sur ~
=/ cs=[db-change:sur state-0]
|-
?: =(index (lent notif-ids-to-del))
[changes state]
=/ id=id:sur (snag index notif-ids-to-del)
=/ ch=db-change-type:sur [%del-row id]
=. notifs-table.state +:(del:notifon:sur notifs-table.state id)
=. del-log.state (put:delon:sur del-log.state (add now.bowl index) ch)
$(index +(index), changes (snoc changes ch))
=/ thechange notif-db-change+!>(-.cs)
=/ gives :~
[%give %fact [/db ~] thechange]
==
[gives +.cs]
::
::
:: JSON
::
++ dejs
=, dejs:format
|%
++ action
|= jon=json
^- ^action
=< (decode jon)
|%
++ decode
%- of
:~ [%create de-create]
[%read-id ni]
[%read-app (se %tas)]
[%read-path app-and-path]
[%read-all bo]
[%dismiss-id ni]
[%dismiss-app (se %tas)]
[%dismiss-path app-and-path]
[%update de-update]
[%delete ni]
==
::
++ de-update
%- ot
:- [%id ni]
de-create-list
::
++ de-create (ot de-create-list)
::
++ de-create-list
:~ [%app (se %tas)]
[%path pa]
[%type (se %tas)]
[%title so]
[%content so]
[%image so]
[%buttons (ar button)]
[%link so]
[%metadata (om so)]
[%dismissed bo]
==
::
++ button
%- ot
:~ [%label so]
[%path pa]
[%data so]
[%metadata (om so)]
==
::
++ app-and-path
%- ot
:~ [%app (se %tas)]
[%path pa]
==
--
--
++ enjs
=, enjs:format
|%
++ db-change :: encodes for on-watch
|= db=db-change:sur
^- json
(changes:encode db)
::
++ rows :: encodes for on-peek
|= rws=(list notif-row:sur)
^- json
(notifs:encode rws)
--
++ encode
=, enjs:format
|%
++ del-log
|= log=del-log:sur
^- json
:- %a
%+ turn (tap:delon:sur log)
|= [k=@da v=db-change-type:sur]
%- pairs
:~
['timestamp' (time k)]
['change' (individual-change v)]
==
::
++ notifs
|= rows=(list notif-row:sur)
^- json
[%a (turn rows notifs-row)]
::
++ notifs-row
|= =notif-row:sur
^- json
%- pairs
:~ id+(numb id.notif-row)
app+s+app.notif-row
path+s+(spat path.notif-row)
type+s+type.notif-row
title+s+title.notif-row
content+s+content.notif-row
image+s+image.notif-row
buttons+a+(turn buttons.notif-row button-up)
link+s+link.notif-row
metadata+(metadata-to-json metadata.notif-row)
created-at+(time created-at.notif-row)
updated-at+(time updated-at.notif-row)
read-at+(time-or-null read-at.notif-row)
read+b+read.notif-row
dismissed-at+(time-or-null dismissed-at.notif-row)
dismissed+b+dismissed.notif-row
==
::
++ time-or-null
|= t=@da
^- json
?: =(t *@da)
~
(time t)
::
++ changes
|= ch=db-change:sur
^- json
[%a (turn ch individual-change)]
++ individual-change
|= ch=db-change-type:sur
%- pairs
?- -.ch
%add-row
:~(['type' %s -.ch] ['row' (notifs-row notif-row.ch)])
%update-all
:~(['type' %s -.ch] ['read' %b flag.ch])
%update-row
:~(['type' %s -.ch] ['row' (notifs-row notif-row.ch)])
%del-row
:~(['type' %s -.ch] ['id' (numb id.ch)])
==
++ button-up
|= b=button:sur
^- json
%- pairs
:~ ['label' %s label.b]
['path' s+(spat path.b)]
['data' s+data.b]
['metadata' (metadata-to-json metadata.b)]
==
++ metadata-to-json
|= m=(map cord cord)
^- json
o+(~(rut by m) |=([k=cord v=cord] s+v))
--
--

1481
lib/passport.hoon Normal file

File diff suppressed because it is too large Load Diff

1182
lib/realm-chat.hoon Normal file

File diff suppressed because it is too large Load Diff

273
lib/realm-wallet.hoon Normal file
View File

@ -0,0 +1,273 @@
/- *realm-wallet
/+ bech32=bip-b173, bip32, ethereum
|%
++ bip44-codes
^- (map network @ud)
%- my
:~ [%bitcoin 0]
[%btctestnet 1]
[%ethereum 60]
==
::
++ new-address
|= [xpub=@t =network idx=@ud]
=, hmac:crypto
=, secp:crypto
=+ ecc=secp256k1
=/ code (~(got by bip44-codes) network)
=/ xpub-bip32 (from-extended:bip32 (trip xpub))
=/ path "0/{<idx>}"
=/ derived-pub (derive-path:xpub-bip32 path)
:- ?- network
%bitcoin
(address:derived-pub %main)
%btctestnet
(address:derived-pub %testnet)
%ethereum
(address-from-pub:key:ethereum (serialize-point.ecc pub:derived-pub))
==
=/ path "m/44'/{<code>}'/0'/0/{<idx>}"
(crip path)
::
++ split-xpub
|= xpub=@
^- [@ @]
:- (rsh 8 xpub)
(end 8 xpub)
::
++ btc-address
|= [ki=@ ci=@]
^- address
*address
::
++ hex-from-cord
|= transaction
0
::
++ json-to-transaction
=, dejs:format
|= =json
^- transaction
=/ tx
^- help-transaction
%. json
:~ (ot ~[hash+so network+(su (perk %bitcoin %ethereum ~)) type+(su (perk %sent %received ~)) initiated-at+so completed-at+so:dejs-soft:format our-address+so their-patp+so:dejs-soft:format their-address+so status+(su (perk %pending %failed %succeeded ~)) failure-reason+so:dejs-soft:format notes+so])
==
:* hash.tx
network.tx
type.tx
initiated-at.tx
completed-at.tx
our-address.tx
?~ their-patp.tx ~
[~ `@p`(slav %p u.their-patp.tx)]
their-address.tx
status.tx
failure-reason.tx
notes.tx
==
::
++ transaction-to-json
=, enjs:format
|= =transaction
^- json
%- pairs
:~ ['hash' [%s hash.transaction]]
['network' [%s network.transaction]]
['type' [%s type.transaction]]
['initiatedAt' [%s initiated-at.transaction]]
:- 'completedAt'
?~ completed-at.transaction ~
[%s u.completed-at.transaction]
['ourAddress' [%s our-address.transaction]]
:- 'theirPatp'
?~ their-patp.transaction ~
[%s (crip (scow %p u.their-patp.transaction))]
['theirAddress' [%s their-address.transaction]]
['status' [%s status.transaction]]
:- 'failureReason'
?~ failure-reason.transaction ~
[%s u.failure-reason.transaction]
['notes' [%s notes.transaction]]
==
::
++ dejs-action
=, dejs:format
|= jon=json
^- action
%. jon
%- of
:~ [%initialize ul]
[%set-xpub (ot ~[network+(su (perk %bitcoin %btctestnet %ethereum ~)) xpub+so])]
[%set-network-settings (ot ~[network+(su (perk %bitcoin %btctestnet %ethereum ~)) mode+(su (perk %default %on-demand ~)) who+(su (perk %nobody %friends %anybody ~)) blocked+(as (se %p)) share-index+ni who+(su (perk %nobody %friends %anybody ~)) mode+(su (perk %on-demand %default ~))])]
[%set-passcode-hash (ot ~[hash+so])]
[%set-wallet-creation-mode (ot ~[network+(su (perk %bitcoin %btctestnet %ethereum ~)) mode+(su (perk %on-demand %default ~))])]
[%set-sharing-mode (ot ~[network+(su (perk %bitcoin %btctestnet %ethereum ~)) who+(su (perk %nobody %friends %anybody ~))])]
[%set-sharing-permissions (ot ~[type+(su (perk %block ~)) who+(se %p)])]
[%set-default-index (ot ~[network+(su (perk %bitcoin %btctestnet %ethereum ~)) index+ni])]
[%set-wallet-nickname (ot ~[network+(su (perk %bitcoin %btctestnet %ethereum ~)) index+ni nickname+so])]
[%create-wallet (ot ~[sndr+(se %p) network+(su (perk %bitcoin %btctestnet %ethereum ~)) nickname+so])]
[%set-transaction (ot ~[network+(su (perk %bitcoin %btctestnet %ethereum ~)) net+so wallet+ni contract+so:dejs-soft hash+json-to-ux transaction+json-to-transaction])]
[%save-transaction-notes (ot ~[network+(su (perk %bitcoin %btctestnet %ethereum ~)) net+so wallet+ni contract+so:dejs-soft hash+so notes+so])]
==
::
++ json-to-ux
=, dejs:format
|= =json
^- @ux
(scan (trip (so json)) ;~(pfix (jest '0x') hex))
::
++ transactions-to-json
=, enjs:format
|= transactions=(map net=@t (map @t transaction))
^- json
%- pairs
=/ tx-list ~(tap by transactions)
%+ turn tx-list
|= [net=@t transactions=(map @t transaction)]
^- [@t json]
:- net
%- pairs
=/ tx-list ~(tap by transactions)
%+ turn tx-list
|= [key=@t =transaction]
^- [@t json]
[key (transaction-to-json transaction)]
::
++ token-transactions-to-json
=, enjs:format
|= token-txns=(map net=@t (map @t (map @t transaction)))
^- json
%- pairs
=/ tx-list ~(tap by token-txns)
%+ turn tx-list
|= [net=@t transactions=(map @t (map @t transaction))]
^- [@t json]
:- net
%- pairs
=/ tx-list ~(tap by transactions)
%+ turn tx-list
|= [contract=@t contract-transactions=(map @t transaction)]
^- [@t json]
:- contract
%- pairs
=/ tx-list ~(tap by contract-transactions)
%+ turn tx-list
|= [key=@t =transaction]
^- [@t json]
[key (transaction-to-json transaction)]
::
++ enjs-update
=, enjs:format
|= =update
^- json
::
=* enjs-ui-update
%- pairs
:_ ~
:- `cord`-.update
?- -.update
%eth-xpub
?~ xpub.update ~
[%s u.xpub.update]
%transaction
%- pairs
:~ ['network' [%s network.update]]
['net' [%s net.update]]
['index' (numb +>+<.update)]
:- 'contract'
?~ +>+>-.update ~
[%s +>+>->.update]
['key' [%s +>+>+<.update]]
['transaction' (transaction-to-json +>+>+>.update)]
==
::
%wallet
^- json
%- pairs
^- (list [@t json])
:~ ['network' [%s network.update]]
['key' [%s +>-.update]]
?: ?| =(network.update %bitcoin)
=(network.update %btctestnet)
==
['address' [%s address.wallet.update]]
::['address' [%s (crip q:(trim 2 (scow %uc address.wallet.update)))]]
['address' [%s address.wallet.update]]
['path' [%s path.wallet.update]]
['nickname' [%s nickname.wallet.update]]
==
::
%wallets
%- pairs
^- (list [@t json])
|^
=/ wallet-list ~(tap by +.update)
%+ turn wallet-list
jsonify-wallet-map
++ jsonify-wallet-map
|= [=network wallets=(map @ud =wallet)]
^- [@t json]
|^
=/ wallet-list
^- (list [@ud =wallet])
~(tap by wallets)
:- `@t`network
%- pairs
^- (list [@t json])
%+ turn wallet-list
jsonify-wallet
++ jsonify-wallet
|= [key=@ud =wallet]
^- [@t json]
:- (crip (scow %ud key))
%- pairs
^- (list [@t json])
:~ ?: ?| =(network %bitcoin)
=(network %btctestnet)
==
['address' [%s address.wallet]]
::['address' [%s (crip q:(trim 2 (scow %uc address.wallet)))]]
['address' [%s address.wallet]]
['path' [%s path.wallet]]
['nickname' [%s nickname.wallet]]
['transactions' (transactions-to-json transactions.wallet)]
['token-txns' (token-transactions-to-json token-txns.wallet)]
==
--
--
::
%settings
%- pairs
^- (list [@t json])
:~ ['passcodeHash' s+passcode-hash.update]
:- 'networks'
%- pairs
%+ turn ~(tap by networks.update)
|= [=network [xpub=(unit @t) default-index=@ud =sharing]]
^- [@t json]
:- `cord`network
%- pairs
:~ ['defaultIndex' (numb default-index)]
['walletCreationMode' s+`cord`wallet-creation.sharing]
['sharingMode' s+`cord`who.sharing]
==
=/ blocked
^- (list json)
=/ blocklist ~(tap in blocked.update)
%+ turn blocklist
|= blocked=@p
[%s (scot %p blocked)]
['blocked' a+blocked]
==
%passcode
s+passcode-hash.update
==
?+ -.update enjs-ui-update
%address
%- pairs
?~ address.update
['address' ~]~
['address' [%s u.address.update]]~
==
--

83
lib/realm.hoon Normal file
View File

@ -0,0 +1,83 @@
/- *realm
|%
::
++ mime
|%
+$ draft
$: size=(unit [@ud @ud])
titlebar-border=(unit ?)
show-titlebar=(unit ?)
==
::
++ finalize
|= =draft
^- (unit config)
?~ size.draft ~
?~ titlebar-border.draft ~
?~ show-titlebar.draft ~
=, draft
:- ~
:* u.size
u.titlebar-border
u.show-titlebar
==
::
++ from-clauses
=| =draft
|= cls=(list clause)
^- (unit config)
=* loop $
?~ cls (finalize draft)
=* clause i.cls
=. draft
?- -.clause
%size draft(size `size.clause)
%titlebar-border draft(titlebar-border `titlebar-border.clause)
%show-titlebar draft(show-titlebar `show-titlebar.clause)
==
loop(cls t.cls)
::
++ to-clauses
|= c=config
^- (list clause)
:~ size+size.c
titlebar-border+titlebar-border.c
show-titlebar+show-titlebar.c
==
::
++ spit-clause
|= =clause
^- tape
%+ weld " {(trip -.clause)}+"
?- -.clause ::"'{(trip +.clause)}'"
%size "[{(scow %ud -.size.clause)} {(scow %ud +.size.clause)}]"
%titlebar-border ?: titlebar-border.clause "%.y" "%.n"
%show-titlebar ?: show-titlebar.clause "%.y" "%.n"
==
::
++ spit-config
|= =config
^- tape
;: welp
":~\0a"
`tape`(zing (join "\0a" (turn (to-clauses config) spit-clause)))
"\0a=="
==
--
::
++ enjs
=, enjs:format
|%
::
++ config
|= c=^config
^- json
%- pairs
:~ ['size' a+~[(numb -:size.c) (numb +:size.c)]]
['titlebarBorder' b+titlebar-border.c]
['showTitlebar' b+show-titlebar.c]
==
::
--
--

57
lib/resource.hoon Normal file
View File

@ -0,0 +1,57 @@
/- sur=resource
=< resource
|%
+$ resource resource:sur
++ en-path
|= =resource
^- path
~[%ship (scot %p entity.resource) name.resource]
::
++ de-path
|= =path
^- resource
(need (de-path-soft path))
::
++ de-path-soft
|= =path
^- (unit resource)
?. ?=([%ship @ @ *] path)
~
=/ ship
(slaw %p i.t.path)
?~ ship
~
`[u.ship i.t.t.path]
::
++ enjs
|= =resource
^- json
=, enjs:format
%- pairs
:~ ship+(ship entity.resource)
name+s+name.resource
==
::
++ enjs-path
|= =resource
%- spat
(en-path resource)
::
++ dejs-path
%- su:dejs:format
;~ pfix
(jest '/ship/')
;~((glue fas) ;~(pfix sig fed:ag) urs:ab)
==
::
++ dejs
=, dejs:format
^- $-(json resource)
|= jon=json
~| dejs+%resource
%. jon
%- ot
:~ ship+(su ;~(pfix sig fed:ag))
name+so
==
--

253
lib/rooms.hoon Normal file
View File

@ -0,0 +1,253 @@
/- sur=rooms
=< [sur .]
=, sur
|%
++ server %rooms
++ client %room
++ max-occupancy 6
++ max-rooms 256
::
:: ++ leave-rooms
:: :: remove ship from all rooms
:: ::
:: :: this enforces cleanliness
:: |= [rooms=(map rid room) =ship]
:: ^- (map rid room)
:: :: TODO should this return bump %exit =ship cards?
:: =/ looms ~(val by rooms)
:: :: create list of rooms to use |-
:: :: -
:: :: remove ship from every room
:: =. looms
:: |-
:: ?~ looms ~
:: =* loom i.looms
:: =? present.loom
:: %-
:: ~(has in present.loom)
:: ship
:: ::
:: (~(del in present.loom) ship)
:: ::
:: [loom $(looms t.looms)]
:: ::
:: :: turn the list back into a map
:: %- ~(gas by rooms)
:: |-
:: ?~ looms ~
:: :- [rid.i.looms i.looms]
:: $(looms t.looms)
::
::
:: welcome to the fun part
++ enjs
=, enjs:format
|%
++ action
|= act=^action
^- json
:: not used
::
*json
++ update
|= upd=^update
^- json
%+ frond %rooms-update
%- pairs
:_ ~
^- [cord json]
:- -.upd
?- -.upd
%room
%- pairs
:~
['room' (room:encode room.upd)]
['diff' (update-diff:encode diff.upd)]
==
%rooms
:- %a
%+ turn
~(tap in rooms.upd)
|= =room
(room:encode room)
%invited
%- pairs
:~
['provider' %s (scot %p provider.upd)]
['id' %s rid.upd]
['title' %s title.upd]
['invitedBy' %s (scot %p ship.upd)]
==
%kicked
%- pairs
:~
['provider' %s (scot %p provider.upd)]
['id' %s rid.upd]
['title' %s title.upd]
['kickedBy' %s (scot %p ship.upd)]
==
%chat
%- pairs
:~
['from' %s (scot %p from.upd)]
['content' %s content.upd]
==
==
++ view
|= viw=^view
^- json
%+ frond %rooms-view
%- pairs
:_ ~
:- -.viw
?- -.viw
%full
%- pairs
:~
:- %my-room
?~ my-room.viw ~
(room:encode u.my-room.viw)
:- %provider
?~ provider.viw ~
[%s (scot %p u.provider.viw)]
==
%present
(set-ship:encode ships.viw)
%whitelist
(set-ship:encode ships.viw)
%provider
(unit-ship:encode who.viw)
==
--
++ encode
=, enjs:format
|%
++ room
|= =^room
^- json
%- pairs
:~
['id' %s rid.room]
['provider' %s (scot %p provider.room)]
['creator' %s (scot %p creator.room)]
['access' %s access.room]
['title' %s title.room]
['capacity' (numb capacity.room)]
:- 'space'
:- %s
?~ space.room
''
u.space.room
['present' (set-ship present.room)]
['whitelist' (set-ship whitelist.room)]
==
++ update-diff
|= diff=^update-diff
^- json
%+ frond -.diff
?- -.diff
%enter
[%s (scot %p ship.diff)]
%exit
[%s (scot %p ship.diff)]
%other ~
==
++ set-ship
|= ships=(set @p)
^- json
:- %a
%+ turn
~(tap in ships)
|= her=@p
[%s (scot %p her)]
++ unit-ship
|= who=(unit @p)
^- json
?~ who
~
[%s (scot %p u.who)]
--
::
++ dejs
=, dejs:format
|%
++ update
|= jon=json
^- ^update
*^update
:: not used
++ action
|= jon=json
^- ^action
=< (decode jon)
|%
++ decode
%- of
:~ [%set-provider patp]
[%logout ul]
[%enter so]
[%exit ul]
[%create create]
[%set-title set-title]
[%set-access set-access]
[%set-capacity set-capacity]
[%set-space set-space]
[%invite invite]
[%kick kick]
[%delete so]
[%request so]
[%request-all ul]
[%chat so]
==
++ patp
(su ;~(pfix sig fed:ag))
:: ::
++ create
%- ot
:~ [%rid so]
[%access access]
[%title so]
:: [%enter bo]
==
++ set-title
%- ot
:~ [%rid so]
[%title so]
==
++ set-access
%- ot
:~ [%rid so]
[%access access]
==
++ set-capacity
%- ot
:~ [%rid so]
[%capacity ni]
==
++ set-space
%- ot
:~ [%rid so]
[%space so]
==
++ invite
%- ot
:~ [%rid so]
[%ship patp]
==
++ kick
%- ot
:~ [%rid so]
[%ship patp]
==
++ access
|= =json
^- ^access
?> ?=(%s -.json)
?: =('private' p.json)
%private
?: =('public' p.json)
%public
!!
--
--
--

87
lib/slip.hoon Normal file
View File

@ -0,0 +1,87 @@
/- sur=slip
=< [sur .]
=, sur
|%
++ agent %slip
::
:: welcome to the fun part
:: ;}
++ enjs
=, enjs:format
|%
++ action
|= act=^action
^- json
%+ frond %slip-action
%- pairs
:_ ~
^- [cord json]
:- -.act
?- -.act
%slip
%- pairs
:~
['from' %s (scot %p from.act)]
['time' (sect time.act)]
:- 'path'
:- %a
%+ turn path.act
|= tas=@tas
[%s tas]
['data' %s data.act]
==
%slop
%- pairs
:~
:- 'to'
:- %a
%+ turn to.act
|= her=@p
[%s (scot %p her)]
['time' (sect time.act)]
:- 'path'
:- %a
%+ turn path.act
|= tas=@tas
[%s tas]
['data' %s data.act]
==
==
--
::
++ dejs
=, dejs:format
|%
++ action
|= jon=json
^- ^action
=< (decode jon)
|%
++ decode
%- of
:~ [%slip slip]
[%slop slop]
==
++ patp
(su ;~(pfix sig fed:ag))
:: ::
++ slip
%- ot
:~
[%from patp]
[%time di]
[%path (ar so)]
[%data so]
==
++ slop
%- ot
:~
[%to (ar patp)]
[%time di]
[%path (ar so)]
[%data so]
==
--
--
--

151
lib/spaces-chat.hoon Normal file
View File

@ -0,0 +1,151 @@
/- sstore=spaces-store, mstore=membership, visas, chat-db
/- store=spaces-chat
/+ memb-lib=membership, rc-lib=realm-chat
=< [store .]
=, store
|%
++ init-spaces
|= [state=state-0:store =bowl:gall]
^- (quip card:agent:gall state-0)
?. =(0 (lent ~(key by chats.state))) `state
~& "{<dap.bowl>}: initializing..."
=/ spaces-scry .^(view:sstore %gx /(scot %p our.bowl)/spaces/(scot %da now.bowl)/all/noun)
?> ?=(%spaces -.spaces-scry)
=/ spaces spaces.spaces-scry
=/ to-add-chat=(list [k=space-path:sstore v=space:sstore])
%+ skim ~(tap by spaces)
|= kv=[k=space-path:sstore v=space:sstore]
&(=(ship.path.v.kv our.bowl) ?!(=(space.k.kv 'our')))
=/ new-chats
%+ turn to-add-chat
|= [sk=space-path:sstore sv=space:sstore]
=/ members-scry .^(view:mstore %gx /(scot %p our.bowl)/spaces/(scot %da now.bowl)/(scot %p ship.sk)/(scot %tas space.sk)/members/noun)
?> ?=(%members -.members-scry)
=/ members members.members-scry
=/ chat-and-cards (create-space-chat sv [%role %member] members now.bowl our.bowl)
=/ chat +.chat-and-cards
=/ cards
%+ weld
-.chat-and-cards
(create-channel-pokes sk chat members)
[k=sk c=chat cd=cards]
=/ cards
%+ roll new-chats
|= [[k=space-path:sstore c=chat:store cd=(list card:agent:gall)] acc=(list card:agent:gall)]
(weld acc cd)
=/ chats
%+ turn new-chats
|= [k=space-path:sstore c=chat:store cd=(list card:agent:gall)]
=/ chats-map `chats:store`~
=/ chats-map (~(put by chats-map) path.c c)
[k chats-map]
=. chats.state `space-chats:store`(malt chats)
[cards state]
::
++ pathify-space-path
|= =space-path:sstore
^- path
/(scot %p ship.space-path)/(wood space.space-path)
:: TODO make this smart enough to actually do different logic based on
:: the value of `chat-access`, instead of just always doing the logic
:: for [%role %member]
++ create-space-chat
|= [=space:sstore =chat-access:store =members:mstore t=@da our=ship]
^- (quip card:agent:gall chat:store)
~& %create-space-chat
:: spaces chats path format: /spaces/<space-path>/chats/<@uv>
=/ chat-path (weld /spaces (weld (pathify-space-path path.space) /chats/(scot %uv (sham path.space))))
=/ metadata-settings
:~ ['image' '']
['title' 'General']
['description' '']
['creator' (scot %p ship.path.space)]
['reactions' 'true']
['space' (spat (pathify-space-path path.space))]
==
=/ metadata=(map cord cord) (~(gas by *(map cord cord)) metadata-settings)
:: TODO when making new channels make sure we can disable chat history for new members or enable it
=/ pathrow=path-row:chat-db [chat-path metadata %space t t ~ %host %.y *@dr *@da ~]
=/ all-peers=ship-roles:chat-db
%+ turn (skim-init-members members)
|= kv=[k=ship v=member:mstore]
[k.kv ?:(=(status.v.kv %host) %host %member)]
:: TODO logic for peers lists for %admins %invited %whitelist and %blacklist
=/ new-chat [chat-path chat-access]
=/ cards=(list card:agent:gall) :: poke %chat-db to create the chat
:- (create-path-bedrock-poke:rc-lib our pathrow all-peers)
:- (create-chat-bedrock-poke:rc-lib our pathrow all-peers ~)
%+ turn all-peers
|= [s=ship role=@tas]
(create-path-db-poke:rc-lib s pathrow all-peers)
[cards new-chat]
:: matching members are status %joined or %host AND have
:: either %member or %admin or %owner roles
++ skim-init-members
|= =members:mstore
^- (list [ship member:mstore])
%+ skim ~(tap by members)
|= kv=[k=ship v=member:mstore]
?& |(=(status.v.kv %joined) =(status.v.kv %host))
?| (~(has in roles.v.kv) %member)
(~(has in roles.v.kv) %admin)
(~(has in roles.v.kv) %owner)
==
==
++ skim-joined-members
|= =members:mstore
^- (list [ship member:mstore])
%+ skim ~(tap by members)
|= kv=[k=ship v=member:mstore]
?& =(status.v.kv %joined)
?| (~(has in roles.v.kv) %member)
(~(has in roles.v.kv) %admin)
(~(has in roles.v.kv) %owner)
==
==
++ create-channel-pokes
|= [=space-path:sstore =chat:store =members:mstore]
^- (list card:agent:gall)
%+ turn (skim-joined-members members)
|= [s=ship v=member:mstore]
^- card:agent:gall
[%pass / %agent [s %spaces-chat] %poke %spaces-chat-action !>([%create-channel space-path chat])]
:: creates the necessary cards for poking %chat-db to add the new ship
:: to all the relevant chats it should be added to
++ add-ship-to-matching-chats
|= [=ship =member:mstore =space-path:store =chats:store =bowl:gall]
^- (list card:agent:gall)
%- zing
%+ turn
~(tap by chats)
|= kv=[k=path v=chat:store]
^- (list card:agent:gall)
?+ -.access.v.kv ~ :: TODO handle other modes of chat access
%role
?. &((~(has in roles.member) role.access.v.kv) |(=(%joined status.member) =(%host status.member))) ~
=/ pathpeers (scry-peers:rc-lib k.kv bowl)
=/ matches (skim pathpeers |=(p=peer-row:chat-db =(patp.p ship)))
?: (gth (lent matches) 0) ~ :: this ship is already in this chat, so no need to add them
:~
[%pass /rcpoke %agent [our.bowl %realm-chat] %poke %chat-action !>([%add-ship-to-chat *@da k.kv ship ~ ~])]
[%pass / %agent [ship %spaces-chat] %poke %spaces-chat-action !>([%create-channel space-path v.kv])]
==
==
:: :: creates the necessary cards for poking %chat-db to remove the new ship
:: :: to all chats within the space
++ remove-ship-from-space-chats
|= [=ship =chats:store =bowl:gall]
^- (list card:agent:gall)
%- zing
%+ turn
~(tap by chats)
|= kv=[k=path v=chat:store]
^- (list card:agent:gall)
[%pass /rcpoke %agent [our.bowl %realm-chat] %poke %chat-action !>([%remove-ship-from-chat k.kv ship])]~
--

387
lib/spaces.hoon Normal file
View File

@ -0,0 +1,387 @@
/- store=spaces-store, member-store=membership, visas
/+ memb-lib=membership
=< [store .]
=, store
|%
++ create-space
|= [=ship slug=@t payload=add-payload:store updated-at=@da]
^- space:store
=/ default-theme
[
mode=%light
background-color='#C4C3BF'
accent-color='#4E9EFD'
input-color='#FFFFFF'
dock-color='#FFFFFF'
icon-color='#CECECC'
text-color='#333333'
window-color='#FFFFFF'
wallpaper='https://images.unsplash.com/photo-1622547748225-3fc4abd2cca0?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=2832&q=100'
]
=/ new-space
[
path=[ship slug]
name=name:payload
description=description:payload
type=type:payload
access=access:payload
picture=picture:payload
color=color:payload
archetype=archetype:payload
theme=default-theme
updated-at=updated-at
]
new-space
::
:: json
::
++ enjs
=, enjs:format
|%
++ reaction
|= rct=^reaction
^- json
%- pairs
:_ ~
^- [cord json]
?- -.rct
%initial
:- %initial
%- pairs
:~ [%spaces (spaces-map:encode spaces.rct)]
[%membership (membership-map:encode membership.rct)]
[%invitations (invitations:encode invitations.rct)]
[%current (curr:encode current.rct)]
==
::
%add
:- %add
%- pairs
:~ [%space (spc:encode space.rct)]
[%members (membs:encode members.rct)]
==
::
%replace
:- %replace
%- pairs
:~ [%space (spc:encode space.rct)]
==
::
%remove
:- %remove
%- pairs
:~ [%space-path s+(spat /(scot %p ship.path.rct)/(wood space.path.rct))]
==
::
%remote-space
:- %remote-space
%- pairs
:~ [%path s+(spat /(scot %p ship.path.rct)/(wood space.path.rct))]
[%space (spc:encode space.rct)]
:: [%members (passes:encode:membership membership.rct)]
[%members (membs:encode members.rct)]
==
%current
:- %current
%- pairs
:~ [%path s+(spat /(scot %p ship.path.rct)/(wood space.path.rct))]
[%space s+space.path.rct]
==
:: %members
:: :- %members
:: %- pairs
:: :~ [%path s+(spat /(scot %p ship.path.rct)/(wood space.path.rct))]
:: [%members (membership-json:encode:memb-lib membership.rct)]
:: ==
==
::
++ view :: encodes for on-peek
|= vi=^view
^- json
%- pairs
:_ ~
^- [cord json]
:- -.vi
?- -.vi
::
%space
(spc:encode space.vi)
::
%spaces
(spaces-map:encode spaces.vi)
==
--
::
++ dejs
=, dejs:format
|%
++ action
|= jon=json
^- ^action
=< (decode jon)
|%
++ decode
%- of
:~ [%add add-space]
[%update update-space]
[%remove path-key]
[%join path-key]
[%leave path-key]
[%current path-key]
:: [%kicked kicked]
==
::
++ de-space
%- ot
:~ [%path pth]
[%name so]
[%type space-type]
[%access access]
[%picture so]
[%color so]
[%archetype archetype]
[%theme thm]
[%updated-at di]
==
::
++ add-space
%- ot
:~ [%slug so]
[%payload add-payload]
[%members (op ;~(pfix sig fed:ag) memb)]
==
::
++ update-space
%- ot
:~ [%path pth]
[%payload edit-payload]
==
::
++ kicked
%- ot
:~ [%path pth]
[%ship (su ;~(pfix sig fed:ag))]
==
::
++ path-key
%- ot
:~ [%path pth]
==
::
++ pth
%- ot
:~ [%ship (su ;~(pfix sig fed:ag))]
[%space so]
==
::
++ add-payload
%- ot
:~ [%name so]
[%description so]
[%type space-type]
[%access access]
[%picture so]
[%color so]
[%archetype archetype]
==
::
++ edit-payload
%- ot
:~ [%name so]
[%description so]
[%access (su (perk %public %private ~))]
[%picture so]
[%color so]
[%theme thm]
==
::
++ thm
%- ot
:~ [%mode theme-mode]
[%background-color so]
[%accent-color so]
[%input-color so]
[%dock-color so]
[%icon-color so]
[%text-color so]
[%window-color so]
[%wallpaper so]
==
::
++ memb
%- ot
:~ [%roles (as rol)]
[%alias so]
[%status status]
:: [%pinned bo]
==
::
++ theme-mode
|= =json
^- theme-mode:store
?> ?=(%s -.json)
?: =('light' p.json) %light
?: =('dark' p.json) %dark
!!
::
++ space-type
|= =json
^- space-type:store
?> ?=(%s -.json)
?: =('group' p.json) %group
?: =('our' p.json) %our
?: =('space' p.json) %space
!!
::
++ rol
|= =json
^- role:member-store
?> ?=(%s -.json)
?: =('initiate' p.json) %initiate
?: =('member' p.json) %member
?: =('admin' p.json) %admin
?: =('owner' p.json) %owner
!!
::
++ archetype
|= =json
^- archetype:store
?> ?=(%s -.json)
?: =('home' p.json) %home
?: =('community' p.json) %community
?: =('creator-dao' p.json) %creator-dao
?: =('service-dao' p.json) %service-dao
?: =('investment-dao' p.json) %investment-dao
!!
::
++ access
|= =json
^- space-access:store
?> ?=(%s -.json)
?: =('public' p.json) %public
?: =('antechamber' p.json) %antechamber
?: =('private' p.json) %private
!!
::
++ status
|= =json
^- status:member-store
?> ?=(%s -.json)
?: =('invited' p.json) %invited
?: =('joined' p.json) %joined
?: =('host' p.json) %host
!!
--
--
::
::
::
++ encode
=, enjs:format
|%
++ spaces-map
|= =spaces:store
^- json
%- pairs
%+ turn ~(tap by spaces)
|= [pth=space-path:store space=space:store]
=/ spc-path (spat /(scot %p ship.pth)/(wood space.pth))
^- [cord json]
[spc-path (spc space)]
::
++ membership-map
|= =membership:member-store
^- json
%- pairs
%+ turn ~(tap by membership)
|= [pth=space-path:store members=members:member-store]
=/ spc-path (spat /(scot %p ship.pth)/(wood space.pth))
^- [cord json]
[spc-path (membs members)]
::
++ membs
|= =members:member-store
^- json
%- pairs
%+ turn ~(tap by members)
|= [=^ship =member:member-store]
^- [cord json]
[(scot %p ship) (memb member)]
::
++ memb
|= =member:member-store
^- json
%- pairs
:~ ['roles' a+(turn ~(tap in roles.member) |=(rol=role:member-store s+(scot %tas rol)))]
['status' s+(scot %tas status.member)]
:: ['pinned' b+pinned.member]
==
++ curr
|= current=space-path:store
^- json
%- pairs
:~ ['path' s+(spat /(scot %p ship.current)/(wood space.current))]
['space' s+space.current]
==
::
++ spc
|= =space
^- json
%- pairs
:~ ['path' s+(spat /(scot %p ship.path.space)/(wood space.path.space))]
['name' s+name.space]
['description' s+description.space]
['access' s+access.space]
['type' s+type.space]
['picture' s+picture.space]
['color' s+color.space]
['theme' (thm theme.space)]
['updatedAt' (time updated-at.space)]
==
::
++ thm
|= =theme
^- json
%- pairs
:~
['mode' s+(scot %tas mode.theme)]
['backgroundColor' s+background-color.theme]
['accentColor' s+accent-color.theme]
['inputColor' s+input-color.theme]
['dockColor' s+dock-color.theme]
['iconColor' s+icon-color.theme]
['textColor' s+text-color.theme]
['windowColor' s+window-color.theme]
['wallpaper' s+wallpaper.theme]
==
::
++ invitations
|= =invitations:visas
^- json
%- pairs
%+ turn ~(tap by invitations)
|= [pth=space-path:store inv=invite:visas]
=/ spc-path (spat /(scot %p ship.pth)/(wood space.pth))
^- [cord json]
[spc-path (invite inv)]
::
++ invite
|= =invite:visas
^- json
%- pairs:enjs:format
:~ ['inviter' s+(scot %p inviter.invite)]
['path' s+(spat /(scot %p ship.path.invite)/(wood space.path.invite))]
['role' s+(scot %tas role.invite)]
['message' s+message.invite]
['name' s+name.invite]
['type' s+type.invite]
['picture' s+picture.invite]
['color' s+color.invite]
['invitedAt' (time invited-at.invite)]
==
::
--
--

321
lib/trove-json.hoon Normal file
View File

@ -0,0 +1,321 @@
/- *trove
|%
++ enjs
=, enjs:format
|%
++ enjs-ship |=(p=@p `json`((lead %s) (scot %p p)))
::
++ enta-trail
|=(t=trail =+(p=(path t) ?>(?=([%s *] p) p.p)))
::
++ enta-space
|=(s=space `@t`(rap 3 (scot %p -.s) '/' +.s ~))
::
++ enta-tope
|=(t=space `@t`(rap 3 (scot %p -.t) '/' +.t ~))
::
++ enjs-node
|= n=node
^- json
(pairs ~[type+s/'record' url+s/url.n dat+(enjs-data dat.n)])
::
++ enjs-tract
|= tat=tract
^- json
%- pairs
:~ from+(sect from.tat)
by+(ship by.tat)
:- %files
=- o/(malt -)
%+ turn ~(tap by +.tat)
|= [k=@uv v=node]
[(scot %uv k) `json`(enjs-node v)]
==
::
++ enjs-trove
|= axe=(axal tract)
^- json
=- o/(malt -)
^- (list [@t json])
%+ turn ~(tap by ~(tar of axe))
|= [k=trail v=tract]
[(enta-trail k) (enjs-tract v)]
::
++ enjs-troves
|= =troves
^- json
%- pairs
%+ turn ~(tap by troves)
|= [=tope trove-data]
^- [@t json]
:- (enta-tope tope)
%- pairs
:~ name+s/name
perms+(enjs-perms perms)
trove+(enjs-trove trove)
==
::
++ enjs-hoard
|= hoard=(map space [=banned =troves])
^- json
%- pairs
%+ turn ~(tap by hoard)
|= [=space =banned =troves]
^- [@t json]
:- (enta-space space)
%- pairs
:~ banned+a/(turn ~(tap in banned) enjs-ship)
troves+(enjs-troves troves)
==
::
++ enjs-perms
|= =perms
^- json
%- pairs
:~ admins+s/admins.perms
member+?~(m=member.perms ~ s/m)
:- %custom
%- pairs
%+ turn ~(tap by custom.perms)
|= [=^ship r=?(%r %rw)]
^- [@t json]
[(scot %p ship) s/r]
==
::
++ enjs-data
|= dat=fimet
^- json
%- pairs
:~ from+(sect from.dat)
by+(ship by.dat)
title+s/title.dat
description+s/description.dat
extension+s/extension.dat
size+s/size.dat
key+s/key.dat
==
::
++ enjs-view
|= =view
^- json
%+ frond %view
%+ frond -.view
?- -.view
%hoard (enjs-hoard hoard.view)
%troves (enjs-troves troves.view)
%trove (enjs-trove trove.view)
==
::
++ enjs-space-action
|= axn=space-action:action
^- json
%+ frond -.axn
?- -.axn
%add-trove
%- pairs
:~ name+s/name.axn
perms+(enjs-perms perms.axn)
==
%rem-trove
%- frond
tope+s/(enta-tope tope.axn)
%banned
%+ frond %banned
a/(turn ~(tap in banned.axn) enjs-ship)
==
::
++ enjs-trove-action
|= axn=trove-action:action
^- json
%+ frond -.axn
?+ -.axn !!
%reperm
(frond perms+(enjs-perms perms.axn))
%edit-name
(frond name+s/name.axn)
%add-folder
(frond trail+s/(enta-trail trail.axn))
%rem-folder
(frond trail+s/(enta-trail trail.axn))
%move-folder
%- pairs
:~ from+s/(enta-trail from.axn)
to+s/(enta-trail to.axn)
==
%rem-node
%- pairs
:~ trail+s/(enta-trail trail.axn)
id+s/(scot %uv id.axn)
==
%edit-node
%- pairs
:~ trail+s/(enta-trail trail.axn)
id+s/(scot %uv id.axn)
title+?~(tut.axn ~ s/u.tut.axn)
description+?~(dus.axn ~ s/u.dus.axn)
==
%move-node
%- pairs
:~ from+s/(enta-trail from.axn)
id+s/(scot %uv id.axn)
to+s/(enta-trail to.axn)
==
==
::
++ enjs-update
|= upd=update
^- json
?- -.upd
%initial (frond %initial (enjs-hoard hoard.upd))
::
%space
%- pairs
:~ space+s/(enta-space space.upd)
:- %update
?+ +>-.upd (enjs-space-action +>.upd)
%add-trove
%+ frond %add-trove
%- pairs
:~ tope+s/(enta-tope tope.upd)
name+s/name.upd
perms+(enjs-perms perms.upd)
trove+(enjs-trove trove.upd)
==
%add-troves
%+ frond %add-troves
%- pairs
:~ banned+a/(turn ~(tap in banned.upd) enjs-ship)
troves+(enjs-troves troves.upd)
==
%rem-troves
[%s %rem-troves]
==
==
::
%trove
%- pairs
:~ space+s/(enta-space space.upd)
tope+s/(enta-tope tope.upd)
:- %update
?+ +>-.upd (enjs-trove-action +>.upd)
%add-node
%+ frond %add-node
%- pairs
:~ trail+s/(enta-trail trail.upd)
id+s/(scot %uv id.upd)
node+(enjs-node node.upd)
==
::
%add-folder
%+ frond %add-folder
%- pairs
:~ trail+s/(enta-trail trail.upd)
tract+(enjs-tract tract.upd)
==
==
==
==
--
++ dejs
=, dejs:format
|%
++ space-rule
;~ (glue fas)
;~(pfix sig fed:ag)
(cook crip (star prn))
==
++ tope-rule space-rule
++ rw-rule
|= jon=json
=/ r ((su ;~(pose (jest %rw) (jest %r))) jon)
?>(?=(?(%r %rw) r) r)
::
++ custom-perms
|= jon=json
^- (map ship ?(%r %rw))
%- ~(gas by *(map ship ?(%r %rw)))
%+ turn
%~ tap by
((om (su ;~(pose (jest %rw) (jest %r)))) jon)
|= [s=@t r=@t]
^- [ship ?(%r %rw)]
?> ?=(?(%r %rw) r)
[(slav %p s) r]
::
++ dejs-perms
^- $-(json perms)
%- ot
:~ admins+rw-rule
member+|=(jon=json ?~(jon ~ (rw-rule jon)))
custom+custom-perms
==
::
++ dejs-fimet
^- $-(json fimet)
%- ot
:~ from+du
by+(se %p)
title+so
description+so
extension+so
size+so
key+so
==
::
++ dejs-node
^- $-(json node)
(ot ~[url+so dat+dejs-fimet])
::
++ space-action
^- $-(json space-action:action)
%- of
:~ :- %add-trove
%- ot
:~ name+so
perms+dejs-perms
==
rem-trove+(ot [tope+(su tope-rule)]~)
banned+(ot [banned+(as (su fed:ag))]~)
==
::
++ trove-action
^- $-(json trove-action:action)
%- of
:~ reperm+(ot ~[perms+dejs-perms])
edit-name+(ot ~[name+so])
add-folder+(ot ~[trail+pa])
rem-folder+(ot ~[trail+pa])
move-folder+(ot ~[from+pa to+pa])
:- %add-node
%- ot
:~ trail+pa
url+so
title+so
description+so
extension+so
size+so
key+so
==
rem-node+(ot ~[trail+pa id+(se %uv)])
:- %edit-node
%- ot
:~ trail+pa
id+(se %uv)
tut+so:dejs-soft:format
dus+so:dejs-soft:format
==
move-node+(ot ~[from+pa id+(se %uv) to+pa])
==
::
++ dejs-action
^- $-(json action)
%- of
:~ space+(ot ~[space+(su space-rule) axn+space-action])
:- %trove
%- ot
:~ st+(ot ~[space+(su space-rule) tope+(su tope-rule)])
axn+trove-action
==
==
--
--

341
lib/visas.hoon Normal file
View File

@ -0,0 +1,341 @@
/- store=visas, spaces-store, member-store=membership
/+ spaces-lib=spaces
=< [store .]
=, store
|%
++ new-visa
|= [path=space-path:spaces-store inviter=ship =ship =role:membership =space:spaces-store message=@t invited-at=@da]
^- invite:store
=/ new-invite
[
inviter=inviter
path=path
role=role
message=message
name=name:space
type=type:space
picture=picture:space
color=color:space
invited-at=invited-at
]
new-invite
::
:: json
::
++ enjs
=, enjs:format
|%
++ action
|= act=^action
^- json
%+ frond %invite-action
%- pairs
:_ ~
^- [cord json]
?- -.act
%send-invite
:- %send-invite
%- pairs
:~ [%path s+(spat /(scot %p ship.path.act)/(scot %tas space.path.act))]
[%ship s+(scot %p ship.act)]
[%role s+(scot %tas role.act)]
[%message s+message.act]
==
::
%invited
:- %invited
%- pairs
:~ [%path s+(spat /(scot %p ship.path.act)/(scot %tas space.path.act))]
[%invite (invite:encode invite.act)]
==
::
%accept-invite
:- %accept-invite
%- pairs
:~ [%path s+(spat /(scot %p ship.path.act)/(scot %tas space.path.act))]
==
%decline-invite
:- %accept-invite
%- pairs
:~ [%path s+(spat /(scot %p ship.path.act)/(scot %tas space.path.act))]
==
::
%stamped
:- %stamped
%- pairs
:~ [%path s+(spat /(scot %p ship.path.act)/(scot %tas space.path.act))]
==
::
%kick-member
:- %kick-member
%- pairs
:~ [%path s+(spat /(scot %p ship.path.act)/(scot %tas space.path.act))]
[%ship s+(scot %p ship.act)]
==
%group-kick-member
:- %group-kick-member
%- pairs
:~ [%path s+(spat /(scot %p ship.path.act)/(scot %tas space.path.act))]
[%ship s+(scot %p ship.act)]
==
%revoke-invite
:- %revoke-invite
%- pairs
:~ [%path s+(spat /(scot %p ship.path.act)/(scot %tas space.path.act))]
==
%edit-member-role
:- %edit-member-role
%- pairs
:~ [%path s+(spat /(scot %p ship.path.act)/(scot %tas space.path.act))]
[%ship s+(scot %p ship.act)]
:- %roles
:- %a
^- (list json)
%+ turn ~(tap in role-set.act)
|= =role:membership
s+(scot %tas role)
==
==
::
++ reaction
|= rct=^reaction
^- json
%+ frond %visa-reaction
%- pairs
:_ ~
^- [cord json]
?- -.rct
%invite-sent
:- %invite-sent
%- pairs
:~ [%path s+(spat /(scot %p ship.path.rct)/(scot %tas space.path.rct))]
[%ship s+(scot %p ship.rct)]
[%invite (invite:encode invite.rct)]
[%member (memb:encode member.rct)]
==
::
%invite-received
:- %invite-received
%- pairs
:~ [%path s+(spat /(scot %p ship.path.rct)/(scot %tas space.path.rct))]
[%invite (invite:encode invite.rct)]
==
::
%invite-removed
:- %invite-removed
%- pairs
[%path s+(spat /(scot %p ship.path.rct)/(scot %tas space.path.rct))]~
::
%invite-accepted
:- %invite-accepted
%- pairs
:~ [%path s+(spat /(scot %p ship.path.rct)/(scot %tas space.path.rct))]
[%ship s+(scot %p ship.rct)]
[%member (memb:encode member.rct)]
==
::
%kicked
:- %kicked
%- pairs
:~ [%path s+(spat /(scot %p ship.path.rct)/(scot %tas space.path.rct))]
[%ship s+(scot %p ship.rct)]
==
::
%edited
:- %edited
%- pairs
:~ [%path s+(spat /(scot %p ship.path.rct)/(scot %tas space.path.rct))]
[%ship s+(scot %p ship.rct)]
:- %roles
:- %a
^- (list json)
%+ turn ~(tap in role-set.rct)
|= =role:membership
s+(scot %tas role)
==
==
::
::
++ view
|= view=^view
^- json
%- pairs
:_ ~
^- [cord json]
?- -.view
%invitations
[%invitations (invitations:encode invites.view)]
::
:: %incoming
:: [%invites (incoming-map:encode invites.view)]
::
==
--
::
++ encode
=, enjs:format
|%
++ invitations
|= =invitations:store
^- json
%- pairs
%+ turn ~(tap by invitations)
|= [pth=space-path:spaces-store inv=invite:store]
=/ spc-path (spat /(scot %p ship.pth)/(scot %tas space.pth))
^- [cord json]
[spc-path (invite inv)]
:: ++ outgoing-map
:: |= outgoing=outgoing-invitations:store
:: ^- json
:: %- pairs
:: %+ turn ~(tap by outgoing)
:: |= [pth=space-path:spaces-store invitations=space-invitations:store]
:: =/ spc-path (spat /(scot %p ship.pth)/(scot %tas space.pth))
:: ^- [cord json]
:: [spc-path (invite-map invitations)]
::
:: ++ incoming-map
:: |= incoming=incoming-invitations:store
:: ^- json
:: %- pairs
:: %+ turn ~(tap by incoming)
:: |= [pth=space-path:spaces-store inv=invite:store]
:: =/ spc-path (spat /(scot %p ship.pth)/(scot %tas space.pth))
:: ^- [cord json]
:: [spc-path (invite inv)]
::
:: ++ invite-map
:: |= =space-invitations:store
:: ^- json
:: %- pairs
:: %+ turn ~(tap by space-invitations)
:: |= [=^ship inv=invite:store]
:: ^- [cord json]
:: [(scot %p ship) (invite inv)]
::
++ invite
|= =invite:store
^- json
%- pairs:enjs:format
:~ ['inviter' s+(scot %p inviter.invite)]
['path' s+(spat /(scot %p ship.path.invite)/(scot %tas space.path.invite))]
['role' s+(scot %tas role.invite)]
['message' s+message.invite]
['name' s+name.invite]
['type' s+type.invite]
['picture' s+picture.invite]
['color' s+color.invite]
['invitedAt' (time invited-at.invite)]
==
::
++ memb
|= =member:member-store
^- json
%- pairs:enjs:format
:~ ['roles' a+(turn ~(tap in roles.member) |=(rol=role:member-store s+(scot %tas rol)))]
['alias' s+alias.member]
['status' s+(scot %tas status.member)]
==
::
--
::
++ dejs
=, dejs:format
|%
++ action
|= jon=json
^- action:store
=< (decode jon)
|%
++ decode
%- of
:~ [%send-invite send-invite-payload]
[%accept-invite accept-invite-payload]
[%decline-invite accept-invite-payload]
[%invited invited-payload]
[%stamped path-payload]
[%kick-member kicked-payload]
[%revoke-invite path-payload]
[%edit-member-role edit-member-role-payload]
==
::
++ kicked-payload
%- ot
:~ [%path pth]
[%ship (su ;~(pfix sig fed:ag))]
==
::
::
++ path-payload
%- ot
:~ [%path pth]
==
::
++ accept-invite-payload
%- ot
:~ [%path pth]
==
::
++ invited-payload
%- ot
:~ [%path pth]
[%invite invite]
==
::
++ invite
%- ot
:~ [%inviter (su ;~(pfix sig fed:ag))]
[%path pth]
[%role rol]
[%message so]
[%name so]
[%type space-type:action:dejs:spaces-lib]
[%picture so]
[%color so]
[%invited-at di]
==
::
++ send-invite-payload
%- ot
:~ [%path pth]
[%ship (su ;~(pfix sig fed:ag))]
[%role rol]
[%message so]
==
::
++ pth
%- ot
:~ [%ship (su ;~(pfix sig fed:ag))]
[%space so]
==
::
++ rol
|= =json
^- role:member-store
?> ?=(%s -.json)
?: =('initiate' p.json) %initiate
?: =('member' p.json) %member
?: =('admin' p.json) %admin
?: =('owner' p.json) %owner
!!
::
++ status
|= =json
^- status:member-store
?> ?=(%s -.json)
?: =('invited' p.json) %invited
?: =('joined' p.json) %joined
?: =('host' p.json) %host
!!
::
++ edit-member-role-payload
%- ot
:~ [%path pth]
[%ship (su ;~(pfix sig fed:ag))]
:: expects an array of roles
[%roles (as rol)]
==
--
--
::
--

14
mar/acme/order.hoon Normal file
View File

@ -0,0 +1,14 @@
::
:::: /mar/acme/order/hoon
::
|_ a=(set (list @t))
++ grad %noun
++ grow
|%
++ noun a
--
++ grab
|%
++ noun (set (list @t))
--
--

18
mar/api-store/action.hoon Normal file
View File

@ -0,0 +1,18 @@
/- api-store
:: /+ lib=api-store
::
|_ act=action:api-store
++ grad %noun
++ grow
|%
++ noun act
:: ++ json (action:enjs act)
--
::
++ grab
|%
++ noun action:api-store
:: ++ json action:dejs:lib
--
--

View File

@ -0,0 +1,26 @@
/- api-store
:: /+ lib=api-store
::
|_ =store-conf:api-store
++ grad %noun
++ grow
|%
++ noun store-conf
++ json
%-
|= creds=store-conf:api-store
^- ^json
%- pairs:enjs:format
:~ ['buckets' a+(turn ~(tap in buckets.creds) |=(t=@t s+t))]
['currentBucket' s+current-bucket.creds]
['region' s+region.creds]
==
store-conf
--
::
++ grab
|%
++ noun store-conf:api-store
--
--

View File

@ -0,0 +1,23 @@
/- api-store
:: /+ lib=api-store
::
|_ creds=store-results:api-store
++ grad %noun
++ grow
|%
++ noun creds
++ json
^- ^json
%- pairs:enjs:format
:~ ['endpoint' s+endpoint.creds]
['accessKeyId' s+access-key-id.creds]
['secretAccessKey' s+secret-access-key.creds]
==
--
::
++ grab
|%
++ noun store-results:api-store
--
--

12
mar/aqua/effect.hoon Normal file
View File

@ -0,0 +1,12 @@
/- *aquarium
|_ af=aqua-effect
++ grad %noun
++ grow
|%
++ noun af
--
++ grab
|%
++ noun aqua-effect
--
--

18
mar/atom.hoon Normal file
View File

@ -0,0 +1,18 @@
::
:::: /hoon/atom/mar
::
/? 310
::
:::: A minimal atom mark
::
=, mimes:html
|_ ato=@
++ grab |%
++ noun @
++ mime |=([* p=octs] q.p)
--
++ grow |%
++ mime [/application/x-urb-unknown (as-octs ato)]
--
++ grad %mime
--

20
mar/azimuth/snapshot.hoon Normal file
View File

@ -0,0 +1,20 @@
:: /app/azimuth state snapshot
::
/- *dice
::
|_ snap=snap-state
++ grab
|%
++ noun snap-state
++ mime
|= [mite =octs]
(noun (cue q.octs))
--
::
++ grow
|%
++ mime
[/application/octet-stream (as-octs:mimes:html (jam snap))]
--
++ grad %mime
--

14
mar/azimuth/update.hoon Normal file
View File

@ -0,0 +1,14 @@
/+ azimuth
::
|_ upd=update:azimuth
::
++ grad %noun
++ grow
|%
++ noun upd
--
++ grab :: convert from
|%
++ noun update:azimuth :: from %noun
--
--

16
mar/bazaar/action.hoon Normal file
View File

@ -0,0 +1,16 @@
/+ *bazaar
::
|_ act=action
++ grad %noun
++ grow
|%
++ noun act
++ json (action:enjs act)
--
::
++ grab
|%
++ noun action
++ json action:dejs
--
--

View File

@ -0,0 +1,14 @@
/+ *bazaar
::
|_ act=interaction
++ grad %noun
++ grow
|%
++ noun act
--
::
++ grab
|%
++ noun interaction
--
--

15
mar/bazaar/reaction.hoon Normal file
View File

@ -0,0 +1,15 @@
/+ *bazaar
::
|_ rct=reaction
++ grad %noun
++ grow
|%
++ noun rct
++ json (reaction:enjs rct)
--
::
++ grab
|%
++ noun reaction
--
--

16
mar/bazaar/view.hoon Normal file
View File

@ -0,0 +1,16 @@
/- store=bazaar-store
/+ *bazaar
::
|_ vi=view:store
++ grad %noun
++ grow
|%
++ noun vi
++ json (view:enjs vi)
--
::
++ grab
|%
++ noun view:store
--
--

20
mar/belt.hoon Normal file
View File

@ -0,0 +1,20 @@
:: belt: runtime belt structure
::
/+ dill
::
|_ =belt:dill
++ grad %noun
:: +grab: convert from
::
++ grab
|%
++ noun belt:dill
++ json belt:dejs:dill
--
:: +grow: convert to
::
++ grow
|%
++ noun belt
--
--

34
mar/bill.hoon Normal file
View File

@ -0,0 +1,34 @@
|_ bil=(list dude:gall)
++ grow
|%
++ mime `^mime`[/text/x-bill (as-octs:mimes:html hoon)]
++ noun bil
++ hoon
^- @t
|^ (crip (of-wall:format (wrap-lines (spit-duz bil))))
::
++ wrap-lines
|= taz=wall
^- wall
?~ taz ["~"]~
:- (weld ":~ " i.taz)
%- snoc :_ "=="
(turn t.taz |=(t=tape (weld " " t)))
::
++ spit-duz
|= duz=(list dude:gall)
^- wall
(turn duz |=(=dude:gall ['%' (trip dude)]))
--
++ txt (to-wain:format hoon)
--
++ grab
|%
++ noun (list dude:gall)
++ mime
|= [=mite len=@ud tex=@]
~_ tex
!<((list dude:gall) (slap !>(~) (ream tex)))
--
++ grad %noun
--

20
mar/blit.hoon Normal file
View File

@ -0,0 +1,20 @@
:: blit: runtime blit structure
::
/+ dill
::
|_ =blit:dill
++ grad %noun
:: +grab: convert from
::
++ grab
|%
++ noun blit:dill
--
:: +grow: convert to
::
++ grow
|%
++ noun blit
++ json (blit:enjs:dill blit)
--
--

16
mar/bulletin/action.hoon Normal file
View File

@ -0,0 +1,16 @@
/+ *bulletin
::
|_ act=action
++ grad %noun
++ grow
|%
++ noun act
++ json (action:enjs act)
--
::
++ grab
|%
++ noun action:store
++ json action:dejs
--
--

View File

@ -0,0 +1,16 @@
/- store=bulletin
/+ *bulletin
::
|_ rct=reaction:store
++ grad %noun
++ grow
|%
++ noun rct
++ json (reaction:enjs rct)
--
::
++ grab
|%
++ noun reaction:store
--
--

16
mar/chat-vent.hoon Normal file
View File

@ -0,0 +1,16 @@
/- sur=chat-db
/+ lib=chat-db
::
|_ =chat-vent:sur
++ grad %noun
++ grow
|%
++ noun chat-vent
++ json (en-vent:encode:lib chat-vent)
--
::
++ grab
|%
++ noun chat-vent:sur
--
--

16
mar/chat/action.hoon Normal file
View File

@ -0,0 +1,16 @@
/+ *realm-chat
::
|_ act=action
++ grad %noun
++ grow
|%
++ noun act
:: ++ json (action:enjs act)
--
::
++ grab
|%
++ noun action
++ json action:dejs
--
--

17
mar/chat/db-action.hoon Normal file
View File

@ -0,0 +1,17 @@
/- chat-db
/+ db-lib=chat-db
::
|_ act=action:chat-db
++ grad %noun
++ grow
|%
++ noun act
--
::
++ grab
|%
++ noun action:chat-db
++ json action:dejs:db-lib
--
--

16
mar/chat/db-change.hoon Normal file
View File

@ -0,0 +1,16 @@
/- chat-db
/+ db-lib=chat-db
::
|_ db=db-change:chat-db
++ grad %noun
++ grow
|%
++ noun db
++ json (db-change:enjs:db-lib db)
--
::
++ grab
|%
++ noun db-change:chat-db
--
--

16
mar/chat/db-dump.hoon Normal file
View File

@ -0,0 +1,16 @@
/- chat-db
/+ db-lib=chat-db
::
|_ db=db-dump:chat-db
++ grad %noun
++ grow
|%
++ noun db
++ json (db-dump:enjs:db-lib db)
--
::
++ grab
|%
++ noun db-dump:chat-db
--
--

18
mar/chat/db-message.hoon Normal file
View File

@ -0,0 +1,18 @@
/- sur=chat-db
/+ db-lib=chat-db
::
|_ m=message:sur
++ grad %noun
++ grow
|%
++ noun m
++ json
a+(turn m |=(mp=msg-part:sur (messages-row:encode:db-lib [msg-id.mp msg-part-id.mp] mp)))
--
::
++ grab
|%
++ noun message:sur
--
--

16
mar/chat/del-log.hoon Normal file
View File

@ -0,0 +1,16 @@
/- sur=chat-db
/+ db-lib=chat-db
::
|_ log=del-log:sur
++ grad %noun
++ grow
|%
++ noun log
++ json (del-log:encode:db-lib log)
--
::
++ grab
|%
++ noun del-log:sur
--
--

View File

@ -0,0 +1,16 @@
/- sur=chat-db
/+ db-lib=chat-db
::
|_ tbl=messages-table:sur
++ grad %noun
++ grow
|%
++ noun tbl
++ json (messages-table:enjs:db-lib tbl)
--
::
++ grab
|%
++ noun messages-table:sur
--
--

16
mar/chat/mutes.hoon Normal file
View File

@ -0,0 +1,16 @@
/- sur=realm-chat
/+ lib=realm-chat
::
|_ =mutes:sur
++ grad %noun
++ grow
|%
++ noun mutes
++ json (paths:encode:lib mutes)
--
::
++ grab
|%
++ noun mutes:sur
--
--

16
mar/chat/path-row.hoon Normal file
View File

@ -0,0 +1,16 @@
/- sur=chat-db
/+ db-lib=chat-db
::
|_ r=path-row:sur
++ grad %noun
++ grow
|%
++ noun r
++ json (path-row:enjs:db-lib r)
--
::
++ grab
|%
++ noun path-row:sur
--
--

16
mar/chat/pins.hoon Normal file
View File

@ -0,0 +1,16 @@
/- sur=realm-chat
/+ lib=realm-chat
::
|_ =pins:sur
++ grad %noun
++ grow
|%
++ noun pins
++ json (paths:encode:lib pins)
--
::
++ grab
|%
++ noun pins:sur
--
--

16
mar/chat/settings.hoon Normal file
View File

@ -0,0 +1,16 @@
/- sur=realm-chat
/+ lib=realm-chat
::
|_ s=[push-enabled=? msg-preview-notif=?]
++ grad %noun
++ grow
|%
++ noun s
++ json (settings:encode:lib s)
--
::
++ grab
|%
++ noun [push-enabled=? msg-preview-notif=?]
--
--

17
mar/contact-update-0.hoon Normal file
View File

@ -0,0 +1,17 @@
/+ *contact-store
::
|_ upd=update
++ grad %noun
++ grow
|%
++ noun upd
++ contact-update upd
++ json (update:enjs upd)
--
::
++ grab
|%
++ noun update
++ json update:dejs
--
--

View File

@ -0,0 +1,2 @@
/= mark /mar/flag
mark

View File

@ -0,0 +1,2 @@
/= mark /mar/flag
mark

15
mar/contact/share.hoon Normal file
View File

@ -0,0 +1,15 @@
/+ *contact-store
::
|_ share=[%share =ship]
++ grad %noun
++ grow
|%
++ noun share
--
::
++ grab
|%
+$ noun [%share ship]
++ json share:share-dejs
--
--

View File

@ -0,0 +1,2 @@
/= mark /mar/ship
mark

View File

@ -0,0 +1,2 @@
/= mark /mar/ship
mark

17
mar/contact/update-0.hoon Normal file
View File

@ -0,0 +1,17 @@
/+ *contact-store
::
|_ upd=update
++ grad %noun
++ grow
|%
++ noun upd
++ contact-update upd
++ json (update:enjs upd)
--
::
++ grab
|%
++ noun update
++ json update:dejs
--
--

17
mar/contact/update.hoon Normal file
View File

@ -0,0 +1,17 @@
/+ *contact-store
::
|_ upd=update
++ grad %noun
++ grow
|%
++ noun upd
++ contact-update-0 upd
++ json (update:enjs upd)
--
::
++ grab
|%
++ noun update
++ json update:dejs
--
--

25
mar/css.hoon Normal file
View File

@ -0,0 +1,25 @@
::
:::: /hoon/css/mar
::
/? 310
=, eyre
=, mimes:html
|_ mud=@t
++ grow :: convert to
|%
++ mime [/text/css (as-octs mud)] :: convert to %mime
++ hymn :: convert to %hymn
|^ html
++ style ;style
;- (trip mud)
==
++ html ;html:(head:"{style}" body)
--
--
++ grab
|% :: convert from
++ mime |=([p=mite q=octs] (@t q.q))
++ noun @t :: clam from %noun
--
++ grad %mime
--

18
mar/db/action.hoon Normal file
View File

@ -0,0 +1,18 @@
/- db
/+ lib=db
::
|_ act=action:db
++ grad %noun
++ grow
|%
++ noun act
:: ++ json (action:enjs act)
--
::
++ grab
|%
++ noun action:db
++ json action:dejs:lib
--
--

16
mar/db/changes.hoon Normal file
View File

@ -0,0 +1,16 @@
/- sur=db
/+ lib=db
::
|_ changes=db-changes:sur
++ grad %noun
++ grow
|%
++ noun changes
++ json (en-db-changes:enjs:lib changes)
--
::
++ grab
|%
++ noun db-changes:sur
--
--

16
mar/db/path.hoon Normal file
View File

@ -0,0 +1,16 @@
/- sur=db
/+ lib=db
::
|_ p=fullpath:sur
++ grad %noun
++ grow
|%
++ noun p
++ json (en-fullpath:enjs:lib p)
--
::
++ grab
|%
++ noun fullpath:sur
--
--

17
mar/db/row.hoon Normal file
View File

@ -0,0 +1,17 @@
/- sur=db, common
/+ lib=db
::
|_ r=[=row:sur =schemas:sur]
++ grad %noun
++ grow
|%
++ noun r
++ json (en-row:enjs:lib row.r schemas.r)
--
::
++ grab
|%
++ noun [=row:sur =schemas:sur]
--
--

16
mar/db/state.hoon Normal file
View File

@ -0,0 +1,16 @@
/- sur=db
/+ lib=db
::
|_ st=versioned-state:sur
++ grad %noun
++ grow
|%
++ noun st
++ json (state:enjs:lib st)
--
::
++ grab
|%
++ noun versioned-state:sur
--
--

17
mar/db/table.hoon Normal file
View File

@ -0,0 +1,17 @@
/- sur=db, common
/+ lib=db
::
|_ tbl=[=type:common pt=pathed-table:sur =schemas:sur]
++ grad %noun
++ grow
|%
++ noun tbl
++ json (en-table:enjs:lib type.tbl pt.tbl schemas.tbl)
--
::
++ grab
|%
++ noun [=type:common pt=pathed-table:sur =schemas:sur]
--
--

16
mar/db/vent.hoon Normal file
View File

@ -0,0 +1,16 @@
/- sur=db
/+ lib=db
::
|_ =vent:sur
++ grad %noun
++ grow
|%
++ noun vent
++ json (en-vent:enjs:lib vent)
--
::
++ grab
|%
++ noun vent:sur
--
--

65
mar/dill/belt.hoon Normal file
View File

@ -0,0 +1,65 @@
::
:::: /hoon/belt/dill/mar
::
/? 310
/- kyev, sole
::
::::
::
=, sole
|_ dill-belt:dill
::
++ grad %noun
++ grow
|%
++ noun +<.grow
--
++ grab :: convert from
|%
++ json
=< (cork . kyev)
|= jon=^json ^- ^kyev
!!
:: %- need
:: %. jon => jo %- ot
:: :~ mod+(cu silt (ar (su (perk ~[%ctrl %shift %alt %meta]))))
:: :- %key
:: %+ cu |*(a=$%([%str @t] [%act @]) ?+(-.a a %str +.a))
:: =- (of [str+so act+(su (perk -)) ~])
:: :~ %ctrl %shift %alt %meta %entr %esc %caps %uncap
:: %pgup %pgdn %home %end %baxp %del %ins
:: %up %down %left %right
:: == ==
++ kyev
|= kev=^kyev ^- dill-belt:dill
~| dill-belt-incomplete+kev
?: ?=([%act ?(%ctrl %shift %alt %meta)] q.kev)
[%txt ~] :: ignore
=+ mod=(~(del in p.kev) %shift)
?^ mod
?^ q.kev !! :: only accept strings
=. q.kev
?. (~(has in p.kev) %ctrl)
q.kev
(con 96 q.kev) :: ctrl key decoding
=+ cha=(tuba (trip q.kev))
?> ?=([@ ~] cha) :: of a single character
?+ mod !! :: modified by one buckykey
[%ctrl ~ ~] [%mod %ctl i.cha]
[%alt ~ ~] [%mod %met i.cha]
==
?@ q.kev
[%txt (tuba (trip q.kev))]
?+ +.q.kev !!
%del [%del ~]
%baxp [%bac ~]
%entr [%ret ~]
%up [%aro %u]
%down [%aro %d]
%left [%aro %l]
%right [%aro %r]
== :: %yow, %rez?
::
++ noun dill-belt:dill :: clam from %noun
--
--

29
mar/dill/blit.hoon Normal file
View File

@ -0,0 +1,29 @@
::
:::: /hoon/blit/dill/mar
::
/? 310
/- sole
=, sole
=, enjs:format
|_ dib=dill-blit:dill
++ grad %noun
::
++ grab :: convert from
|%
++ noun dill-blit:dill :: clam from %noun
--
++ grow
|%
++ noun dib
++ json
^- ^json
?+ -.dib ~|(unsupported-blit+-.dib !!)
%mor [%a (turn p.dib |=(a=dill-blit:dill json(dib a)))]
%hop %+ frond %hop
?@ p.dib (numb p.dib)
(pairs 'x'^(numb x.p.dib) 'y'^(numb y.p.dib) ~)
%put (frond -.dib (tape (tufa p.dib)))
?(%bel %clr) (frond %act %s -.dib)
==
--
--

12
mar/dns/address.hoon Normal file
View File

@ -0,0 +1,12 @@
/- *dns
|_ address
++ grad %noun
++ grow
|%
++ noun +<.grow
--
++ grab
|%
++ noun address
--
--

12
mar/dns/binding.hoon Normal file
View File

@ -0,0 +1,12 @@
/- *dns
|_ binding
++ grad %noun
++ grow
|%
++ noun +<.grow
--
++ grab
|%
++ noun binding
--
--

21
mar/dns/complete.hoon Normal file
View File

@ -0,0 +1,21 @@
/- *dns
|_ [ship binding]
++ grad %noun
++ grow
|%
++ noun +<.grow
--
++ grab
|%
+$ noun [ship binding]
++ json
=, dejs:format
|= jon=json
%. jon
%- ot
:~ [%ship |=(j=json ?>(?=([%s *] j) (rash +.j fed:ag)))]
[%address |=(j=json ?>(?=([%s *] j) [%if (rash +.j ip4:eyre)]))]
[%turf (ar so)]
==
--
--

16
mar/dns/request.hoon Normal file
View File

@ -0,0 +1,16 @@
/- *dns
|_ r=request
++ grad %noun
++ grow
|%
++ json
%- pairs:enjs:format
:~ ['ship' (ship:enjs:format ship.r)]
['address' s+(rsh 3 (scot %if +.address.r))]
==
--
++ grab
|%
++ noun request
--
--

25
mar/docket-0.hoon Normal file
View File

@ -0,0 +1,25 @@
/+ dock=docket
|_ =docket:dock
++ grow
|%
++ mime
^- ^mime
[/text/x-docket (as-octt:mimes:html (spit-docket:mime:dock docket))]
++ noun docket
++ json (docket:enjs:dock docket)
--
++ grab
|%
::
++ mime
|= [=mite len=@ud tex=@]
^- docket:dock
%- need
%- from-clauses:mime:dock
!<((list clause:dock) (slap !>(~) (ream tex)))
::
++ noun docket:dock
--
++ grad %noun
--

15
mar/drum-put.hoon Normal file
View File

@ -0,0 +1,15 @@
:: %drum-put: download into host system
::
/? 310
|_ [path $@(@ [@ta @])]
::
++ grad %noun
++ grow
|%
++ noun +<.grow
--
++ grab :: convert from
|%
+$ noun [path $@(@ [@ta @])] :: clam from %noun
--
--

12
mar/eth-watcher-poke.hoon Normal file
View File

@ -0,0 +1,12 @@
/- *eth-watcher
|_ poke
++ grad %noun
++ grow
|%
++ noun +<.grow
--
++ grab
|%
++ noun poke
--
--

20
mar/eth/logs.hoon Normal file
View File

@ -0,0 +1,20 @@
:: list of ethereum logs
::
/+ ethereum
::
|_ logs=(list event-log:rpc:ethereum)
++ grab
|%
++ noun (list event-log:rpc:ethereum)
++ mime
|= [mite =octs]
(noun (cue q.octs))
--
::
++ grow
|%
++ mime
[/application/x-ethereum-logs (as-octs:mimes:html (jam logs))]
--
++ grad %mime
--

70
mar/eth/txs.hoon Normal file
View File

@ -0,0 +1,70 @@
:: list of ethereum transactions
::
/+ *ethereum
=, format
=, rpc
=, mimes:html
::
|_ txs=(list transaction)
++ u-parser
%- cook :_ nuck:so
|= =coin
?> ?=(%$ -.coin)
?> ?=(%u (end 3 p.p.coin))
`@`q.p.coin
::
++ grab
|%
++ mime
|= (pair mite octs)
=/ wan=wain (to-wain q.q)
?> ?=(^ wan)
%+ murn t.wan
|= tx=@t
^- (unit transaction)
?: =('' tx)
~
:- ~
%+ rash tx
;~ (glue com)
u-parser
u-parser
u-parser
;~(pfix (jest '0x') hex)
u-parser
;~(pfix (jest '0x') hex)
u-parser
==
++ noun (list transaction)
--
::
++ grow
=> v=.
|%
++ mime
=> v
:- /text/plain
%- as-octs %- of-wain
=- (weld - '' ~)
:- 'nonce,gas-price,gas,to,value,data,chain-id'
%+ turn txs
|= transaction
^- @t
%+ rap 3
:~ (scot %ui nonce)
','
(scot %ui gas-price)
','
(scot %ui gas)
','
(crip (address-to-hex to))
','
(scot %ui value)
','
(crip (prefix-hex (render-hex-bytes (max 1 (met 3 data)) `@`data)))
','
(scot %ux chain-id)
==
--
++ grad %mime
--

16
mar/friends/action.hoon Normal file
View File

@ -0,0 +1,16 @@
/+ *friends
::
|_ act=action
++ grad %noun
++ grow
|%
++ noun act
++ json (action:enjs act)
--
::
++ grab
|%
++ noun action
++ json action:dejs
--
--

15
mar/friends/reaction.hoon Normal file
View File

@ -0,0 +1,15 @@
/+ *friends
::
|_ rct=reaction
++ grad %noun
++ grow
|%
++ noun rct
++ json (reaction:enjs rct)
--
::
++ grab
|%
++ noun reaction
--
--

16
mar/friends/view.hoon Normal file
View File

@ -0,0 +1,16 @@
/- store=friends
/+ *friends
::
|_ view=view:store
++ grad %noun
++ grow
|%
++ noun view
++ json view:enjs
--
::
++ grab
|%
++ noun view:store
--
--

17
mar/groups/view.hoon Normal file
View File

@ -0,0 +1,17 @@
/- store=groups
/+ *groups
::
|_ view=view:store
++ grad %noun
++ grow
|%
++ noun view
++ json (view:enjs view)
--
::
++ grab
|%
++ noun view:store
--
--

20
mar/helm-hi.hoon Normal file
View File

@ -0,0 +1,20 @@
::
:::: /hoon/helm-hi/mar
::
/? 310
=, mimes:html
=, format
|_ txt=cord
::
++ grad %noun
++ grab :: convert from
|%
++ noun @t :: clam from %noun
++ json so:dejs
--
++ grow
|%
++ psal ;div: {(trip txt)}
++ mime [text+/plain (as-octs txt)]
--
--

12
mar/helm-moon-breach.hoon Normal file
View File

@ -0,0 +1,12 @@
|_ mun=ship
::
++ grad %noun
++ grab
|%
++ noun ship
--
++ grow
|%
++ noun mun
--
--

46
mar/herm/task.hoon Normal file
View File

@ -0,0 +1,46 @@
:: task: herm task for passthrough to dill
::
/- herm
/+ dill
::
|_ =task:herm
++ grad %noun
:: +grab: convert from
::
++ grab
|%
++ noun task:herm
::
++ json
|= jon=^json
^+ task
~| jon
?> ?=([%o *] jon)
=+ ses=(~(got by p.jon) 'session')
?> ?=([%s *] ses)
:- ?: =('' p.ses) %$
(slav %tas p.ses)
=. p.jon (~(del by p.jon) 'session')
%. jon
=, dejs:format
|^ task
++ task
%- of
:~ belt+belt:dejs:^dill
blew+(ot 'w'^ni 'h'^ni ~)
hail+ul
open+(ot 'term'^(se %tas) 'apps'^(ar gill) ~)
shut+ul
==
::
++ gill
(ot 'who'^(se %p) 'app'^(se %tas) ~)
--
--
:: +grow: convert to
::
++ grow
|%
++ noun task
--
--

36
mar/hoon.hoon Normal file
View File

@ -0,0 +1,36 @@
:::: /hoon/hoon/mar
::
/? 310
::
=, eyre
|_ own=@t
::
++ grow :: convert to
|%
++ mime `^mime`[/text/x-hoon (as-octs:mimes:html own)] :: convert to %mime
++ hymn
;html
;head
;title:"Source"
;script@"//cdnjs.cloudflare.com/ajax/libs/codemirror/4.3.0/codemirror.js";
;script@"/lib/syntax/hoon.js";
;link(rel "stylesheet", href "//cdnjs.cloudflare.com/ajax/libs/".
"codemirror/4.3.0/codemirror.min.css");
;link/"/lib/syntax/codemirror.css"(rel "stylesheet");
==
;body
;textarea#src:"{(trip own)}"
;script:'CodeMirror.fromTextArea(src, {lineNumbers:true, readOnly:true})'
==
==
++ txt
(to-wain:format own)
--
++ grab
|% :: convert from
++ mime |=([p=mite q=octs] q.q)
++ noun @t :: clam from %noun
++ txt of-wain:format
--
++ grad %txt
--

6
mar/htm.hoon Normal file
View File

@ -0,0 +1,6 @@
::
:::: /hoon/htm/mar
::
/? 310
/= htm /mar/html
htm

22
mar/html.hoon Normal file
View File

@ -0,0 +1,22 @@
::
:::: /hoon/html/mar
::
/? 310
::
:::: compute
::
=, html
|_ htm=@t
++ grow :: convert to
^?
|% ::
++ mime [/text/html (met 3 htm) htm] :: to %mime
++ hymn (need (de-xml htm)) :: to %hymn
-- ::
++ grab ^?
|% :: convert from
++ noun @t :: clam from %noun
++ mime |=([p=mite q=octs] q.q) :: retrieve form %mime
--
++ grad %mime
--

24
mar/httr.hoon Normal file
View File

@ -0,0 +1,24 @@
::
:::: /hoon/httr/mar
::
/? 310
::
=, eyre
=, format
|_ hit=httr
++ grad %noun
++ grow |% ++ wall (turn wain trip)
++ wain (to-wain cord)
++ json (need (de:json:html cord))
++ cord q:octs
++ noun hit
++ octs
~| hit
?> =(2 (div p.hit 100))
(need r.hit)
--
++ grab :: convert from
|%
++ noun httr :: clam from %noun
--
--

17
mar/hymn.hoon Normal file
View File

@ -0,0 +1,17 @@
::
:::: /hoon/hymn/mar
::
/? 310
=, mimes:html
=, html
|_ own=manx
::
++ grad %noun
++ grow :: convert to
|%
++ html (crip (en-xml own)) :: convert to %html
++ mime [/text/html (as-octs html)] :: convert to %mime
--
++ grab |% :: convert from
++ noun manx :: clam from %noun
-- --

12
mar/ico.hoon Normal file
View File

@ -0,0 +1,12 @@
|_ dat=@
++ grow
|%
++ mime [/image/x-icon (as-octs:mimes:html dat)]
--
++ grab
|%
++ mime |=([p=mite q=octs] q.q)
++ noun @
--
++ grad %mime
--

17
mar/jam.hoon Normal file
View File

@ -0,0 +1,17 @@
::
:::: /hoon/jam/mar
::
/? 310
::
=, mimes:html
|_ mud=@
++ grow
|%
++ mime [/application/x-urb-jam (as-octs mud)]
--
++ grab
|% :: convert from
++ noun @ :: clam from %noun
--
++ grad %mime
--

Some files were not shown because too many files have changed in this diff Show More