Merge branch 'next/groups' into hm/landscape-perf-optimization

This commit is contained in:
Hunter Miller 2022-03-11 15:45:00 -06:00
commit a6d7ddd164
77 changed files with 60414 additions and 74412 deletions

6
.gitattributes vendored
View File

@ -8,4 +8,8 @@ pkg/arvo/tmp/landscape.jam filter=lfs diff=lfs merge=lfs -text
pkg/arvo/tmp/base.jam filter=lfs diff=lfs merge=lfs -text
pkg/arvo/tmp/bitcoin.jam filter=lfs diff=lfs merge=lfs -text
pkg/arvo/tmp/webterm.jam filter=lfs diff=lfs merge=lfs -text
*.hoon text eol=lf
*.kelvin text eol=lf
*.bill text eol=lf
*.docket-0 text eol=lf
*.ship text eol=lf

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9a56f675d2a6c5dafa92a9e2d55040d994f3d3d27a1ed827bd87d1158b1e69d0
size 3749183
oid sha256:ae4a7a69fe81c5f2114d7b7360c05602f614fe66b96d1db4c3dc0c2a2a5d856e
size 7536000

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:c29577dc949ac0689ba3c97ad13b812ea6c3c6cc9d255b770d2da95fd9af84b9
size 23121802
oid sha256:bcab0698de6efda1bbac54b0833da5e853bca058919110aa5668aa63fb40626e
size 9392699

View File

@ -54,13 +54,13 @@
?: =(broke-continuity i.topics.event-log)
=/ who=@ (decode-topics t.topics.event-log ~[%uint])
=/ num=@ (decode-results data.event-log ~[%uint])
`[who id %rift num]
`[who id %rift num %.n]
?: =(changed-keys i.topics.event-log)
=/ who=@ (decode-topics t.topics.event-log ~[%uint])
=/ [enc=octs aut=octs sut=@ud rev=@ud]
%+ decode-results data.event-log
~[[%bytes-n 32] [%bytes-n 32] %uint %uint]
`[who id %keys rev sut (pass-from-eth:azimuth enc aut sut)]
`[who id %keys [rev sut (pass-from-eth:azimuth enc aut sut)] %.n]
?: =(lost-sponsor i.topics.event-log)
=/ [who=@ pos=@]
(decode-topics t.topics.event-log ~[%uint %uint])

View File

@ -7,24 +7,21 @@
verb,
dbug
:: Generally don't update the snapshot until we have clay tombstoning.
:: To update, run:
:: =e -build-file %/lib/ethereum/hoon
:: =l .^((list event-log:rpc:e) %gx /=azimuth=/logs/noun)
:: */app/azimuth/logs/eth-logs &eth-logs l
::
/* snap %eth-logs /app/azimuth/logs/eth-logs
/* snap %azimuth-snapshot /app/azimuth/version-0/azimuth-snapshot
:: To update, run from dojo:
:: -azimuth-snap-state %default 'version-0'
::
=/ last-snap :: maybe just use the last one?
%+ roll `(list event-log:rpc:ethereum)`snap ::~
|= [log=event-log:rpc:ethereum last=@ud]
?~ mined.log
last
(max block-number.u.mined.log last)
:: To recreate from a full list of logs (at /app/azimuth/logs/eth-logs):
:: -azimuth-snap-logs %default 'version-0'
::
=/ snap=snap-state snap
=/ last-snap=@ number.id.snap
::
=, jael
|%
+$ app-state
$: %2
$: %5
url=@ta
=net
whos=(set ship)
@ -62,8 +59,14 @@
::
++ on-init
^- (quip card _this)
=/ points=@ud ~(wyt by points.nas.snap)
%- %- slog
[leaf+"ship: loading azimuth snapshot ({<points>} points)"]~
::
=: net.state %default
logs.state snap
nas.state nas.snap
own.state owners.snap
spo.state sponsors.snap
url.state 'http://eth-mainnet.urbit.org:8545'
==
:_ this
@ -89,18 +92,56 @@
?. ?=(%1 -.old-state)
`old-state
%- %- slog :_ ~
leaf+"azimuth: loading snapshot with {<(lent logs.old-state)>} events"
leaf+"ship: loading snapshot with {<(lent logs.old-state)>} events"
=. +.state +.old-state
=^ cards state
(%*(run-logs do nas.state *^state:naive) logs.state)
[(jael-update:do (to-udiffs:do cards)) state]
?> ?=(%2 -.old-state)
[cards-1 this(state old-state)]
=^ cards-2 old-state
?. ?=(%2 -.old-state)
`old-state
~& > '%azimuth: updating to state 3'
=. +.state +.old-state
:: replace naive state and indices with snapshot
::
=: nas.state nas.snap
own.state owners.snap
spo.state sponsors.snap
logs.state ~
:: TODO: shouldn't be needed but have seen eth-watcher
:: threads use a url='' if this is not used
::
url.state 'http://eth-mainnet.urbit.org:8545'
==
=/ points=@ud ~(wyt by points.nas.state)
%- %- slog :_ ~
leaf+"ship: processing azimuth snapshot ({<points>} points)"
=/ snap-cards=udiffs:point (run-state:do id.snap points.nas.state)
:_ [%3 +.state]
%+ weld
(jael-update:do snap-cards)
:: start getting new logs after the last id:block in the snapshot
::
start:do
=^ cards-3 old-state
?. ?=(%3 -.old-state) [cards-2 old-state]
:_ old-state(- %4)
~& > '%azimuth: updating to state 4'
[%pass /resend-pk %arvo %j %resend ~]^cards-2
=^ cards-4 old-state
?. ?=(%4 -.old-state) [cards-3 old-state]
=^ cards this
%- %*(. on-poke +.state.this +.old-state)
[%azimuth-poke !>([%watch [url net]:old-state])]
~& > '%azimuth: updating to state 5'
[cards state.this(- %5)]
?> ?=(%5 -.old-state)
[cards-4 this(state old-state)]
::
++ app-states $%(state-0 state-1 app-state)
++ app-states $%(state-0 state-1-2-3-4 app-state)
::
+$ state-1
$: %1
+$ state-1-2-3-4
$: ?(%1 %2 %3 %4)
url=@ta
=net
whos=(set ship)
@ -126,12 +167,13 @@
^- (quip card _this)
?: =(%noun mark)
?+ q.vase !!
::
%rerun
~& [%rerunning (lent logs.state)]
=. points.nas.state ~
=. own.state ~
=^ * state (run-logs:do logs.state)
`this
=/ points=@ud ~(wyt by points.nas.state)
~& > "rerunning ({<points>} points)"
=/ =udiffs:point
(run-state:do (last-block-id:dice logs.state) points.nas.state)
[(jael-update:do udiffs) this]
::
%resub
:_ this :_ ~
@ -140,13 +182,12 @@
==
::
%resnap
=. logs.state snap
$(mark %noun, vase !>(%rerun))
=: nas.state nas.snap
own.state owners.snap
spo.state sponsors.snap
==
`this
==
?: =(%eth-logs mark)
=+ !<(logs=(list event-log:rpc:ethereum) vase)
=. logs.state logs
$(mark %noun, vase !>(%rerun))
::
?. ?=(%azimuth-poke mark)
(on-poke:def mark vase)
@ -156,15 +197,12 @@
[[%pass /lo %arvo %j %listen (silt whos.poke) source.poke]~ this]
::
%watch
:: TODO: only wipe out state when switching networks?
:: ?: =(net.state net.poke)
:: [~ this]
=: nas.state *^state:naive
=: nas.state ?:(?=(%default net.poke) nas.snap *^state:naive)
own.state ?:(?=(%default net.poke) owners.snap ~)
spo.state ?:(?=(%default net.poke) sponsors.snap ~)
net.state net.poke
url.state url.poke
own.state ~
spo.state ~
logs.state ?:(?=(%default net.poke) snap ~)
logs.state ~
==
[start:do this]
==
@ -188,11 +226,13 @@
:: Slow to recalculate all the diffs, but this is necessary to make
:: sure Jael gets the updates from the snapshot
::
=/ points=@ud ~(wyt by points.nas.state)
%- %- slog :_ ~
leaf+"azimuth: loading snapshot with {<(lent logs.state)>} events"
=^ snap-cards state
(%*(run-logs do nas.state *^state:naive) logs.state)
[(weld (jael-update:do (to-udiffs:do snap-cards)) start:do) this]
:- %leaf
"ship: processing azimuth snapshot ({<points>} points)"
=/ snap-cards=udiffs:point
(%*(run-state do logs.state ~) id.snap points.nas.state)
[(weld (jael-update:do snap-cards) start:do) this]
::
++ on-leave on-leave:def
++ on-peek
@ -237,9 +277,13 @@
%history (welp logs.state loglist.diff)
%logs (welp logs.state loglist.diff)
==
=? nas.state ?=(%history -.diff) *^state:naive
=^ effects state (run-logs:do loglist.diff)
:: doing :azimuth|watch caused a l2-sig-fail when using the eth-log
:: snapshot because we were not updating nas with the saved logs.
::
:: now (L: 189) nas.state is loaded with the contents of the snapshot,
:: if we are on the %default network.
::
=^ effects state (run-logs:do loglist.diff)
:_ this
%+ weld
(event-update:do effects)
@ -287,16 +331,27 @@
^- (list ?(@ux (list @ux)))
~
::
++ data-to-hex
|= data=@t
?~ data *@ux
?: =(data '0x') *@ux
(hex-to-num:ethereum data)
++ run-state
|= [=id:block =points:naive]
::%- road |. :: count memory usage in a separate road
^- =udiffs:point
%- flop
%+ roll (tap:orp:dice points)
|= [[=ship naive-point=point:naive] =udiffs:point]
=, naive-point
=/ =pass
(pass-from-eth:azimuth [32^crypt 32^auth suite]:keys.net)
^- (list [@p udiff:point])
:* [ship id %rift rift.net %.y]
[ship id %keys [life.keys.net suite.keys.net pass] %.y]
[ship id %spon ?:(has.sponsor.net `who.sponsor.net ~)]
udiffs
==
::
++ run-logs
|= [logs=(list event-log:rpc:ethereum)]
^- (quip tagged-diff _state)
=+ net=(get-network net.state)
=+ net=(get-network:dice net.state)
=| effects=(list tagged-diff)
!. :: saves 700MB replaying snapshot
=- =/ res (mule -)
@ -309,11 +364,12 @@
[(flop effects) state]
?~ mined.i.logs
$(logs t.logs)
=/ [raw-effects=effects:naive new-nas=_nas.state]
=+ cache=nas.state
=^ raw-effects nas.state
=/ =^input:naive
:- block-number.u.mined.i.logs
?: =(azimuth.net address.i.logs)
=/ data (data-to-hex data.i.logs)
=/ data (data-to-hex:dice data.i.logs)
=/ =event-log:naive
[address.i.logs data topics.i.logs]
[%log event-log]
@ -321,28 +377,16 @@
[%bat *@]
[%bat u.input.u.mined.i.logs]
(%*(. naive lac |) verifier chain-id.net nas.state input)
:: TODO: move to /lib/dice ?
:: TODO: make index update optional?
::
=/ [new-own=_own.state new-spo=_spo.state]
=< [own spo]
?. =(azimuth.net address.i.logs)
%: apply-effects:dice
chain-id.net
raw-effects
nas.state
own.state
spo.state
==
%: update-indices:dice
raw-effects
nas.state
new-nas
own.state
spo.state
==
=: nas.state new-nas
own.state new-own
spo.state new-spo
=/ =indices [own spo]:state
=. indices
?: =(naive.net address.i.logs)
(tx-effects:dice chain-id.net raw-effects cache indices)
=< indices
(point-effects:dice raw-effects points.cache points.nas.state indices)
=: own.state own.indices
spo.state spo.indices
==
=/ effects-1
=/ =id:block [block-hash block-number]:u.mined.i.logs
@ -358,12 +402,12 @@
^- (unit [=ship =udiff:point])
?. ?=(%point +<.tag) ~
?+ +>+<.tag ~
%rift `[ship.tag id.tag %rift rift.tag]
%rift `[ship.tag id.tag %rift rift.tag %.n]
%sponsor `[ship.tag id.tag %spon sponsor.tag]
%keys
=/ =pass
(pass-from-eth:azimuth 32^crypt.keys.tag 32^auth.keys.tag suite.keys.tag)
`[ship.tag id.tag %keys life.keys.tag suite.keys.tag pass]
`[ship.tag id.tag %keys [life.keys.tag suite.keys.tag pass] %.n]
==
::
++ jael-update
@ -391,26 +435,14 @@
^- card
[%give %fact ~[/event] %naive-diffs !>(+.tag)]
::
++ get-network
|= =net
^- [azimuth=@ux naive=@ux chain-id=@ launch=@]
=< [azimuth naive chain-id launch]
=, azimuth
?- net
%mainnet mainnet-contracts
%ropsten ropsten-contracts
%local local-contracts
%default contracts
==
::
++ start
^- (list card)
=+ net=(get-network net.state)
=+ net=(get-network:dice net.state)
=/ args=vase !>
:+ %watch /[dap.bowl]
^- config:eth-watcher
:* url.state =(%czar (clan:title our.bowl)) refresh ~h30
(max launch.net ?:(=(net.state %default) last-snap 0))
(max launch.net ?:(=(net.state %default) +(last-snap) 0))
~[azimuth.net]
~[naive.net]
(topics whos.state)

Binary file not shown.

Binary file not shown.

View File

@ -200,6 +200,9 @@
=/ contracts (get-contracts network)
?+ -.call ecliptic:contracts
%send-point delegated-sending:contracts
::
?(%approve-batch-transfer %transfer-batch %withdraw)
linear-star-release:contracts
==
::
++ deed
@ -379,7 +382,7 @@
?> =(%king (clan:title s))
(~(put in ss) (^sein:title s))
|-
?~ parents txs
?~ parents !! ::txs
=. txs
%+ do-here ecliptic:mainnet-contracts
(set-spawn-proxy:dat i.parents lockup-contract)
@ -394,15 +397,18 @@
=. txs
%+ do-here ecliptic:mainnet-contracts
(set-transfer-proxy:dat i.what lockup-contract)
=. txs
%+ do-here lockup-contract
(deposit:dat to i.what)
$(what t.what)
==
:: depositing
::
|-
?~ what txs
=. txs
%+ do-here lockup-contract
(deposit:dat to i.what)
:: =. txs
:: %+ do-here lockup-contract
:: (deposit:dat to i.what)
$(what t.what)
++ do-here
|= [contract=address dat=tape]

View File

@ -902,6 +902,9 @@
%dv (dy-sing hand+q.bil %a p.bil (snoc q.bil %hoon))
%ge (dy-run-generator (dy-cage p.p.p.bil) q.p.bil)
%sa
=/ has-mark .?((get-fit:clay he-beak %mar p.bil))
?. has-mark
(he-diff(poy ~) %tan leaf+"dojo: %{(trip p.bil)} missing" ~)
=+ .^(=dais:clay cb+(en-beam he-beak /[p.bil]))
(dy-hand p.bil *vale:dais)
::
@ -910,8 +913,12 @@
=/ has-mark .?((get-fit:clay he-beak %mar p.bil))
?. has-mark :: yolo
(dy-hand p.bil q.cag)
=+ .^(=tube:clay cc+(en-beam he-beak /[p.cag]/[p.bil]))
(dy-hand p.bil (tube q.cag))
=/ res
=+ .^(=tube:clay cc+(en-beam he-beak /[p.cag]/[p.bil]))
(mule |.((tube q.cag)))
?: ?=(%| -.res)
(he-diff(poy ~) %tan leaf+"dojo: %as %{(trip p.bil)} failed" p.res)
(dy-hand p.bil p.res)
::
%do
=/ gat (dy-eval p.bil)

View File

@ -462,9 +462,9 @@
++ release-logs
|= [=path dog=watchdog]
^- (quip card watchdog)
?: (lth number.dog 0) :: TODO: 30!
?: (lth number.dog 30)
`dog
=/ rel-number (sub number.dog 0) :: TODO: 30!
=/ rel-number (sub number.dog 30)
=/ numbers=(list number:block) ~(tap in ~(key by pending-logs.dog))
=. numbers (sort numbers lth)
=^ logs=(list event-log:rpc:ethereum) dog

View File

@ -2,27 +2,28 @@
/+ drum=hood-drum, helm=hood-helm, kiln=hood-kiln
|%
+$ state
$~ [%22 *state:drum *state:helm *state:kiln]
$>(%22 any-state)
$~ [%23 *state:drum *state:helm *state:kiln]
$>(%23 any-state)
::
+$ any-state
$% [ver=?(%1 %2 %3 %4 %5 %6) lac=(map @tas fin-any-state)]
[%7 drum=state-2:drum helm=state:helm kiln=state-0:kiln]
[%8 drum=state-2:drum helm=state:helm kiln=state-0:kiln]
[%9 drum=state-2:drum helm=state:helm kiln=state-0:kiln]
[%10 drum=state-2:drum helm=state:helm kiln=state-0:kiln]
[%11 drum=state-2:drum helm=state:helm kiln=state-0:kiln]
[%12 drum=state-2:drum helm=state:helm kiln=state-0:kiln]
[%13 drum=state-2:drum helm=state:helm kiln=state-1:kiln]
[%14 drum=state-2:drum helm=state:helm kiln=state-1:kiln]
[%15 drum=state-2:drum helm=state:helm kiln=state-2:kiln]
[%16 drum=state-4:drum helm=state:helm kiln=state-3:kiln]
[%17 drum=state-4:drum helm=state:helm kiln=state-4:kiln]
[%18 drum=state-4:drum helm=state:helm kiln=state-5:kiln]
[%19 drum=state-4:drum helm=state:helm kiln=state-6:kiln]
[%20 drum=state-4:drum helm=state:helm kiln=state-7:kiln]
[%21 drum=state-4:drum helm=state:helm kiln=state-8:kiln]
[%22 drum=state-4:drum helm=state:helm kiln=state-9:kiln]
[%7 drum=state-2:drum helm=state-1:helm kiln=state-0:kiln]
[%8 drum=state-2:drum helm=state-1:helm kiln=state-0:kiln]
[%9 drum=state-2:drum helm=state-1:helm kiln=state-0:kiln]
[%10 drum=state-2:drum helm=state-1:helm kiln=state-0:kiln]
[%11 drum=state-2:drum helm=state-1:helm kiln=state-0:kiln]
[%12 drum=state-2:drum helm=state-1:helm kiln=state-0:kiln]
[%13 drum=state-2:drum helm=state-1:helm kiln=state-1:kiln]
[%14 drum=state-2:drum helm=state-1:helm kiln=state-1:kiln]
[%15 drum=state-2:drum helm=state-1:helm kiln=state-2:kiln]
[%16 drum=state-4:drum helm=state-1:helm kiln=state-3:kiln]
[%17 drum=state-4:drum helm=state-1:helm kiln=state-4:kiln]
[%18 drum=state-4:drum helm=state-1:helm kiln=state-5:kiln]
[%19 drum=state-4:drum helm=state-1:helm kiln=state-6:kiln]
[%20 drum=state-4:drum helm=state-1:helm kiln=state-7:kiln]
[%21 drum=state-4:drum helm=state-1:helm kiln=state-8:kiln]
[%22 drum=state-4:drum helm=state-1:helm kiln=state-9:kiln]
[%23 drum=state-4:drum helm=state-2:helm kiln=state-9:kiln]
==
+$ any-state-tuple
$: drum=any-state:drum
@ -48,6 +49,7 @@
++ on-fail on-fail:def
++ on-init
^- step:agent:gall
=^ h helm.state on-init:helm-core
=^ d drum.state on-init:drum-core
=^ k kiln.state on-init:kiln-core
[:(welp d k) this]

View File

@ -151,12 +151,16 @@
?: ?=(l2-tx method)
(process-rpc id +.params method over-quota:scry)
?+ method [~ ~(method error:json-rpc id)]
%cancel-transaction (cancel-tx id +.params)
%when-next-batch `(next-timer id +.params next-batch:scry)
%when-next-slice `(next-timer id +.params next-slice:scry)
%spawns-remaining `(spawns-remaining id +.params unspawned:scry)
%get-remaining-quota `(quota-remaining id +.params ship-quota:scry)
%get-allowance `(ship-allowance id +.params allowance:scry)
%get-point `(get-point id +.params point:scry)
%get-ships `(get-ships id +.params ships:scry)
%cancel-transaction (cancel-tx id +.params)
%get-spawned `(get-spawned id +.params spawned:scry)
%get-unspawned `(get-spawned id +.params unspawned:scry)
%spawns-remaining `(spawns-remaining id +.params unspawned:scry)
%get-sponsored-points `(sponsored-points id +.params sponsored:scry)
%get-owned-points `(get-ships id +.params owned:scry)
%get-transferring-for `(get-ships id +.params transfers:scry)
@ -168,18 +172,13 @@
%get-pending-by-address `(addr:pending id +.params addr:pending:scry)
%get-pending-tx `(hash:pending id +.params hash:pending:scry)
%get-transaction-status `(status id +.params tx-status:scry)
%when-next-batch `(next-batch id +.params next-batch:scry)
%get-predicted-state `(get-naive id +.params predicted:scry)
%get-nonce `(nonce id +.params nonce:scry)
%get-history `(history id +.params addr:history:scry)
%get-roller-config `(get-config id +.params config:scry)
%prepare-for-signing `(hash-transaction id +.params chain:scry | &)
%get-unsigned-tx `(hash-transaction id +.params chain:scry & |)
%get-predicted-state `(get-naive id +.params predicted:scry)
%prepare-for-signing `(hash-transaction id +.params chain:scry | &)
%hash-raw-transaction `(hash-raw-transaction id +.params)
:: TODO: deprecated, remove (used together with personal_sign)
::
%hash-transaction ::`(hash-transaction id +.params chain:scry | &)
`(hash-transaction id +.params chain:scry & |)
==
--
::
@ -307,7 +306,13 @@
++ next-batch
.^ time
%gx
(~(scry agentio bowl) %roller /next-batch/noun)
(~(scry agentio bowl) %roller /next-batch/atom)
==
::
++ next-slice
.^ time
%gx
(~(scry agentio bowl) %roller /next-slice/atom)
==
::
++ nonce
@ -356,6 +361,20 @@
(~(scry agentio bowl) %roller /over-quota/(scot %p ship)/atom)
==
::
++ ship-quota
|= =ship
.^ @ud
%gx
(~(scry agentio bowl) %roller /ship-quota/(scot %p ship)/atom)
==
::
++ allowance
|= =ship
.^ (unit @ud)
%gx
(~(scry agentio bowl) %roller /allowance/(scot %p ship)/noun)
==
::
++ ready
.^ ?
%gx

File diff suppressed because it is too large Load Diff

View File

@ -30,4 +30,4 @@
?. =(*^rift rift)
rift
+(.^(^rift j+/(scot %p our)/rift/(scot %da now)/(scot %p mon)))
`[mon *id:block:jael %rift rift]
`[mon *id:block:jael %rift rift %.n]

View File

@ -42,4 +42,4 @@
leaf+(scow %uw (jam seed))
==
pub:ex:cub
`[mon *id:block:jael %keys life 1 pass]
`[mon *id:block:jael %keys [life 1 pass] %.n]

View File

@ -41,4 +41,4 @@
leaf+(scow %uw (jam seed))
==
pub:ex:cub
`[mon *id:block:jael %keys 1 1 pass]
`[mon *id:block:jael %keys [1 1 pass] %.n]

View File

@ -0,0 +1,6 @@
:: Assigns a specific quota to the given ship
:: Not providing a quota allows the ship to submit any number of transactions
::
:- %say
|= [* [=ship quota=(unit @ud) ~] ~]
[%roller-action %assign ship quota]

View File

@ -0,0 +1,5 @@
:: Bumps the gas price for a sending transaction
::
:- %say
|= [* [nonce=@ gas=@ud address=(unit @ux) ~] ~]
[%roller-action %refuel nonce address gas]

View File

@ -599,7 +599,7 @@
~(parse error:json-rpc id)
[%result id (tx-status:to-json (scry u.hash))]
::
++ next-batch
++ next-timer
|= [id=@t params=(map @t json) when=time]
^- response:rpc
?. =((lent ~(tap by params)) 0)
@ -680,4 +680,25 @@
?. =((lent ~(tap by params)) 0)
~(params error:json-rpc id)
[%result id (azimuth-config:to-json azimuth-config)]
::
++ quota-remaining
|= [id=@t params=(map @t json) quota-left=$-(@p @ud)]
^- response:rpc
?. =((lent ~(tap by params)) 1)
~(params error:json-rpc id)
?~ ship=(ship:from-json params)
~(params error:json-rpc id)
[%result id (numb:enjs:format (quota-left u.ship))]
::
++ ship-allowance
|= [id=@t params=(map @t json) allowance=$-(@p (unit @ud))]
^- response:rpc
?. =((lent ~(tap by params)) 1)
~(params error:json-rpc id)
?~ ship=(ship:from-json params)
~(params error:json-rpc id)
:+ %result id
?^ allow=(allowance u.ship)
(numb:enjs:format u.allow)
s+(crip "No quota restrictions for {(scow %p u.ship)}")
--

View File

@ -42,8 +42,14 @@
%adopt (adopt:dat +.call)
%start-document-poll (start-document-poll:dat +.call)
%cast-document-vote (cast-document-vote:dat +.call)
%start-upgrade-poll (start-upgrade-poll:dat +.call)
%cast-upgrade-vote (cast-upgrade-vote:dat +.call)
::
%send-point (send-point:dat +.call)
::
%approve-batch-transfer (approve-batch-transfer:dat +.call)
%transfer-batch (transfer-batch:dat +.call)
%withdraw (withdraw:dat +.call)
==
::
+$ call-data call-data:rpc
@ -67,12 +73,18 @@
++ adopt (enc adopt:cal)
++ start-document-poll (enc start-document-poll:cal)
++ cast-document-vote (enc cast-document-vote:cal)
++ start-upgrade-poll (enc start-upgrade-poll:cal)
++ cast-upgrade-vote (enc cast-upgrade-vote:cal)
::
++ register-linear (enc register-linear:cal)
++ register-conditional (enc register-conditional:cal)
++ deposit (enc deposit:cal)
::
++ send-point (enc send-point:cal)
::
++ approve-batch-transfer (enc approve-batch-transfer:cal)
++ transfer-batch (enc transfer-batch:cal)
++ withdraw (enc withdraw:cal)
--
::
::TODO lib
@ -170,6 +182,25 @@
[%bool support]
==
::
++ start-upgrade-poll
|= [gal=ship =address]
^- call-data
?> =(%czar (clan:title gal))
:- 'startUpgradePoll(uint8,address)'
:~ [%uint `@`gal]
[%address address]
==
::
++ cast-upgrade-vote
|= [gal=ship =address support=?]
^- call-data
?> =(%czar (clan:title gal))
:- 'castUpgradeVote(uint8,address,bool)'
:~ [%uint `@`gal]
[%address address]
[%bool support]
==
::
::
++ set-dns-domains
|= [pri=tape sec=tape ter=tape]
@ -252,6 +283,27 @@
[%address to]
==
::
++ approve-batch-transfer
|= to=address
^- call-data
:- 'approveBatchTransfer(address)'
:~ [%address to]
==
::
++ transfer-batch
|= from=address
^- call-data
:- 'transferBatch(address)'
:~ [%address from]
==
::
++ withdraw
|= to=address
^- call-data
:- 'withdraw(address)'
:~ [%address to]
==
::
:: read calls
::
++ rights

View File

@ -1,207 +1,388 @@
:: dice: helper functions for L2 Rollers
::
/- *dice
/+ naive, *naive-transactions
/+ naive, *naive-transactions, ethereum, azimuth
:: verbose bit
::
=| verb=?
::
|%
:: orp: ordered points in naive state by parent ship
::
++ orp ((on ship point:naive) por:naive)
:: ors: ordered sending map by (increasing) L1 nonce
::
++ ors ((on l1-tx-pointer send-tx) nonce-order)
:: orh: ordered tx history by (decreasing) timestamp
::
++ orh ((on time roll-tx) gth)
::
++ nonce-order
|= [a=[* =nonce:naive] b=[* =nonce:naive]]
(lte nonce.a nonce.b)
::
++ apply-effects
|= [chain-t=@ =effects:naive =indices]
++ data-to-hex
|= data=@t
?~ data *@ux
?: =(data '0x') *@ux
(hex-to-num:ethereum data)
::
++ get-network
|= =net
^- [azimuth=@ux naive=@ux chain-id=@ launch=@]
=< [azimuth naive chain-id launch]
=, azimuth
?- net
%mainnet mainnet-contracts
%ropsten ropsten-contracts
%local local-contracts
%default contracts
==
::
++ last-block-id
|= logs=(list event-log:rpc:ethereum)
^- id:block:jael
%+ roll logs
|= [log=event-log:rpc:ethereum =id:block:jael]
?~ mined.log id
?. (gth block-number.u.mined.log number.id)
id
[block-hash block-number]:u.mined.log
::
++ tx-effects
|= [chain-t=@ =effects:naive nas=^state:naive =indices]
^+ indices
%+ roll effects
|= [=diff:naive indices=_indices]
?. ?=([%tx *] diff) indices::[nas own spo]
=< indices
(apply-raw-tx | chain-t raw-tx.diff indices)
%+ roll effects
|= [=diff:naive nas=_nas indices=_indices]
?. ?=([%tx *] diff) [nas indices]
=< [nas indices]
%- %*(. apply-raw-tx verb |)
[| chain-t raw-tx.diff nas indices]
::
++ apply-raw-tx
|= [force=? chain-t=@ =raw-tx:naive =indices]
^- [? ups=(list update) indices=_indices]
=+ cache-nas=nas.indices
|= [force=? chain-t=@ =raw-tx:naive nas=^state:naive =indices]
^- [? (list update) nas=_nas indices=_indices]
=+ cache=nas
=/ chain-t=@t (ud-to-ascii:naive chain-t)
?. (verify-sig-and-nonce:naive verifier chain-t nas.indices raw-tx)
~& [%verify-sig-and-nonce %failed tx.raw-tx]
[force ~ indices]
=^ * points.nas.indices
(increment-nonce:naive nas.indices from.tx.raw-tx)
?~ nex=(receive-tx:naive nas.indices tx.raw-tx)
~& [%receive-tx %failed]
=? nas.indices !force cache-nas
[force ~ indices]
?. (verify-sig-and-nonce:naive verifier chain-t nas raw-tx)
=+ [force ~ nas indices]
?. verb -
~& >>> [verb+verb %verify-sig-and-nonce %failed tx.raw-tx] -
=^ effects-1 points.nas
(increment-nonce:naive nas from.tx.raw-tx)
?~ nex=(receive-tx:naive nas tx.raw-tx)
=+ [force ~ ?:(force nas cache) indices]
?. verb -
~& >>> [verb+verb %receive-tx %failed] -
=* new-nas +.u.nex
=* effects -.u.nex
=/ [updates=(list update) own=_own.indices spo=_spo.indices]
(update-indices effects cache-nas new-nas [own spo]:indices)
=: nas.indices new-nas
own.indices own
spo.indices spo
==
[& updates indices]
=/ effects (welp effects-1 -.u.nex)
=^ updates indices
(point-effects effects points.cache points.new-nas [own spo]:indices)
[& updates new-nas indices]
::
++ update-indices
|= $: =effects:naive
cache-nas=^state:naive
nas=^state:naive
=owners
=sponsors
==
^- [(list update) own=_owners spo=_sponsors]
%+ roll effects
|= $: =diff:naive
ups=(list update)
owners=_owners
sponsors=_sponsors
==
=, orm:naive
?. ?=([%point *] diff) [ups owners sponsors]
=* ship ship.diff
=/ old=(unit point:naive)
(get points.cache-nas ship)
=/ new=point:naive
(need (get points.nas ship))
++ point-effects
|= [=effects:naive cache=points:naive =points:naive =indices]
^- [(list update) indices=_indices]
=^ updates=(list update) indices
%+ roll effects
|= [=diff:naive updates=(list update) indices=_indices]
?. |(?=([%point *] diff) ?=([%nonce *] diff))
[updates indices]
?: ?=([%nonce *] diff)
:_ indices
(welp (nonce-updates diff cache points) updates)
?> ?=([%point *] diff)
=* ship ship.diff
=* sponsors spo.indices
=* owners own.indices
=/ old=(unit point:naive) (get:orp cache ship)
=/ new=point:naive (need (get:orp points ship))
=^ update-1 sponsors
(sponsorship-diff diff ship new old sponsors)
=^ update-2 owners
(ownership-diff diff ship new old owners)
=/ update-3=_updates
(point-data-updates diff ship new old)
:_ indices
:(welp update-3 update-2 update-1 updates)
[(flop updates) indices]
::
++ sponsorship-diff
|= [=diff:naive =ship new=point:naive old=(unit point:naive) =sponsors]
^- (quip update _sponsors)
?. ?=([%point *] diff) `sponsors
=* event +>.diff
|^
=^ updates owners ownership
=+ sponsors=sponsorship
:+ (weld ups updates)
owners
sponsors
::
++ sponsorship
^+ sponsors
?+ -.event sponsors
%owner
?^ old
:: ownership change
::
sponsors
:: owner event with ?=(~ old) is a spawn
?+ -.event `sponsors
%owner
?^ old
:: ownership change
::
=* parent who.sponsor.net.new
?: =(parent ship) sponsors
%+ ~(put by sponsors) parent
?~ sponsor=(~(get by sponsors) parent)
:_ *(set @p)
(~(put in *(set @p)) ship)
:_ requests.u.sponsor
(~(put in residents.u.sponsor) ship)
`sponsors
:: owner event with ?=(~ old) is a spawn
::
%escape
?~ old sponsors
=* from who.sponsor.net.u.old
=* to to.event
=* escape escape.net.u.old
?~ to
:: cancel/reject escape
::
?~ escape sponsors
?~ receiver=(~(get by sponsors) u.escape)
sponsors
%+ ~(put by sponsors) u.escape
:- residents.u.receiver
(~(del in requests.u.receiver) ship)
:: normal escape
=* parent who.sponsor.net.new
?: =(parent ship) `sponsors
:: updates for proxy %own are taken care of
:: in +sponsorship to avoid duplicates
::
:- ~
%+ ~(put by sponsors) parent
?~ sponsor=(~(get by sponsors) parent)
:_ *(set @p)
(~(put in *(set @p)) ship)
:_ requests.u.sponsor
(~(put in residents.u.sponsor) ship)
::
%escape
?~ old `sponsors
=* from who.sponsor.net.u.old
=* to to.event
=* escape escape.net.u.old
?~ to
:: cancel/reject escape
::
%+ ~(put by sponsors) u.to
?~ receiver=(~(get by sponsors) u.to)
:- *(set @p)
(~(put in *(set @p)) ship)
?~ escape `sponsors
?~ receiver=(~(get by sponsors) u.escape)
`sponsors
::
:- (proxy-updates diff ship new old)
::
%+ ~(put by sponsors) u.escape
:- residents.u.receiver
(~(put in requests.u.receiver) ship)
(~(del in requests.u.receiver) ship)
:: normal escape
::
%sponsor
?~ old sponsors
=* from who.sponsor.net.u.old
=* to sponsor.event
=/ previous (~(get by sponsors) from)
?~ to
:: detach
::
?~ previous sponsors
%+ ~(put by sponsors) from
:_ requests.u.previous
(~(del in residents.u.previous) ship)
:: accepted
::
=/ receiver (~(get by sponsors) u.to)
=? sponsors ?=(^ receiver)
%+ ~(put by sponsors) u.to
:- (~(put in residents.u.receiver) ship)
(~(del in requests.u.receiver) ship)
=? sponsors ?=(^ previous)
%+ ~(put by sponsors) from
:_ requests.u.previous
(~(del in residents.u.previous) ship)
sponsors
==
:- (proxy-updates diff ship new old)
::
%+ ~(put by sponsors) u.to
?~ receiver=(~(get by sponsors) u.to)
:- *(set @p)
(~(put in *(set @p)) ship)
:- residents.u.receiver
(~(put in requests.u.receiver) ship)
::
++ ownership
^- (quip update _owners)
=; [to=(unit owner) from=(unit owner)]
=? owners &(?=(^ from) !=(address.u.from 0x0))
(~(del ju owners) u.from ship)
?: ?| =(~ to)
&(?=(^ to) =(address.u.to 0x0))
==
[ups owners]
?~ to [ups owners]
:_ (~(put ju owners) u.to ship)
(snoc ups [%point ship new u.to from])
?+ -.event [~ ~]
%owner
:- `[%own +.event]
?~ old ~
`[%own address.owner.own.u.old]
%sponsor
?~ old `sponsors
=* from who.sponsor.net.u.old
=* to sponsor.event
=/ previous (~(get by sponsors) from)
?~ to
:: detach
::
?~ previous `sponsors
::
:- (proxy-updates diff ship new old)
::
%+ ~(put by sponsors) from
:_ requests.u.previous
(~(del in residents.u.previous) ship)
:: accepted
::
%management-proxy
:- `[%manage +.event]
?~ old ~
`[%manage address.management-proxy.own.u.old]
=/ receiver (~(get by sponsors) u.to)
=? sponsors ?=(^ receiver)
%+ ~(put by sponsors) u.to
:- (~(put in residents.u.receiver) ship)
(~(del in requests.u.receiver) ship)
=? sponsors ?=(^ previous)
%+ ~(put by sponsors) from
:_ requests.u.previous
(~(del in residents.u.previous) ship)
:_ sponsors
(proxy-updates diff ship new old)
==
::
++ ownership-diff
|= [=diff:naive =ship new=point:naive old=(unit point:naive) =owners]
^- (quip update _owners)
?. ?=([%point *] diff) `owners
=* event +>.diff
=; [to=(unit owner) from=(unit owner)]
=? owners &(?=(^ from) !=(address.u.from 0x0))
(~(del ju owners) u.from ship)
?: ?| =(~ to)
&(?=(^ to) =(address.u.to 0x0))
==
[~ owners]
?~ to [~ owners]
:_ (~(put ju owners) u.to ship)
[%point diff ship new old u.to from]~
?+ -.event [~ ~]
%owner
:- `[%own +.event]
?~ old ~
`[%own address.owner.own.u.old]
::
%management-proxy
:- `[%manage +.event]
?~ old ~
`[%manage address.management-proxy.own.u.old]
::
%spawn-proxy
:- `[%spawn +.event]
?~ old ~
`[%spawn address.spawn-proxy.own.u.old]
::
%voting-proxy
:- `[%vote +.event]
?~ old ~
`[%vote address.voting-proxy.own.u.old]
::
%transfer-proxy
:- `[%transfer +.event]
?~ old ~
`[%transfer address.transfer-proxy.own.u.old]
==
::
++ create-indices
|= nas=^state:naive
^- [sponsors owners]
%+ roll (tap:orp points.nas)
|= [[=ship =point:naive] =sponsors =owners]
|^
=? sponsors has.sponsor.net.point
^+ sponsors
(add-resident who.sponsor.net.point)
=? sponsors ?=(^ escape.net.point)
(add-request u.escape.net.point)
[sponsors add-ownership]
::
++ add-resident
|= sponsor=@p
^+ sponsors
:: galaxies have themselves as their sponsors
::
%spawn-proxy
:- `[%spawn +.event]
?~ old ~
`[%spawn address.spawn-proxy.own.u.old]
?: =(sponsor ship) sponsors
%+ ~(put by sponsors) sponsor
?~ sponsees=(~(get by sponsors) sponsor)
:_ *(set @p)
(~(put in *(set @p)) ship)
:_ requests.u.sponsees
(~(put in residents.u.sponsees) ship)
::
++ add-request
|= sponsor=@p
^+ sponsors
:: galaxies have themselves as their sponsors
::
%voting-proxy
:- `[%vote +.event]
?~ old ~
`[%vote address.voting-proxy.own.u.old]
::
%transfer-proxy
:- `[%transfer +.event]
?~ old ~
`[%transfer address.transfer-proxy.own.u.old]
==
?: =(sponsor ship) sponsors
%+ ~(put by sponsors) sponsor
?~ receiver=(~(get by sponsors) sponsor)
:- *(set @p)
(~(put in *(set @p)) ship)
:- residents.u.receiver
(~(put in requests.u.receiver) ship)
::
++ add-ownership
^+ owners
=/ proxies=(list proxy:naive)
~[%own %spawn %manage %vote %transfer]
%+ roll proxies
|= [=proxy:naive own=_owners]
?~ owner=(get-owner point proxy)
own
(~(put ju own) u.owner ship)
--
::
++ proxy-updates
|= [=diff:naive =ship =point:naive old=(unit point:naive)]
^- (list update)
=/ proxies=(list proxy:naive)
~[%own %spawn %manage %vote %transfer]
?~ old ~
%- flop
%+ roll proxies
|= [=proxy:naive updates=(list update)]
?~ owner=(get-owner u.old proxy) updates
:_ updates
[%point diff ship point old u.owner ~]
::
++ nonce-updates
|= [=diff:naive cache=points:naive =points:naive]
^- (list update)
?. ?=([%nonce *] diff) ~
=/ old=(unit point:naive) (get:orp cache ship.diff)
=/ new=point:naive (need (get:orp points ship.diff))
(point-data-updates diff ship.diff new old)
::
++ point-data-updates
|= [=diff:naive =ship =point:naive old=(unit point:naive)]
^- (list update)
?. ?=([%point *] diff) ~
=* event +>.diff
?+ -.event ~
%rift (proxy-updates +<)
%keys (proxy-updates +<)
%dominion (proxy-updates +<)
==
::
++ get-owner
|= [=point:naive =proxy:naive]
^- [nonce=@ _point]
=* own own.point
^- (unit owner)
=, own.point
?- proxy
%own
:- nonce.owner.own
point(nonce.owner.own +(nonce.owner.own))
?:(=(address.owner 0x0) ~ `own+address.owner)
::
%spawn
:- nonce.spawn-proxy.own
point(nonce.spawn-proxy.own +(nonce.spawn-proxy.own))
?:(=(address.spawn-proxy 0x0) ~ `spawn+address.spawn-proxy)
::
%manage
:- nonce.management-proxy.own
point(nonce.management-proxy.own +(nonce.management-proxy.own))
?:(=(address.management-proxy 0x0) ~ `manage+address.management-proxy)
::
%vote
:- nonce.voting-proxy.own
point(nonce.voting-proxy.own +(nonce.voting-proxy.own))
?:(=(address.voting-proxy 0x0) ~ `vote+address.voting-proxy)
::
%transfer
:- nonce.transfer-proxy.own
point(nonce.transfer-proxy.own +(nonce.transfer-proxy.own))
?:(=(address.transfer-proxy 0x0) ~ `transfer+address.transfer-proxy)
==
::
++ get-nonce
|= [=point:naive =proxy:naive]
^- nonce:naive
=, own.point
?- proxy
%own nonce.owner
%spawn nonce.spawn-proxy
%manage nonce.management-proxy
%vote nonce.voting-proxy
%transfer nonce.transfer-proxy
==
::
++ controlled-ships
|= [=address:ethereum =owners]
^- (list [=proxy:naive =ship])
=/ proxies=(list proxy:naive)
~[%own %spawn %manage %vote %transfer]
%+ roll proxies
|= [=proxy:naive ships=(list [=proxy:naive ship])]
%+ welp
%+ turn
~(tap in (~(get ju owners) [proxy address]))
(lead proxy)
ships
:: +update-history: updates status for all given list of transaction
::
++ update-history
|= [=history txs=(list pend-tx) =status]
^- (quip update _history)
=^ updates=(list update) history
%+ roll txs
|= [=pend-tx ups=(list update) history=_history]
=, pend-tx
=/ =roll-tx
=, pend-tx
:* ship.from.tx.raw-tx
status
(hash-raw-tx raw-tx)
(l2-tx +<.tx.raw-tx)
==
=/ txs=(tree hist-tx)
?~ txs=(~(get by history) address) ~
u.txs
=? txs ?=(^ txs) +:(del:orh txs time)
:- [tx+[pend-tx status] ups]
%+ ~(put by history) address
(put:orh txs [time roll-tx])
[(flop updates) history]
--

View File

@ -136,6 +136,7 @@
::
++ poke
|= [=mark =vase]
?> =(our src):hid
?+ mark ~|([%poke-drum-bad-mark mark] !!)
%drum-dill-belt =;(f (f !<(_+<.f vase)) poke-dill-belt)
%drum-dill-blit =;(f (f !<(_+<.f vase)) poke-dill-blit)

View File

@ -1,27 +1,33 @@
/+ pill
=* card card:agent:gall
|%
+$ state state-1
+$ state state-2
+$ any-state
$~ *state
$% state-1
$% state-2
state-1
state-0
==
+$ state-1
$: %1
mass-timer=[way=wire nex=@da tim=@dr]
==
+$ state-2 [%2 =mass-timer]
+$ state-1 [%1 =mass-timer]
+$ state-0 [%0 hoc=(map bone session-0)]
+$ session-0
$: say=*
mud=*
mass-timer=[way=wire nex=@da tim=@dr]
=mass-timer
==
::
+$ mass-timer [way=wire nex=@da tim=@dr]
::
++ state-0-to-1
|= s=state-0
^- state
^- state-1
[%1 mass-timer:(~(got by hoc.s) 0)]
::
++ state-1-to-2
|= s=state-1
^- state-2
[%2 +.s]
--
|= [=bowl:gall sat=state]
=| moz=(list card)
@ -39,27 +45,46 @@
^+ this
?~(caz this $(caz t.caz, this (emit i.caz)))
::
++ on-init
(poke-serve [~ /who] %base /gen/who/hoon ~)
::
++ on-load
|= [hood-version=@ud old=any-state]
=< abet
=? old ?=(%0 -.old) (state-0-to-1 old)
?> ?=(%1 -.old)
=? old ?=(%0 -.old) (state-0-to-1 old)
=? this ?=(%1 -.old)
(emil -:(poke-serve [~ /who] %base /gen/who/hoon ~))
=? old ?=(%1 -.old) (state-1-to-2 old)
?> ?=(%2 -.old)
this(sat old)
::
++ poke-rekey :: rotate private keys
|= des=@t
=/ sed=(unit seed:jael)
=/ fud=(unit feed:jael)
%+ biff
(bind (slaw %uw des) cue)
(soft seed:jael)
(soft feed:jael)
=< abet
?~ sed
?~ fud
~& %invalid-private-key
this
?. =(our.bowl who.u.sed)
~& [%wrong-private-key-ship who.u.sed]
=/ fed (need fud)
?@ -.fed
?. =(our.bowl who.fed)
~& [%wrong-private-key-ship who.fed]
this
(emit %pass / %arvo %j %rekey lyf.fed key.fed)
?. =(our.bowl who.fed)
~& [%wrong-private-key-ship who.fed]
this
(emit %pass / %arvo %j %rekey lyf.u.sed key.u.sed)
=| caz=(list card)
%- emil
|-
?~ kyz.fed (flop caz)
%= $
kyz.fed t.kyz.fed
caz [[%pass / %arvo %j %rekey i.kyz.fed] caz]
==
::
++ ames-secret
^- @t
@ -199,6 +224,9 @@
::
++ poke
|= [=mark =vase]
?> ?| ?=(%helm-hi mark)
=(our src):bowl
==
?+ mark ~|([%poke-helm-bad-mark mark] !!)
%helm-ames-sift =;(f (f !<(_+<.f vase)) poke-ames-sift)
%helm-ames-verb =;(f (f !<(_+<.f vase)) poke-ames-verb)

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
--

View File

@ -66,8 +66,14 @@
[%adopt who=ship]
[%start-document-poll gal=ship hash=@]
[%cast-document-vote gal=ship hash=@ vote=?]
[%start-upgrade-poll gal=ship =address]
[%cast-upgrade-vote gal=ship =address vote=?]
::
[%send-point as=ship point=ship to=address]
::
[%approve-batch-transfer to=address]
[%transfer-batch from=address]
[%withdraw to=address]
==
::
++ prep-result

View File

@ -1,15 +1,18 @@
:: dice: structures for L2 rollers
:: dice: structures for Azimuth L2 rollers
::
/+ naive, ethereum
::
|%
+$ owner [=proxy:naive =address:naive]
+$ owners (jug owner ship)
+$ sponsors (map ship [residents=(set ship) requests=(set ship)])
+$ net ?(%mainnet %ropsten %local %default)
+$ owner [=proxy:naive =address:naive]
+$ owners (jug owner ship)
+$ sponsors (map ship [residents=(set ship) requests=(set ship)])
+$ history (map address:ethereum (tree hist-tx))
+$ net ?(%mainnet %ropsten %local %default)
+$ snap-state [%0 =id:block:jael nas=^state:naive =owners =sponsors]
::
+$ config
$% [%frequency frequency=@dr]
[%fallback gas=@ud]
[%setkey pk=@]
[%endpoint endpoint=@t =net]
[%resend-time time=@dr]
@ -19,8 +22,7 @@
==
::
+$ indices
$: nas=^state:naive
own=owners
$: own=owners
spo=sponsors
==
::
@ -69,9 +71,16 @@
==
::
+$ update
$% [%point =ship =point:naive new=owner old=(unit owner)]
[%tx =address:ethereum =roll-tx]
==
$% [%tx =pend-tx =status]
::
$: %point
=diff:naive
=ship
new=point:naive
old=(unit point:naive)
to=owner
from=(unit owner)
== ==
::
+$ hist-tx [p=time q=roll-tx]
+$ roll-tx [=ship =status hash=keccak type=l2-tx]
@ -90,7 +99,12 @@
pk=@
::
nonce=@ud
fallback-gas-price=@ud
next-gas-price=@ud
txs=(list raw-tx:naive)
==
::
+$ roller-data
[chain-id=@ =points:naive history=(tree hist-tx) =owners =sponsors]
::
--

View File

@ -48,7 +48,7 @@
+$ dock (pair @p term)
+$ gang (unit (set ship))
+$ mark @tas
+$ mein [our=ship now=@da eny=@uvJ]
+$ mien [our=ship now=@da eny=@uvJ]
++ omen |$ [a] (pair path (cask a))
+$ ship @p
+$ sink (trel bone ship path)
@ -214,7 +214,7 @@
:: zen: Outside knowledge
:: mod: internal modules
::
mein
mien
$= fad
$: :: lac: not verbose
::
@ -1294,31 +1294,30 @@
^- mass
=; sam=(list mass)
:+ %arvo %|
:~ hoon+&+pit
zuse+&+zus.mod
:~ :+ %hoon %|
:~ one+&+..bloq
two+&+..turn
tri+&+..year
qua+&+..sane
pen+&+..ride
==
hex+&+..part
pit+&+pit
lull+|+[dot+&+q typ+&+p ~]:lul.mod
zuse+|+[dot+&+q typ+&+p ~]:zus.mod
vane+|+sam
==
::
=/ von
%+ turn
(sort ~(tap by van.mod) |=([[a=@tas *] [b=@tas *]] (aor a b)))
::
:~ :+ %reports %|
=/ bem=beam [[our %home da+now] /whey] ::TODO %base?
%+ turn von
|= [nam=term =vane]
=/ met (peek [~ ~] nam bem)
~| mass/nam
?> &(?=(^ met) ?=(^ u.met)) :: XX make optional
nam^|+;;((list mass) q.q.u.u.met)
::
:+ %caches %|
%+ turn von
|=([nam=term =vane] nam^&+worm.vane)
::
:+ %dregs %|
%+ turn von
|=([nam=term =vane] nam^&+vase.vane)
==
=/ bem=beam [[our %home da+now] /whey] ::TODO %base?
|= [nam=term =vane]
=; mas=(list mass)
nam^|+(welp mas [dot+&+q.vase typ+&+p.vase sac+&+worm ~]:vane)
?~ met=(peek [~ ~] nam bem) ~
?~ u.met ~
~| mass+nam
;;((list mass) q.q.u.u.met)
:: +peek: read from the entire namespace
::
++ peek

View File

@ -1906,6 +1906,7 @@
[%private-keys ~] :: sub to privates
[%public-keys ships=(set ship)] :: sub to publics
[%rekey =life =ring] :: update private keys
[%resend ~] :: resend private key
[%ruin ships=(set ship)] :: pretend breach
$>(%trim vane-task) :: trim state
[%turf ~] :: view domains
@ -1980,8 +1981,8 @@
+$ udiffs (list [=ship =udiff])
+$ udiff
$: =id:block
$% [%rift =rift]
[%keys key-update]
$% [%rift =rift boot=?]
[%keys key-update boot=?]
[%spon sponsor=(unit @p)]
[%disavow ~]
== ==
@ -1995,14 +1996,14 @@
%rift
?. (gth rift.a-udiff rift.a-point)
~
~? !=(rift.a-udiff +(rift.a-point))
~? &(!=(rift.a-udiff +(rift.a-point)) !boot.a-udiff)
[%udiff-to-diff-skipped-rift a-udiff a-point]
`[%rift rift.a-point rift.a-udiff]
::
%keys
?. (gth life.a-udiff life.a-point)
~
~? !=(life.a-udiff +(life.a-point))
~? &(!=(life.a-udiff +(life.a-point)) !boot.a-udiff)
[%udiff-to-diff-skipped-life a-udiff a-point]
:^ ~ %keys
[life.a-point (~(gut by keys.a-point) life.a-point *[@ud pass])]

View File

@ -1593,10 +1593,12 @@
?~ sponsor
~| %ames-lost-sponsor^our^ship !!
::
=/ =peer-state (got-peer-state ship)
=. sponsor.peer-state u.sponsor
::
=. peers.ames-state (~(put by peers.ames-state) ship %known peer-state)
=/ state=(unit peer-state) (get-peer-state ship)
?~ state
%- (slog leaf+"ames: missing peer-state, ignoring" ~)
event-core
=. sponsor.u.state u.sponsor
=. peers.ames-state (~(put by peers.ames-state) ship %known u.state)
event-core
:: +on-publ-full: handle new pki data for peer(s)
::

View File

@ -427,6 +427,13 @@
%- curd =< abet
(private-keys:~(feel su hen now pki etn) life.tac ring.tac)
::
:: resend private key to subscribers
::
%resend
%- curd =< abet
%- ~(exec su hen now pki etn)
[yen.own.pki [%give %private-keys [lyf jaw]:own.pki]]
::
:: register moon keys
::
%moon
@ -733,14 +740,18 @@
=/ a-point=point (~(gut by pos.zim.pki) ship.i.udiffs *point)
=/ a-diff=(unit diff:point) (udiff-to-diff:point udiff.i.udiffs a-point)
=? this-su ?=(^ a-diff)
:: if this about our keys, and we already know these, start using them
::
=? lyf.own
=? this-su
?& =(our ship.i.udiffs)
?=(%keys -.u.a-diff)
(~(has by jaw.own) life.to.u.a-diff)
==
life.to.u.a-diff
:: if this about our keys, and we already know these, start using them
::
=. lyf.own life.to.u.a-diff
:: notify subscribers (ames) to start using our new private keys
::
(exec yen.own [%give %private-keys [lyf jaw]:own])
::
(public-keys:feel original-pos %diff ship.i.udiffs u.a-diff)
$(udiffs t.udiffs)
::

View File

@ -2235,6 +2235,112 @@
=/ pub (from.j qj)
?< =([0 0] pub)
pub
++ schnorr
~% %schnorr ..schnorr ~
=> |%
++ tagged-hash
|= [tag=@ [l=@ x=@]]
=+ hat=(sha-256:sha (swp 3 tag))
%- sha-256l:sha
:- (add 64 l)
(can 3 ~[[l x] [32 hat] [32 hat]])
++ lift-x
|= x=@I
^- (unit point)
=/ c curve
?. (lth x p.domain.c)
~
=/ fop field-p.c
=+ [fadd fpow]=[sum.fop exp.fop]
=/ cp (fadd (fpow 3 x) 7)
=/ y (fpow (rsh [0 2] +(p.domain.c)) cp)
?. =(cp (fpow 2 y))
~
%- some :- x
?: =(0 (mod y 2))
y
(sub p.domain.c y)
--
|%
::
++ sign :: schnorr signature
~/ %sosi
|= [sk=@I m=@I a=@I]
^- @J
?> (gte 32 (met 3 m))
?> (gte 32 (met 3 a))
=/ c curve
:: implies (gte 32 (met 3 sk))
::
?< |(=(0 sk) (gte sk n.domain.c))
=/ pp
(mul-point-scalar g.domain.c sk)
=/ d
?: =(0 (mod y.pp 2))
sk
(sub n.domain.c sk)
=/ t
%+ mix d
(tagged-hash 'BIP0340/aux' [32 a])
=/ rand
%+ tagged-hash 'BIP0340/nonce'
:- 96
(rep 8 ~[m x.pp t])
=/ kp (mod rand n.domain.c)
?< =(0 kp)
=/ rr (mul-point-scalar g.domain.c kp)
=/ k
?: =(0 (mod y.rr 2))
kp
(sub n.domain.c kp)
=/ e
%- mod
:_ n.domain.c
%+ tagged-hash 'BIP0340/challenge'
:- 96
(rep 8 ~[m x.pp x.rr])
=/ sig
%^ cat 8
(mod (add k (mul e d)) n.domain.c)
x.rr
?> (verify x.pp m sig)
sig
::
++ verify :: schnorr verify
~/ %sove
|= [pk=@I m=@I sig=@J]
^- ?
?> (gte 32 (met 3 pk))
?> (gte 32 (met 3 m))
?> (gte 64 (met 3 sig))
=/ c curve
=/ pup (lift-x pk)
?~ pup
%.n
=/ pp u.pup
=/ r (cut 8 [1 1] sig)
?: (gte r p.domain.c)
%.n
=/ s (end 8 sig)
?: (gte s n.domain.c)
%.n
=/ e
%- mod
:_ n.domain.c
%+ tagged-hash 'BIP0340/challenge'
:- 96
(rep 8 ~[m x.pp r])
=/ aa
(mul-point-scalar g.domain.c s)
=/ bb
(mul-point-scalar pp (sub n.domain.c e))
?: &(=(x.aa x.bb) !=(y.aa y.bb)) :: infinite?
%.n
=/ rr (add-points aa bb)
?. =(0 (mod y.rr 2))
%.n
=(r x.rr)
--
--
--
::
@ -4422,7 +4528,7 @@
:: :: ++chrd:de-xml:html
++ chrd :: character data
%+ cook |=(a=tape ^-(mars ;/(a)))
(plus ;~(less doq ;~(pose (just `@`10) escp)))
(plus ;~(pose (just `@`10) escp))
:: :: ++comt:de-xml:html
++ comt :: comments
=- (ifix [(jest '<!--') (jest '-->')] (star -))

View File

@ -0,0 +1,72 @@
:: Creates a snapshot of the azimuth state and its indices
:: (owners and sposnors) from a list of ethereum logs
::
/- spider, *dice
/+ strand,
azimuth,
strandio,
naive,
lib=naive-transactions,
ethereum,
dice
/* logs %eth-logs /app/azimuth/logs/eth-logs
=, strand=strand:spider
::
=> |% +$ card card:agent:gall
+$ task task:clay
+$ id id:block:jael
+$ events (list event-log:rpc:ethereum)
--
::
^- thread:spider
|= arg=vase
=/ m (strand ,vase)
^- form:m
=+ !<([~ =net file-name=@t] arg)
::
=/ [azimuth-contract=@ux chain-id=@]
[azimuth chain-id]:(get-network:dice net)
::
%- %- slog :_ ~
leaf+"azimuth: creating snapshot with {<(lent logs)>} events"
::
=/ [=id nas=^state:naive]
%+ roll `events`logs
|= [log=event-log:rpc:ethereum =id nas=^state:naive]
?~ mined.log
id^nas
=/ =^input:naive
:- block-number.u.mined.log
?: =(azimuth-contract address.log)
:- %log
[address.log (data-to-hex:dice data.log) topics.log]
?~ input.u.mined.log
[%bat *@]
[%bat u.input.u.mined.log]
=. id
?. (gth block-number.u.mined.log number.id)
id
[block-hash block-number]:u.mined.log
=^ * nas
(%*(. naive lac |) verifier:lib chain-id nas input)
id^nas
::
=/ [=sponsors =owners] (create-indices:dice nas)
::
%- %- slog
:~ leaf+"points: {<~(wyt by points.nas)>}"
leaf+"sponsors: {<~(wyt by sponsors)>}"
leaf+"owners: {<~(wyt by owners)>}"
leaf+"block-number: {<number.id>}"
leaf+"block-hash: {<hash.id>}"
==
::
=/ =path /app/azimuth/[file-name]/azimuth-snapshot
=/ =cage
:- %azimuth-snapshot
!> ^- snap-state
[%0 id nas owners sponsors]
=/ =task [%info %base %& [path %ins cage]~]
=/ =card [%pass /next %arvo %c task]
;< ~ bind:m (send-raw-card:strandio card)
(pure:m !>('azimuth logs processed'))

View File

@ -0,0 +1,43 @@
:: Creates a snapshot of the azimuth state and its indices
:: (owners and sposnors) from scrying /app/azimuth
::
::
/- spider, *dice
/+ strand, strandio, naive, ethereum, dice
=, strand=strand:spider
=, jael
::
=> |% +$ card card:agent:gall
+$ task task:clay
+$ events (list event-log:rpc:ethereum)
--
::
^- thread:spider
|= arg=vase
=/ m (strand ,vase)
^- form:m
=+ !<([~ file-name=@t] arg)
::
;< nas=^state:naive bind:m (scry:strandio ^state:naive /gx/azimuth/nas/noun)
;< =owners bind:m (scry:strandio owners /gx/azimuth/own/noun)
;< =sponsors bind:m (scry:strandio sponsors /gx/azimuth/spo/noun)
;< =events bind:m (scry:strandio events /gx/azimuth/logs/noun)
=/ =id:block (last-block-id:dice events)
::
%- %- slog
:~ leaf+"points: {<~(wyt by points.nas)>}"
leaf+"sponsors: {<~(wyt by sponsors)>}"
leaf+"owners: {<~(wyt by owners)>}"
leaf+"block-number: {<number.id>}"
leaf+"block-hash: {<hash.id>}"
==
::
=/ =path /app/azimuth/[file-name]/azimuth-snapshot
=/ =cage
:- %azimuth-snapshot
!> ^- snap-state
[%0 id nas owners sponsors]
=/ =task [%info %base %& [path %ins cage]~]
=/ =card [%pass /next %arvo %c task]
;< ~ bind:m (send-raw-card:strandio card)
(pure:m !>('azimuth state saved'))

View File

@ -82,8 +82,8 @@
|= [pup=watchpup =latest=number:block]
=/ m (strand:strandio ,watchpup)
^- form:m
=/ zoom-margin=number:block 0 :: TODO: 30!
=/ zoom-step=number:block 100.000
=/ zoom-margin=number:block 30
=/ zoom-step=number:block 100.000
?: (lth latest-number (add number.pup zoom-margin))
(pure:m pup)
=/ up-to-number=number:block

View File

@ -9,32 +9,40 @@
=/ m (strand:strandio ,vase)
|^
^- form:m
:: =* not-sent (pure:m !>(%.n^next-gas-price))
::
=/ =address:ethereum (address-from-prv:key:ethereum pk)
;< expected-nonce=@ud bind:m
(get-next-nonce:ethio endpoint address)
:: if chain expects a different nonce, don't send this transaction
::
?. =(nonce expected-nonce)
~& [%unexpected-nonce nonce expected+expected-nonce]
(pure:m !>(%.n^[%not-sent %unexpected-nonce]))
:: if a gas-price of 0 was specified, fetch the recommended one
::
;< use-gas-price=@ud bind:m
?: =(0 next-gas-price) fetch-gas-price
(pure:(strand:strandio @ud) next-gas-price)
::
=/ batch-data=octs
%+ cad:naive 3
%- flop
%+ roll txs
|= [=raw-tx:naive out=(list octs)]
[raw.raw-tx 65^sig.raw-tx out]
:: TODO: keep this to avoid sending bad batches or disregard?
:: if the batch is malformed, emit error to kick it out of sending
::
?~ (parse-roll:naive q.batch-data)
(pure:m !>(%.n^[%not-sent %batch-parse-error]))
:: if chain expects a different nonce, don't send this transaction
::
?. =(nonce expected-nonce)
~& >>> [%unexpected-nonce nonce expected+expected-nonce]
%- pure:m
!> ^- [%.n @tas @t]
:+ %.n
%not-sent
?: (lth expected-nonce nonce)
:: if ahead, it will use the same next-gas-price when resending
::
%ahead-nonce
:: if behind, start out-of-sync flow
::
%behind-nonce
:: if a gas-price of 0 was specified, fetch the recommended one
::
;< use-gas-price=@ud bind:m
?: =(0 next-gas-price) fetch-gas-price
(pure:(strand:strandio @ud) next-gas-price)
::
:: each l2 signature is 65 bytes + XX bytes for the raw data
:: from the ethereum yellow paper:
@ -72,7 +80,8 @@
:: log batch tx-hash to getTransactionReceipt(tx-hash)
::
~? &(?=(%result -.response) ?=(%s -.res.response))
^-([nonce=@ud batch-hash=@t] nonce^(so:dejs:format res.response))
^- [nonce=@ud batch-hash=@t gas=@ud]
nonce^(so:dejs:format res.response)^use-gas-price
%- pure:m
!> ^- (each @ud [term @t])
:: TODO: capture if the tx fails (e.g. Runtime Error: revert)
@ -101,10 +110,13 @@
;< rep=(unit client-response:iris) bind:m
take-maybe-response:strandio
=* fallback
~& %fallback-gas-price
(pure:m 10.000.000.000)
~& >> %fallback-gas-price
(pure:m fallback-gas-price)
?. ?& ?=([~ %finished *] rep)
?=(^ full-file.u.rep)
:: get suggested price only for mainnet txs
::
=(chain-id 1)
==
fallback
?~ jon=(de-json:html q.data.u.full-file.u.rep)
@ -115,7 +127,7 @@
(mul 1.000.000.000 u.res) ::NOTE gwei to wei
%. u.jon
=, dejs-soft:format
(ot 'result'^(ot 'FastGasPrice'^ni ~) ~)
(ot 'result'^(ot 'FastGasPrice'^(su dem) ~) ~)
::
++ send-batch
|= [endpoint=@ta batch=@ux]

View File

@ -116,4 +116,237 @@
3d07.03a9.9925.0581.
f7de.cd5e.f0f4.f809
==
++ test-schnorr
=> |%
+$ case-sec
$: sec=@
pub=@
aux=@
mes=@
sig=@
==
+$ case-pub
$: pub=@
mes=@
sig=@
res=?
==
--
=< %+ category "bip-0340 vectors"
(zing :(weld t1 t2 t3))
=/ cases-sec=(list case-sec)
:~
:* 0x3
0xf930.8a01.9258.c310.4934.4f85.f89d.5229.
b531.c845.836f.99b0.8601.f113.bce0.36f9
0
0
0xe907.831f.8084.8d10.69a5.371b.4024.1036.
4bdf.1c5f.8307.b008.4c55.f1ce.2dca.8215.
25f6.6a4a.85ea.8b71.e482.a74f.382d.2ce5.
ebee.e8fd.b217.2f47.7df4.900d.3105.36c0
==
:* 0xb7e1.5162.8aed.2a6a.bf71.5880.9cf4.f3c7.
62e7.160f.38b4.da56.a784.d904.5190.cfef
0xdff1.d77f.2a67.1c5f.3618.3726.db23.41be.
58fe.ae1d.a2de.ced8.4324.0f7b.502b.a659
1
0x243f.6a88.85a3.08d3.1319.8a2e.0370.7344.
a409.3822.299f.31d0.082e.fa98.ec4e.6c89
0x6896.bd60.eeae.296d.b48a.229f.f71d.fe07.
1bde.413e.6d43.f917.dc8d.cf8c.78de.3341.
8906.d11a.c976.abcc.b20b.0912.92bf.f4ea.
897e.fcb6.39ea.871c.fa95.f6de.339e.4b0a
==
:* 0xc90f.daa2.2168.c234.c4c6.628b.80dc.1cd1.
2902.4e08.8a67.cc74.020b.bea6.3b14.e5c9
0xdd30.8afe.c577.7e13.121f.a72b.9cc1.b7cc.
0139.7153.09b0.86c9.60e1.8fd9.6977.4eb8
0xc87a.a538.24b4.d7ae.2eb0.35a2.b5bb.bccc.
080e.76cd.c6d1.692c.4b0b.62d7.98e6.d906
0x7e2d.58d8.b3bc.df1a.bade.c782.9054.f90d.
da98.05aa.b56c.7733.3024.b9d0.a508.b75c
0x5831.aaee.d7b4.4bb7.4e5e.ab94.ba9d.4294.
c49b.cf2a.6072.8d8b.4c20.0f50.dd31.3c1b.
ab74.5879.a5ad.954a.72c4.5a91.c3a5.1d3c.
7ade.a98d.82f8.481e.0e1e.0367.4a6f.3fb7
==
:* 0xb43.2b26.7793.7381.aef0.5bb0.2a66.ecd0.
1277.3062.cf3f.a254.9e44.f58e.d240.1710
0x25d1.dff9.5105.f525.3c40.22f6.28a9.96ad.
3a0d.95fb.f21d.468a.1b33.f8c1.60d8.f517
0xffff.ffff.ffff.ffff.ffff.ffff.ffff.ffff.
ffff.ffff.ffff.ffff.ffff.ffff.ffff.ffff
0xffff.ffff.ffff.ffff.ffff.ffff.ffff.ffff.
ffff.ffff.ffff.ffff.ffff.ffff.ffff.ffff
0x7eb0.5097.57e2.46f1.9449.8856.5161.1cb9.
65ec.c1a1.87dd.51b6.4fda.1edc.9637.d5ec.
9758.2b9c.b13d.b393.3705.b32b.a982.af5a.
f25f.d788.81eb.b327.71fc.5922.efc6.6ea3
==
==
=/ t1
%+ turn cases-sec
|= case-sec
^- tang
%+ expect-eq
!> sig
!> (sign:schnorr:ecc sec mes aux)
=/ t2
%+ turn cases-sec
|= case-sec
^- tang
%- expect
!> (verify:schnorr:ecc pub mes sig)
=/ cases-pub=(list case-pub)
:~
:* 0xd69c.3509.bb99.e412.e68b.0fe8.544e.7283.
7dfa.3074.6d8b.e2aa.6597.5f29.d22d.c7b9
0x4df3.c3f6.8fcc.83b2.7e9d.42c9.0431.a724.
99f1.7875.c81a.599b.566c.9889.b969.6703
0x3b.78ce.563f.89a0.ed94.14f5.aa28.ad0d.
96d6.795f.9c63.76af.b154.8af6.03b3.eb45.
c9f8.207d.ee10.60cb.71c0.4e80.f593.060b.
07d2.8308.d7f4
%.y
==
:* 0xeefd.ea4c.db67.7750.a420.fee8.07ea.cf21.
eb98.98ae.79b9.7687.66e4.faa0.4a2d.4a34
0x243f.6a88.85a3.08d3.1319.8a2e.0370.7344.
a409.3822.299f.31d0.082e.fa98.ec4e.6c89
0x6cff.5c3b.a86c.69ea.4b73.76f3.1a9b.cb4f.
74c1.9760.89b2.d996.3da2.e554.3e17.7769.
69e8.9b4c.5564.d003.4910.6b84.9778.5dd7.
d1d7.13a8.ae82.b32f.a79d.5f7f.c407.d39b
%.n
==
:* 0xdff1.d77f.2a67.1c5f.3618.3726.db23.41be.
58fe.ae1d.a2de.ced8.4324.0f7b.502b.a659
0x243f.6a88.85a3.08d3.1319.8a2e.0370.7344.
a409.3822.299f.31d0.082e.fa98.ec4e.6c89
0xfff9.7bd5.755e.eea4.2045.3a14.3552.35d3.
82f6.472f.8568.a18b.2f05.7a14.6029.7556.
3cc2.7944.640a.c607.cd10.7ae1.0923.d9ef.
7a73.c643.e166.be5e.beaf.a34b.1ac5.53e2
%.n
==
:* 0xdff1.d77f.2a67.1c5f.3618.3726.db23.41be.
58fe.ae1d.a2de.ced8.4324.0f7b.502b.a659
0x243f.6a88.85a3.08d3.1319.8a2e.0370.7344.
a409.3822.299f.31d0.082e.fa98.ec4e.6c89
0x1fa6.2e33.1edb.c21c.3947.92d2.ab11.00a7.
b432.b013.df3f.6ff4.f99f.cb33.e0e1.515f.
2889.0b3e.db6e.7189.b630.448b.515c.e4f8.
622a.954c.fe54.5735.aaea.5134.fccd.b2bd
%.n
==
:* 0xdff1.d77f.2a67.1c5f.3618.3726.db23.41be.
58fe.ae1d.a2de.ced8.4324.0f7b.502b.a659
0x243f.6a88.85a3.08d3.1319.8a2e.0370.7344.
a409.3822.299f.31d0.082e.fa98.ec4e.6c89
0x6cff.5c3b.a86c.69ea.4b73.76f3.1a9b.cb4f.
74c1.9760.89b2.d996.3da2.e554.3e17.7769.
9617.64b3.aa9b.2ffc.b6ef.947b.6887.a226.
e8d7.c93e.00c5.ed0c.1834.ff0d.0c2e.6da6
%.n
==
:* 0xdff1.d77f.2a67.1c5f.3618.3726.db23.41be.
58fe.ae1d.a2de.ced8.4324.0f7b.502b.a659
0x243f.6a88.85a3.08d3.1319.8a2e.0370.7344.
a409.3822.299f.31d0.082e.fa98.ec4e.6c89
0x123d.da83.28af.9c23.a94c.1fee.cfd1.23ba.
4fb7.3476.f0d5.94dc.b65c.6425.bd18.6051
%.n
==
:* 0xdff1.d77f.2a67.1c5f.3618.3726.db23.41be.
58fe.ae1d.a2de.ced8.4324.0f7b.502b.a659
0x243f.6a88.85a3.08d3.1319.8a2e.0370.7344.
a409.3822.299f.31d0.082e.fa98.ec4e.6c89
0x1.7615.fbaf.5ae2.8864.013c.0997.42de.
adb4.dba8.7f11.ac67.54f9.3780.d5a1.837c.
f197
%.n
==
:* 0xdff1.d77f.2a67.1c5f.3618.3726.db23.41be.
58fe.ae1d.a2de.ced8.4324.0f7b.502b.a659
0x243f.6a88.85a3.08d3.1319.8a2e.0370.7344.
a409.3822.299f.31d0.082e.fa98.ec4e.6c89
0x4a29.8dac.ae57.395a.15d0.795d.dbfd.1dcb.
564d.a82b.0f26.9bc7.0a74.f822.0429.ba1d.
69e8.9b4c.5564.d003.4910.6b84.9778.5dd7.
d1d7.13a8.ae82.b32f.a79d.5f7f.c407.d39b
%.n
==
:* 0xdff1.d77f.2a67.1c5f.3618.3726.db23.41be.
58fe.ae1d.a2de.ced8.4324.0f7b.502b.a659
0x243f.6a88.85a3.08d3.1319.8a2e.0370.7344.
a409.3822.299f.31d0.082e.fa98.ec4e.6c89
0xffff.ffff.ffff.ffff.ffff.ffff.ffff.ffff.
ffff.ffff.ffff.ffff.ffff.fffe.ffff.fc2f.
69e8.9b4c.5564.d003.4910.6b84.9778.5dd7.
d1d7.13a8.ae82.b32f.a79d.5f7f.c407.d39b
%.n
==
:* 0xdff1.d77f.2a67.1c5f.3618.3726.db23.41be.
58fe.ae1d.a2de.ced8.4324.0f7b.502b.a659
0x243f.6a88.85a3.08d3.1319.8a2e.0370.7344.
a409.3822.299f.31d0.082e.fa98.ec4e.6c89
0x6cff.5c3b.a86c.69ea.4b73.76f3.1a9b.cb4f.
74c1.9760.89b2.d996.3da2.e554.3e17.7769.
ffff.ffff.ffff.ffff.ffff.ffff.ffff.fffe.
baae.dce6.af48.a03b.bfd2.5e8c.d036.4141
%.n
==
:* 0xffff.ffff.ffff.ffff.ffff.ffff.ffff.ffff.
ffff.ffff.ffff.ffff.ffff.fffe.ffff.fc30
0x243f.6a88.85a3.08d3.1319.8a2e.0370.7344.
a409.3822.299f.31d0.082e.fa98.ec4e.6c89
0x6cff.5c3b.a86c.69ea.4b73.76f3.1a9b.cb4f.
74c1.9760.89b2.d996.3da2.e554.3e17.7769.
69e8.9b4c.5564.d003.4910.6b84.9778.5dd7.
d1d7.13a8.ae82.b32f.a79d.5f7f.c407.d39b
%.n
==
==
:_ .
^= t3
%+ turn cases-pub
|= case-pub
^- tang
%+ expect-eq
!> res
!> (verify:schnorr:ecc pub mes sig)
++ test-schnorr-bounds
=> |% +$ case [sec=@ pub=@ aux=@ mes=@ sig=@] --
=< %+ category "bounds"
(zing (weld t1 t2))
=/ too-big
0xff.ffff.ffff.ffff.ffff.ffff.ffff.ffff.ffff.
ffff.ffff.ffff.ffff.ffff.ffff.ffff.ffff
=/ big-sig
0xff.ffff.ffff.ffff.ffff.ffff.ffff.ffff.ffff.
ffff.ffff.ffff.ffff.ffff.ffff.ffff.ffff.
ffff.ffff.ffff.ffff.ffff.ffff.ffff.ffff.
ffff.ffff.ffff.ffff.ffff.ffff.ffff.ffff
=/ cases-big-sec=(list case)
:~ [too-big 0 0 0 0]
[1 0 too-big 0 0]
[1 0 0 too-big 0]
==
=/ cases-big-pub=(list case)
:~ [0 too-big 0 0 0]
[0 0 0 too-big 0]
[0 0 0 0 big-sig]
==
=/ t1
%+ turn cases-big-sec
|= case
%- expect-fail
|. (sign:schnorr:ecc sec mes aux)
:_ .
^= t2
%+ turn cases-big-pub
|= case
%- expect-fail
|. (verify:schnorr:ecc pub mes sig)
--

View File

@ -87,7 +87,7 @@
0x223c.067f.8cf2.8ae1.73ee.5caf.ea60.ca44.c335.fecb
::
++ ecliptic
0xa5b6.109a.d2d3.5191.b3bc.32c0.0e45.26be.56fe.321f
0x33ee.cbf9.0847.8c10.6146.26a9.d304.bfe1.8b78.dd73
::
++ linear-star-release
0x86cd.9cd0.992f.0423.1751.e376.1de4.5cec.ea5d.1801

View File

@ -1,5 +1,6 @@
:: |pill: helper functions for making pills
::
/- dice
^?
|%
::
@ -80,7 +81,13 @@
=/ pax (weld bas lyt)
=/ lon .^(arch %cy pax)
=? hav ?=(^ fil.lon)
:_(hav [lyt mark=;;(@tas (head tyl)) noun=.^(* %cx pax)])
:_ hav
:- lyt
?. ?=([%azimuth-snapshot *] tyl)
[mark=;;(@tas (head tyl)) noun=.^(* %cx pax)]
=; convert
mime/(convert .^(snap-state:dice %cx pax))
.^($-(snap-state:dice mime) %cf (weld bas /azimuth-snapshot/mime))
=/ all ~(tap by dir.lon)
|- ^+ hav
?~ all hav

View File

@ -349,7 +349,7 @@
++ on-peek
|= =path
^- (unit (unit cage))
?. =(/x/dbug/state path) ~
?. =(/x/dbug/state path) (on-peek:og path)
``noun+(slop on-save:og !>(shoe=state))
::
++ on-agent

View File

@ -1,10 +1,10 @@
:~ title+'System'
info+'An app launcher for Urbit.'
color+0xee.5432
glob-http+['https://bootstrap.urbit.org/glob-0v4.64ana.19ug9.ik7l6.og080.68ce4.glob' 0v4.64ana.19ug9.ik7l6.og080.68ce4]
glob-http+['https://bootstrap.urbit.org/glob-0v5.1o2c9.g1btf.nandl.703oh.40up1.glob' 0v5.1o2c9.g1btf.nandl.703oh.40up1]
::glob-ames+~zod^0v0
base+'grid'
version+[1 0 2]
version+[1 0 3]
website+'https://tlon.io'
license+'MIT'
==

View File

@ -8,15 +8,15 @@
"name": "landscape",
"version": "0.0.0",
"dependencies": {
"@radix-ui/react-checkbox": "^0.1.5",
"@radix-ui/react-dialog": "^0.0.20",
"@radix-ui/react-dropdown-menu": "^0.0.23",
"@radix-ui/react-icons": "^1.1.0",
"@radix-ui/react-polymorphic": "^0.0.13",
"@radix-ui/react-portal": "^0.0.15",
"@radix-ui/react-toggle": "^0.0.10",
"@tlon/sigil-js": "^1.4.4",
"@types/lodash": "^4.14.172",
"@urbit/api": "^2.0.0",
"@urbit/http-api": "^2.0.0",
"big-integer": "^1.6.48",
"classnames": "^2.3.1",
"clipboard-copy": "^4.0.1",
@ -385,9 +385,9 @@
}
},
"node_modules/@babel/runtime": {
"version": "7.14.8",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
"integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
"version": "7.17.2",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz",
"integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==",
"dependencies": {
"regenerator-runtime": "^0.13.4"
},
@ -531,11 +531,6 @@
"integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
"dev": true
},
"node_modules/@microsoft/fetch-event-source": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz",
"integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA=="
},
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -601,6 +596,138 @@
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-checkbox": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-0.1.5.tgz",
"integrity": "sha512-M8Y4dSXsKSbF+FryG5VvZKr/1MukMVG7swq9p5s7wYb8Rvn0UM0rQ5w8BWmSWSV4BL/gbJdhwVCznwXXlgZRZg==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/primitive": "0.1.0",
"@radix-ui/react-compose-refs": "0.1.0",
"@radix-ui/react-context": "0.1.1",
"@radix-ui/react-label": "0.1.5",
"@radix-ui/react-presence": "0.1.2",
"@radix-ui/react-primitive": "0.1.4",
"@radix-ui/react-use-controllable-state": "0.1.0",
"@radix-ui/react-use-previous": "0.1.1",
"@radix-ui/react-use-size": "0.1.1"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/primitive": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-0.1.0.tgz",
"integrity": "sha512-tqxZKybwN5Fa3VzZry4G6mXAAb9aAqKmPtnVbZpL0vsBwvOHTBwsjHVPXylocYLwEtBY9SCe665bYnNB515uoA==",
"dependencies": {
"@babel/runtime": "^7.13.10"
}
},
"node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-compose-refs": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-0.1.0.tgz",
"integrity": "sha512-eyclbh+b77k+69Dk72q3694OHrn9B3QsoIRx7ywX341U9RK1ThgQjMFZoPtmZNQTksXHLNEiefR8hGVeFyInGg==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-context": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-0.1.1.tgz",
"integrity": "sha512-PkyVX1JsLBioeu0jB9WvRpDBBLtLZohVDT3BB5CTSJqActma8S8030P57mWZb4baZifMvN7KKWPAA40UmWKkQg==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-presence": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-0.1.2.tgz",
"integrity": "sha512-3BRlFZraooIUfRlyN+b/Xs5hq1lanOOo/+3h6Pwu2GMFjkGKKa4Rd51fcqGqnVlbr3jYg+WLuGyAV4KlgqwrQw==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "0.1.0",
"@radix-ui/react-use-layout-effect": "0.1.0"
},
"peerDependencies": {
"react": ">=16.8"
}
},
"node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-primitive": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-0.1.4.tgz",
"integrity": "sha512-6gSl2IidySupIMJFjYnDIkIWRyQdbu/AHK7rbICPani+LW4b0XdxBXc46og/iZvuwW8pjCS8I2SadIerv84xYA==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-slot": "0.1.2"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-slot": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-0.1.2.tgz",
"integrity": "sha512-ADkqfL+agEzEguU3yS26jfB50hRrwf7U4VTwAOZEmi/g+ITcBWe12yM46ueS/UCIMI9Py+gFUaAdxgxafFvY2Q==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "0.1.0"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-use-callback-ref": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-0.1.0.tgz",
"integrity": "sha512-Va041McOFFl+aV+sejvl0BS2aeHx86ND9X/rVFmEFQKTXCp6xgUK0NGUAGcgBlIjnJSbMYPGEk1xKSSlVcN2Aw==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-use-controllable-state": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-0.1.0.tgz",
"integrity": "sha512-zv7CX/PgsRl46a52Tl45TwqwVJdmqnlQEQhaYMz/yBOD2sx2gCkCFSoF/z9mpnYWmS6DTLNTg5lIps3fV6EnXg==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-use-callback-ref": "0.1.0"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-use-layout-effect": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-0.1.0.tgz",
"integrity": "sha512-+wdeS51Y+E1q1Wmd+1xSSbesZkpVj4jsg0BojCbopWvgq5iBvixw5vgemscdh58ep98BwUbsFYnrywFhV9yrVg==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-checkbox/node_modules/@radix-ui/react-use-size": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-0.1.1.tgz",
"integrity": "sha512-pTgWM5qKBu6C7kfKxrKPoBI2zZYZmp2cSXzpUiGM3qEBQlMLtYhaY2JXdXUCxz+XmD1YEjc8oRwvyfsD4AG4WA==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-collection": {
"version": "0.0.15",
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-0.0.15.tgz",
@ -726,6 +853,14 @@
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-icons": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.1.0.tgz",
"integrity": "sha512-nhctV9YKN8G4HfkS3p03ml+osTBDMGKImaAJTm666hymtaWEgIPiqL7F53ivDqIO4A+20ERwUiiKJ8h3XK7uAg==",
"peerDependencies": {
"react": "^16.x || ^17.x"
}
},
"node_modules/@radix-ui/react-id": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-0.0.6.tgz",
@ -737,6 +872,90 @@
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-label": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-0.1.5.tgz",
"integrity": "sha512-Au9+n4/DhvjR0IHhvZ1LPdx/OW+3CGDie30ZyCkbSHIuLp4/CV4oPPGBwJ1vY99Jog3zyQhsGww9MXj8O9Aj/A==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "0.1.0",
"@radix-ui/react-context": "0.1.1",
"@radix-ui/react-id": "0.1.5",
"@radix-ui/react-primitive": "0.1.4"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-compose-refs": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-0.1.0.tgz",
"integrity": "sha512-eyclbh+b77k+69Dk72q3694OHrn9B3QsoIRx7ywX341U9RK1ThgQjMFZoPtmZNQTksXHLNEiefR8hGVeFyInGg==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-context": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-0.1.1.tgz",
"integrity": "sha512-PkyVX1JsLBioeu0jB9WvRpDBBLtLZohVDT3BB5CTSJqActma8S8030P57mWZb4baZifMvN7KKWPAA40UmWKkQg==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-id": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-0.1.5.tgz",
"integrity": "sha512-IPc4H/63bes0IZ1GJJozSEkSWcDyhNGtKFWUpJ+XtaLyQ1X3x7Mf6fWwWhDcpqlYEP+5WtAvfqcyEsyjP+ZhBQ==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-use-layout-effect": "0.1.0"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-primitive": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-0.1.4.tgz",
"integrity": "sha512-6gSl2IidySupIMJFjYnDIkIWRyQdbu/AHK7rbICPani+LW4b0XdxBXc46og/iZvuwW8pjCS8I2SadIerv84xYA==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-slot": "0.1.2"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-slot": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-0.1.2.tgz",
"integrity": "sha512-ADkqfL+agEzEguU3yS26jfB50hRrwf7U4VTwAOZEmi/g+ITcBWe12yM46ueS/UCIMI9Py+gFUaAdxgxafFvY2Q==",
"dependencies": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "0.1.0"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-use-layout-effect": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-0.1.0.tgz",
"integrity": "sha512-+wdeS51Y+E1q1Wmd+1xSSbesZkpVj4jsg0BojCbopWvgq5iBvixw5vgemscdh58ep98BwUbsFYnrywFhV9yrVg==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-menu": {
"version": "0.0.22",
"resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-0.0.22.tgz",
@ -952,6 +1171,17 @@
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-use-previous": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-0.1.1.tgz",
"integrity": "sha512-O/ZgrDBr11dR8rhO59ED8s5zIXBRFi8MiS+CmFGfi7MJYdLbfqVOmQU90Ghf87aifEgWe6380LA69KBneaShAg==",
"dependencies": {
"@babel/runtime": "^7.13.10"
},
"peerDependencies": {
"react": "^16.8 || ^17.0"
}
},
"node_modules/@radix-ui/react-use-rect": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-0.0.7.tgz",
@ -1292,39 +1522,6 @@
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@urbit/api": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@urbit/api/-/api-2.0.0.tgz",
"integrity": "sha512-shELBuW1cjXYP2DrJyRMomIh5oMDkwLgNx8AWnVY2FhZUgsojRKiWmJ/bdO/mGnFZUch0tPBAl6bawwVPkBPDg==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@types/lodash": "^4.14.168",
"@urbit/eslint-config": "^1.0.3",
"big-integer": "^1.6.48",
"immer": "^9.0.1",
"lodash": "^4.17.20",
"urbit-ob": "^5.0.1"
}
},
"node_modules/@urbit/eslint-config": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@urbit/eslint-config/-/eslint-config-1.0.3.tgz",
"integrity": "sha512-4mGd4GzzF+JMG/eAhjDQBjyVYo0xNbpcC7I16GouINLIuz5LJmNZ98SRQaOpfnsGIfTiZxwyZnfIX20orvWMxQ=="
},
"node_modules/@urbit/http-api": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@urbit/http-api/-/http-api-2.0.0.tgz",
"integrity": "sha512-rwi+6sNbx+WPA1E+cwsHR4kQYtlNDbObPZ8BXCwHc9lWN1FJTbZNkjCtXBR3KMelvFlf4ftR+8EkdiWTfFOnoQ==",
"dependencies": {
"@babel/runtime": "^7.12.5",
"@microsoft/fetch-event-source": "^2.0.0",
"browser-or-node": "^1.3.0",
"browserify-zlib": "^0.2.0",
"buffer": "^6.0.3",
"stream-browserify": "^3.0.0",
"stream-http": "^3.1.1"
}
},
"node_modules/@urbit/vite-plugin-urbit": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/@urbit/vite-plugin-urbit/-/vite-plugin-urbit-0.7.1.tgz",
@ -1655,25 +1852,6 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/big-integer": {
"version": "1.6.49",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.49.tgz",
@ -1718,19 +1896,6 @@
"node": ">=8"
}
},
"node_modules/browser-or-node": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-1.3.0.tgz",
"integrity": "sha512-0F2z/VSnLbmEeBcUrSuDH5l0HxTXdQQzLjkmBR4cYfvg1zJrKSlmIZFqyFR8oX0NrwPhy3c3HQ6i3OxMbew4Tg=="
},
"node_modules/browserify-zlib": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
"integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
"dependencies": {
"pako": "~1.0.5"
}
},
"node_modules/browserslist": {
"version": "4.17.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.3.tgz",
@ -1754,34 +1919,6 @@
"url": "https://opencollective.com/browserslist"
}
},
"node_modules/buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"node_modules/builtin-status-codes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
"integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug="
},
"node_modules/bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
@ -4337,25 +4474,6 @@
"node": ">=0.10.0"
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
@ -4454,7 +4572,8 @@
"node_modules/inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"node_modules/inquirer": {
"version": "6.5.2",
@ -5925,11 +6044,6 @@
"node": ">=4"
}
},
"node_modules/pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
},
"node_modules/parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@ -6538,6 +6652,7 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@ -7027,26 +7142,6 @@
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
"dev": true
},
"node_modules/stream-browserify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz",
"integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==",
"dependencies": {
"inherits": "~2.0.4",
"readable-stream": "^3.5.0"
}
},
"node_modules/stream-http": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz",
"integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==",
"dependencies": {
"builtin-status-codes": "^3.0.0",
"inherits": "^2.0.4",
"readable-stream": "^3.6.0",
"xtend": "^4.0.2"
}
},
"node_modules/strict-uri-encode": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
@ -7059,6 +7154,7 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dev": true,
"dependencies": {
"safe-buffer": "~5.2.0"
}
@ -7067,6 +7163,7 @@
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true,
"funding": [
{
"type": "github",
@ -7672,7 +7769,8 @@
"node_modules/util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"dev": true
},
"node_modules/v8-compile-cache": {
"version": "2.3.0",
@ -7873,6 +7971,7 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"dev": true,
"engines": {
"node": ">=0.4"
}
@ -8171,9 +8270,9 @@
}
},
"@babel/runtime": {
"version": "7.14.8",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.8.tgz",
"integrity": "sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg==",
"version": "7.17.2",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.17.2.tgz",
"integrity": "sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw==",
"requires": {
"regenerator-runtime": "^0.13.4"
}
@ -8283,11 +8382,6 @@
"integrity": "sha512-wdppn25U8z/2yiaT6YGquE6X8sSv7hNMWSXYSSU1jGv/yd6XqjXgTDJ8KP4NgjTXfJ3GbRjeeb8RTV7a/VpM+w==",
"dev": true
},
"@microsoft/fetch-event-source": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@microsoft/fetch-event-source/-/fetch-event-source-2.0.1.tgz",
"integrity": "sha512-W6CLUJ2eBMw3Rec70qrsEW0jOm/3twwJv21mrmj2yORiaVmVYGS4sSS5yUwvQc1ZlDLYGPnClVWmUUMagKNsfA=="
},
"@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@ -8341,6 +8435,110 @@
"@radix-ui/react-primitive": "0.0.15"
}
},
"@radix-ui/react-checkbox": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-0.1.5.tgz",
"integrity": "sha512-M8Y4dSXsKSbF+FryG5VvZKr/1MukMVG7swq9p5s7wYb8Rvn0UM0rQ5w8BWmSWSV4BL/gbJdhwVCznwXXlgZRZg==",
"requires": {
"@babel/runtime": "^7.13.10",
"@radix-ui/primitive": "0.1.0",
"@radix-ui/react-compose-refs": "0.1.0",
"@radix-ui/react-context": "0.1.1",
"@radix-ui/react-label": "0.1.5",
"@radix-ui/react-presence": "0.1.2",
"@radix-ui/react-primitive": "0.1.4",
"@radix-ui/react-use-controllable-state": "0.1.0",
"@radix-ui/react-use-previous": "0.1.1",
"@radix-ui/react-use-size": "0.1.1"
},
"dependencies": {
"@radix-ui/primitive": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-0.1.0.tgz",
"integrity": "sha512-tqxZKybwN5Fa3VzZry4G6mXAAb9aAqKmPtnVbZpL0vsBwvOHTBwsjHVPXylocYLwEtBY9SCe665bYnNB515uoA==",
"requires": {
"@babel/runtime": "^7.13.10"
}
},
"@radix-ui/react-compose-refs": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-0.1.0.tgz",
"integrity": "sha512-eyclbh+b77k+69Dk72q3694OHrn9B3QsoIRx7ywX341U9RK1ThgQjMFZoPtmZNQTksXHLNEiefR8hGVeFyInGg==",
"requires": {
"@babel/runtime": "^7.13.10"
}
},
"@radix-ui/react-context": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-0.1.1.tgz",
"integrity": "sha512-PkyVX1JsLBioeu0jB9WvRpDBBLtLZohVDT3BB5CTSJqActma8S8030P57mWZb4baZifMvN7KKWPAA40UmWKkQg==",
"requires": {
"@babel/runtime": "^7.13.10"
}
},
"@radix-ui/react-presence": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-0.1.2.tgz",
"integrity": "sha512-3BRlFZraooIUfRlyN+b/Xs5hq1lanOOo/+3h6Pwu2GMFjkGKKa4Rd51fcqGqnVlbr3jYg+WLuGyAV4KlgqwrQw==",
"requires": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "0.1.0",
"@radix-ui/react-use-layout-effect": "0.1.0"
}
},
"@radix-ui/react-primitive": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-0.1.4.tgz",
"integrity": "sha512-6gSl2IidySupIMJFjYnDIkIWRyQdbu/AHK7rbICPani+LW4b0XdxBXc46og/iZvuwW8pjCS8I2SadIerv84xYA==",
"requires": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-slot": "0.1.2"
}
},
"@radix-ui/react-slot": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-0.1.2.tgz",
"integrity": "sha512-ADkqfL+agEzEguU3yS26jfB50hRrwf7U4VTwAOZEmi/g+ITcBWe12yM46ueS/UCIMI9Py+gFUaAdxgxafFvY2Q==",
"requires": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "0.1.0"
}
},
"@radix-ui/react-use-callback-ref": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-0.1.0.tgz",
"integrity": "sha512-Va041McOFFl+aV+sejvl0BS2aeHx86ND9X/rVFmEFQKTXCp6xgUK0NGUAGcgBlIjnJSbMYPGEk1xKSSlVcN2Aw==",
"requires": {
"@babel/runtime": "^7.13.10"
}
},
"@radix-ui/react-use-controllable-state": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-0.1.0.tgz",
"integrity": "sha512-zv7CX/PgsRl46a52Tl45TwqwVJdmqnlQEQhaYMz/yBOD2sx2gCkCFSoF/z9mpnYWmS6DTLNTg5lIps3fV6EnXg==",
"requires": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-use-callback-ref": "0.1.0"
}
},
"@radix-ui/react-use-layout-effect": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-0.1.0.tgz",
"integrity": "sha512-+wdeS51Y+E1q1Wmd+1xSSbesZkpVj4jsg0BojCbopWvgq5iBvixw5vgemscdh58ep98BwUbsFYnrywFhV9yrVg==",
"requires": {
"@babel/runtime": "^7.13.10"
}
},
"@radix-ui/react-use-size": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-0.1.1.tgz",
"integrity": "sha512-pTgWM5qKBu6C7kfKxrKPoBI2zZYZmp2cSXzpUiGM3qEBQlMLtYhaY2JXdXUCxz+XmD1YEjc8oRwvyfsD4AG4WA==",
"requires": {
"@babel/runtime": "^7.13.10"
}
}
}
},
"@radix-ui/react-collection": {
"version": "0.0.15",
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-0.0.15.tgz",
@ -8440,6 +8638,12 @@
"@radix-ui/react-use-callback-ref": "0.0.5"
}
},
"@radix-ui/react-icons": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-icons/-/react-icons-1.1.0.tgz",
"integrity": "sha512-nhctV9YKN8G4HfkS3p03ml+osTBDMGKImaAJTm666hymtaWEgIPiqL7F53ivDqIO4A+20ERwUiiKJ8h3XK7uAg==",
"requires": {}
},
"@radix-ui/react-id": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-0.0.6.tgz",
@ -8448,6 +8652,71 @@
"@babel/runtime": "^7.13.10"
}
},
"@radix-ui/react-label": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-0.1.5.tgz",
"integrity": "sha512-Au9+n4/DhvjR0IHhvZ1LPdx/OW+3CGDie30ZyCkbSHIuLp4/CV4oPPGBwJ1vY99Jog3zyQhsGww9MXj8O9Aj/A==",
"requires": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "0.1.0",
"@radix-ui/react-context": "0.1.1",
"@radix-ui/react-id": "0.1.5",
"@radix-ui/react-primitive": "0.1.4"
},
"dependencies": {
"@radix-ui/react-compose-refs": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-0.1.0.tgz",
"integrity": "sha512-eyclbh+b77k+69Dk72q3694OHrn9B3QsoIRx7ywX341U9RK1ThgQjMFZoPtmZNQTksXHLNEiefR8hGVeFyInGg==",
"requires": {
"@babel/runtime": "^7.13.10"
}
},
"@radix-ui/react-context": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-0.1.1.tgz",
"integrity": "sha512-PkyVX1JsLBioeu0jB9WvRpDBBLtLZohVDT3BB5CTSJqActma8S8030P57mWZb4baZifMvN7KKWPAA40UmWKkQg==",
"requires": {
"@babel/runtime": "^7.13.10"
}
},
"@radix-ui/react-id": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-0.1.5.tgz",
"integrity": "sha512-IPc4H/63bes0IZ1GJJozSEkSWcDyhNGtKFWUpJ+XtaLyQ1X3x7Mf6fWwWhDcpqlYEP+5WtAvfqcyEsyjP+ZhBQ==",
"requires": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-use-layout-effect": "0.1.0"
}
},
"@radix-ui/react-primitive": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-0.1.4.tgz",
"integrity": "sha512-6gSl2IidySupIMJFjYnDIkIWRyQdbu/AHK7rbICPani+LW4b0XdxBXc46og/iZvuwW8pjCS8I2SadIerv84xYA==",
"requires": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-slot": "0.1.2"
}
},
"@radix-ui/react-slot": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-0.1.2.tgz",
"integrity": "sha512-ADkqfL+agEzEguU3yS26jfB50hRrwf7U4VTwAOZEmi/g+ITcBWe12yM46ueS/UCIMI9Py+gFUaAdxgxafFvY2Q==",
"requires": {
"@babel/runtime": "^7.13.10",
"@radix-ui/react-compose-refs": "0.1.0"
}
},
"@radix-ui/react-use-layout-effect": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-0.1.0.tgz",
"integrity": "sha512-+wdeS51Y+E1q1Wmd+1xSSbesZkpVj4jsg0BojCbopWvgq5iBvixw5vgemscdh58ep98BwUbsFYnrywFhV9yrVg==",
"requires": {
"@babel/runtime": "^7.13.10"
}
}
}
},
"@radix-ui/react-menu": {
"version": "0.0.22",
"resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-0.0.22.tgz",
@ -8617,6 +8886,14 @@
"@babel/runtime": "^7.13.10"
}
},
"@radix-ui/react-use-previous": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-0.1.1.tgz",
"integrity": "sha512-O/ZgrDBr11dR8rhO59ED8s5zIXBRFi8MiS+CmFGfi7MJYdLbfqVOmQU90Ghf87aifEgWe6380LA69KBneaShAg==",
"requires": {
"@babel/runtime": "^7.13.10"
}
},
"@radix-ui/react-use-rect": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-0.0.7.tgz",
@ -8861,39 +9138,6 @@
"eslint-visitor-keys": "^2.0.0"
}
},
"@urbit/api": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@urbit/api/-/api-2.0.0.tgz",
"integrity": "sha512-shELBuW1cjXYP2DrJyRMomIh5oMDkwLgNx8AWnVY2FhZUgsojRKiWmJ/bdO/mGnFZUch0tPBAl6bawwVPkBPDg==",
"requires": {
"@babel/runtime": "^7.12.5",
"@types/lodash": "^4.14.168",
"@urbit/eslint-config": "^1.0.3",
"big-integer": "^1.6.48",
"immer": "^9.0.1",
"lodash": "^4.17.20",
"urbit-ob": "^5.0.1"
}
},
"@urbit/eslint-config": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@urbit/eslint-config/-/eslint-config-1.0.3.tgz",
"integrity": "sha512-4mGd4GzzF+JMG/eAhjDQBjyVYo0xNbpcC7I16GouINLIuz5LJmNZ98SRQaOpfnsGIfTiZxwyZnfIX20orvWMxQ=="
},
"@urbit/http-api": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@urbit/http-api/-/http-api-2.0.0.tgz",
"integrity": "sha512-rwi+6sNbx+WPA1E+cwsHR4kQYtlNDbObPZ8BXCwHc9lWN1FJTbZNkjCtXBR3KMelvFlf4ftR+8EkdiWTfFOnoQ==",
"requires": {
"@babel/runtime": "^7.12.5",
"@microsoft/fetch-event-source": "^2.0.0",
"browser-or-node": "^1.3.0",
"browserify-zlib": "^0.2.0",
"buffer": "^6.0.3",
"stream-browserify": "^3.0.0",
"stream-http": "^3.1.1"
}
},
"@urbit/vite-plugin-urbit": {
"version": "0.7.1",
"resolved": "https://registry.npmjs.org/@urbit/vite-plugin-urbit/-/vite-plugin-urbit-0.7.1.tgz",
@ -9136,11 +9380,6 @@
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true
},
"base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="
},
"big-integer": {
"version": "1.6.49",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.49.tgz",
@ -9176,19 +9415,6 @@
"fill-range": "^7.0.1"
}
},
"browser-or-node": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/browser-or-node/-/browser-or-node-1.3.0.tgz",
"integrity": "sha512-0F2z/VSnLbmEeBcUrSuDH5l0HxTXdQQzLjkmBR4cYfvg1zJrKSlmIZFqyFR8oX0NrwPhy3c3HQ6i3OxMbew4Tg=="
},
"browserify-zlib": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz",
"integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==",
"requires": {
"pako": "~1.0.5"
}
},
"browserslist": {
"version": "4.17.3",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.17.3.tgz",
@ -9202,20 +9428,6 @@
"picocolors": "^0.2.1"
}
},
"buffer": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
"integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.2.1"
}
},
"builtin-status-codes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz",
"integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug="
},
"bytes": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
@ -11134,11 +11346,6 @@
"safer-buffer": ">= 2.1.2 < 3"
}
},
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
},
"ignore": {
"version": "4.0.6",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
@ -11211,7 +11418,8 @@
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
},
"inquirer": {
"version": "6.5.2",
@ -12303,11 +12511,6 @@
"integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
"dev": true
},
"pako": {
"version": "1.0.11",
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
"integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw=="
},
"parent-module": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
@ -12714,6 +12917,7 @@
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
"integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
"dev": true,
"requires": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
@ -13085,26 +13289,6 @@
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
"dev": true
},
"stream-browserify": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-3.0.0.tgz",
"integrity": "sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==",
"requires": {
"inherits": "~2.0.4",
"readable-stream": "^3.5.0"
}
},
"stream-http": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/stream-http/-/stream-http-3.2.0.tgz",
"integrity": "sha512-Oq1bLqisTyK3TSCXpPbT4sdeYNdmyZJv1LxpEm2vu1ZhK89kSE5YXwZc3cWk0MagGaKriBh9mCFbVGtO+vY29A==",
"requires": {
"builtin-status-codes": "^3.0.0",
"inherits": "^2.0.4",
"readable-stream": "^3.6.0",
"xtend": "^4.0.2"
}
},
"strict-uri-encode": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
@ -13114,6 +13298,7 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
"integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
"dev": true,
"requires": {
"safe-buffer": "~5.2.0"
},
@ -13121,7 +13306,8 @@
"safe-buffer": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
"dev": true
}
}
},
@ -13572,7 +13758,8 @@
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
"dev": true
},
"v8-compile-cache": {
"version": "2.3.0",
@ -13715,7 +13902,8 @@
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
"dev": true
},
"y18n": {
"version": "5.0.8",

View File

@ -15,8 +15,10 @@
"tsc": "tsc --noEmit"
},
"dependencies": {
"@radix-ui/react-checkbox": "^0.1.5",
"@radix-ui/react-dialog": "^0.0.20",
"@radix-ui/react-dropdown-menu": "^0.0.23",
"@radix-ui/react-icons": "^1.1.0",
"@radix-ui/react-polymorphic": "^0.0.13",
"@radix-ui/react-portal": "^0.0.15",
"@radix-ui/react-toggle": "^0.0.10",

View File

@ -0,0 +1,35 @@
import React, { useState } from 'react';
import classNames from 'classnames';
import * as RadixCheckbox from '@radix-ui/react-checkbox';
import { CheckIcon } from '@radix-ui/react-icons';
export const Checkbox: React.FC<RadixCheckbox.CheckboxProps> = ({
defaultChecked,
checked,
onCheckedChange,
disabled,
className,
children
}) => {
const [on, setOn] = useState(defaultChecked);
const isControlled = !!onCheckedChange;
const proxyChecked = isControlled ? checked : on;
const proxyOnCheckedChange = isControlled ? onCheckedChange : setOn;
return (
<div className="flex content-center space-x-2">
<RadixCheckbox.Root
className={classNames('default-ring rounded-lg bg-white h-7 w-7', className)}
checked={proxyChecked}
onCheckedChange={proxyOnCheckedChange}
disabled={disabled}
id="checkbox"
>
<RadixCheckbox.Indicator className="flex justify-center">
<CheckIcon className="text-black" />
</RadixCheckbox.Indicator>
</RadixCheckbox.Root>
<label htmlFor="checkbox">{children}</label>
</div>
);
};

View File

@ -0,0 +1,20 @@
import React from 'react';
export const Lock = (props: React.SVGProps<SVGSVGElement>) => (
<svg
width="10"
height="12"
viewBox="-11 -8 32 32"
fill="none"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M8 5H9C9.55228 5 10 5.44772 10 6V11C10 11.5523 9.55229 12 9 12H1C0.447716 12 0 11.5523 0 11V6C0 5.44772 0.447715 5 1 5H2V3C2 1.34315 3.34315 0 5 0C6.65685 0 8 1.34315 8 3V5ZM7 5V3C7 1.89543 6.10457 1 5 1C3.89543 1 3 1.89543 3 3V5H7ZM3 6H9V11H1V6H2H3Z"
className="fill-current"
strokeMiterlimit="10"
/>
</svg>
);

View File

@ -5,6 +5,7 @@ import classNames from 'classnames';
import { NotificationPrefs } from './preferences/NotificationPrefs';
import { SystemUpdatePrefs } from './preferences/SystemUpdatePrefs';
import { InterfacePrefs } from './preferences/InterfacePrefs';
import { SecurityPrefs } from './preferences/SecurityPrefs';
import { useCharges } from '../state/docket';
import { AppPrefs } from './preferences/AppPrefs';
import { DocketImage } from '../components/DocketImage';
@ -14,6 +15,7 @@ import { LeftArrow } from '../components/icons/LeftArrow';
import { System } from '../components/icons/System';
import { Interface } from '../components/icons/Interface';
import { Notifications } from '../components/icons/Notifications';
import { Lock } from '../components/icons/Lock';
import { getAppName } from '../state/util';
interface SystemPreferencesSectionProps {
@ -77,11 +79,11 @@ export const SystemPreferences = (props: RouteComponentProps<{ submenu: string }
FallbackComponent={ErrorAlert}
onReset={() => history.push('/leap/system-preferences')}
>
<div className="sm:flex h-full overflow-y-auto">
<div className="h-full overflow-y-auto sm:flex">
<Route exact={isMobile} path={match.url}>
<aside className="flex-none self-start w-full sm:w-auto min-w-60 py-4 sm:py-8 font-semibold text-black sm:text-gray-600 border-r-2 border-gray-50">
<aside className="self-start flex-none w-full py-4 font-semibold text-black border-r-2 sm:w-auto min-w-60 sm:py-8 sm:text-gray-600 border-gray-50">
<nav className="px-2 sm:px-6">
<h2 className="sm:hidden h3 mb-4 px-2">System Preferences</h2>
<h2 className="px-2 mb-4 sm:hidden h3">System Preferences</h2>
<ul className="space-y-1">
<SystemPreferencesSection
url={subUrl('notifications')}
@ -101,6 +103,10 @@ export const SystemPreferences = (props: RouteComponentProps<{ submenu: string }
<Interface className="w-8 h-8 mr-3 bg-gray-100 rounded-md" />
Interface Settings
</SystemPreferencesSection>
<SystemPreferencesSection url={subUrl('security')} active={matchSub('security')}>
<Lock className="w-8 h-8 mr-3 bg-gray-100 rounded-md" />
Security
</SystemPreferencesSection>
</ul>
</nav>
<hr className="my-4 border-t-2 border-gray-50" />
@ -126,6 +132,7 @@ export const SystemPreferences = (props: RouteComponentProps<{ submenu: string }
<Route path={`${match.url}/apps/:desk`} component={AppPrefs} />
<Route path={`${match.url}/system-updates`} component={SystemUpdatePrefs} />
<Route path={`${match.url}/interface`} component={InterfacePrefs} />
<Route path={`${match.url}/security`} component={SecurityPrefs} />
<Route
path={[`${match.url}/notifications`, match.url]}
component={NotificationPrefs}
@ -133,7 +140,7 @@ export const SystemPreferences = (props: RouteComponentProps<{ submenu: string }
</Switch>
<Link
to={match.url}
className="inline-flex sm:hidden items-center sm:none mt-auto pt-4 h4 text-gray-400"
className="inline-flex items-center pt-4 mt-auto text-gray-400 sm:hidden sm:none h4"
>
<LeftArrow className="w-3 h-3 mr-2" /> Back
</Link>

View File

@ -0,0 +1,32 @@
import React, { useState } from 'react';
import classNames from 'classnames';
import { Button } from '../../components/Button';
import { Checkbox } from '../../components/Checkbox';
export const SecurityPrefs = () => {
const [allSessions, setAllSessions] = useState(false);
return (
<>
<h2 className="h3 mb-7">Security</h2>
<div className="space-y-3">
<section className={classNames('inner-section')}>
<h3 className="flex items-center mb-2 h4">Logout</h3>
<div className="flex flex-col justify-center flex-1 space-y-6">
<Checkbox
defaultChecked={false}
checked={allSessions}
onCheckedChange={() => setAllSessions((prev) => !prev)}
>
Log out of all sessions.
</Checkbox>
<form method="post" action="/~/logout">
{allSessions && <input type="hidden" name="all" />}
<Button>Logout</Button>
</form>
</div>
</section>
</div>
</>
);
};

View File

@ -4,7 +4,7 @@ import { compose } from 'lodash/fp';
import _ from 'lodash';
import create, { GetState, SetState, UseStore } from 'zustand';
import { persist } from 'zustand/middleware';
import Urbit, { SubscriptionRequestInterface } from '@urbit/http-api';
import Urbit, { FatalError, SubscriptionRequestInterface } from '@urbit/http-api';
import { Poke } from '@urbit/api';
import api from './api';
import { clearStorageMigration, createStorageKey, storageVersion, useMockData } from './util';
@ -107,7 +107,9 @@ export function createSubscription(
path,
event: e,
err: () => {},
quit: () => {}
quit: () => {
throw new FatalError("subscription clogged");
}
};
// TODO: err, quit handling (resubscribe?)
return request;

File diff suppressed because it is too large Load Diff

View File

@ -7,7 +7,6 @@
content="width=device-width, initial-scale=1, shrink-to-fit=no,maximum-scale=1"/>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-touch-fullscreen" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<link rel="manifest"
href='data:application/manifest+json,{
"name": "Groups",
@ -16,6 +15,9 @@
"display": "standalone",
"background_color": "%23FFFFFF",
"theme_color": "%23000000"}' />
<meta name="theme-color" content="#FFFFFF" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#1A1A1A" media="(prefers-color-scheme: dark)">
<meta name="theme-color" content="#FFFFFF">
<script src="/apps/landscape/desk.js"></script>
<script src="/session.js"></script>
</head>

View File

@ -1,7 +1,7 @@
import Urbit from '@urbit/http-api';
const api = new Urbit('', '', (window as any).desk);
api.ship = window.ship;
api.verbose = true;
// api.verbose = true;
// @ts-ignore TODO window typings
window.api = api;

View File

@ -1,17 +1,18 @@
import useMetadataState from '../state/metadata';
import ob from 'urbit-ob';
import useInviteState from '../state/invite';
import { resourceAsPath } from '@urbit/api';
import { deSig, resourceAsPath } from '@urbit/api';
import { createJoinParams } from '~/views/landscape/components/Join/Join';
function getGroupResourceRedirect(key: string) {
const association = useMetadataState.getState().associations.graph[`/ship/${key}`];
const { metadata } = association;
if(!association || !('graph' in metadata.config)) {
const graphs = useMetadataState.getState().associations.graph;
const association = graphs[`/ship/${key}`];
if(!association || !('graph' in association.metadata.config)) {
return '';
}
const section = association.group === association.resource ? '/messages' : association.group;
return `/~landscape${section}/resource/${metadata.config.graph}${association.resource}`;
return `/~landscape${section}/resource/${association.metadata.config.graph}${association.resource}`;
}
function getPostRedirect(key: string, segs: string[]) {
@ -70,8 +71,18 @@ function getGraphRedirect(link: string) {
function getInviteRedirect(link: string) {
const [,,app,uid] = link.split('/');
const invite = useInviteState.getState().invites[app][uid];
if(!invite) { return ''; }
return { search: `?join-kind=${app}&join-path=${encodeURIComponent(resourceAsPath(invite.resource))}` };
if(!invite || (app !== 'groups' && app !== 'graph')) {
return '';
}
const { ship, name } = invite.resource;
const alreadyJoined = getGroupResourceRedirect(`~${deSig(ship)}/${name}`);
if (alreadyJoined) {
return alreadyJoined;
}
return { search: createJoinParams(app, resourceAsPath(invite.resource)) };
}
function getDmRedirect(link: string) {

View File

@ -1,5 +1,6 @@
import { isChannelAdmin } from '@urbit/api';
import { cite } from '~/logic/lib/util';
import { createJoinParams } from '~/views/landscape/components/Join/Join';
const makeIndexes = () => new Map([
['ships', []],
@ -55,7 +56,7 @@ const commandIndex = function (currentGroup, groups, associations) {
if (canAdd) {
commands.push(result('Channel: Create', `/~landscape${workspace}/new`, 'Groups', null));
}
commands.push(result('Groups: Join', '?join-kind=group', 'Groups', null));
commands.push(result('Groups: Join', createJoinParams('groups'), 'Groups', null));
return commands;
};

View File

@ -228,6 +228,18 @@ export function deSig(ship: string): string {
return ship.replace('~', '');
}
export function preSig(ship: string): string {
if (!ship) {
return '';
}
if (ship.trim().startsWith('~')) {
return ship.trim();
}
return '~'.concat(ship.trim());
}
export function uxToHex(ux: string) {
if (ux.length > 2 && ux.substr(0, 2) === '0x') {
const value = ux.substr(2).replace('.', '').padStart(6, '0');

View File

@ -242,7 +242,7 @@ function timebox(json: any, state: HarkState): HarkState {
const time = makePatDa(lid.archive);
const old = state.archive.get(time) || {};
notifications.forEach((note: any) => {
if(note.bin.desk !== window.desk) {
if(note.bin.place.desk !== window.desk) {
return;
}
const binId = harkBinToId(note.bin);
@ -252,7 +252,7 @@ function timebox(json: any, state: HarkState): HarkState {
} else {
const seen = 'seen' in lid ? 'seen' : 'unseen';
notifications.forEach((note: any) => {
if(note.bin.desk !== window.desk) {
if(note.bin.place.desk !== window.desk) {
return;
}
const binId = harkBinToId(note.bin);

View File

@ -90,7 +90,7 @@ const ChatResource = (props: ChatResourceProps): ReactElement => {
);
const isAdmin = useMemo(
() => (group ? _.includes(group.tags.role.admin, `~${window.ship}`) : false),
() => (group ? _.includes(group.tags.role.admin, deSig(window.ship)) : false),
[group]
);

View File

@ -77,7 +77,7 @@ export function DmResource(props: DmResourceProps) {
);
useEffect(() => {
if(dm.size === 0) {
if(dm.size === 0 && !pending) {
getNewest(`~${window.ship}`, 'dm-inbox', 100, `/${patp2dec(ship)}`);
}
}, [ship, dm]);
@ -134,6 +134,7 @@ export function DmResource(props: DmResourceProps) {
history.push('/~landscape/messages');
await airlock.poke(declineDm(ship));
};
return (
<Col width="100%" height="100%" overflow="hidden">
<Row

View File

@ -12,7 +12,7 @@ import ModalButton from './components/ModalButton';
import Tiles from './components/tiles';
import Tile from './components/tiles/tile';
import './css/custom.css';
import { JoinRoute } from '~/views/landscape/components/Join/Join';
import { createJoinParams, JoinRoute } from '~/views/landscape/components/Join/Join';
const ScrollbarLessBox = styled(Box)`
scrollbar-width: none !important;
@ -36,7 +36,7 @@ export const LaunchApp = (): ReactElement | null => {
</title>
</Helmet>
<Route path='/join/:ship/:name'>
<JoinRoute modal />
<JoinRoute />
</Route>
<ScrollbarLessBox
height='100%'
@ -90,7 +90,7 @@ export const LaunchApp = (): ReactElement | null => {
border={0}
p={0}
borderRadius={2}
onClick={() => history.push({ search: '?join-kind=group' })}
onClick={() => history.push({ search: createJoinParams('groups') })}
>
<Row backgroundColor='white' gapX='2' p={2} height='100%' width='100%' alignItems='center'>
<Icon icon='BootNode' />

View File

@ -22,6 +22,7 @@ import useSettingsState, {
} from "~/logic/state/settings";
import Tile from "../components/tiles/tile";
import { useQuery } from "~/logic/lib/useQuery";
import { createJoinParams } from "~/views/landscape/components/Join/Join";
const sortGroupsAlph = (a: Association, b: Association) =>
alphabeticalOrder(a.metadata.title, b.metadata.title);
@ -123,8 +124,7 @@ function PendingGroup(props: PendingGroupProps) {
const title = preview?.metadata?.title || path;
const { toQuery } = useQuery();
const onClick = () => {
const { ship, name } = resourceFromPath(path);
history.push(toQuery({ "join-kind": "groups", "join-path": path }));
history.push(toQuery(createJoinParams('groups', path, null, false)));
};
const joining = useGroupState((s) => s.pendingJoin[path]?.progress);
@ -143,6 +143,8 @@ function PendingGroup(props: PendingGroupProps) {
<Box>
{!joining ? (
<Text color="blue">Invited</Text>
) : joining === 'no-perms' || joining == 'strange' ? (
<Text color="red">Join Failed</Text>
) : joining !== "done" ? (
<Text gray>Joining...</Text>
) : (

View File

@ -8,7 +8,7 @@ import {
} from '@urbit/api';
import { BigInteger } from 'big-integer';
import React, { useCallback } from 'react';
import { useHovering } from '~/logic/lib/util';
import { deSig, useHovering } from '~/logic/lib/util';
import useLocalState from '~/logic/state/local';
import { StatelessAsyncAction } from '~/views/components/StatelessAsyncAction';
import { SwipeMenu } from '~/views/components/SwipeMenu';
@ -38,7 +38,7 @@ const NotificationText = ({ contents, ...rest }: NotificationTextProps) => {
return (
<Mention
key={idx}
ship={content.ship}
ship={deSig(content.ship)}
first={idx === 0}
{...rest}
/>

View File

@ -16,6 +16,7 @@ import { TranscludedNode } from './TranscludedNode';
import styled from 'styled-components';
import Author from '~/views/components/Author';
import useDocketState, { useTreaty } from '~/logic/state/docket';
import { createJoinParams } from '~/views/landscape/components/Join/Join';
function Placeholder(type) {
const lines = (type) => {
@ -118,8 +119,7 @@ function GraphPermalink(
const permalink = (() => {
const link = `/perma${getPermalinkForGraph(group, graph, index).slice(16)}`;
return (!association && !loading)
? { search: `?join-kind=group&join-path=${encodeURIComponent(group)}&redir=${encodeURIComponent(link)}` }
: link
? { search: createJoinParams('groups', group, link) } : link;
})();
const [nodeGroupHost, nodeGroupName] = association?.group.split('/').slice(-2) ?? ['Unknown', 'Unknown'];

View File

@ -1,54 +0,0 @@
import {
Button,
Col,
StatelessCheckboxField, Text
} from '@tlon/indigo-react';
import React, { useState } from 'react';
import { BackButton } from './BackButton';
export default function SecuritySettings() {
const [allSessions, setAllSessions] = useState(false);
return (
<>
<BackButton />
<Col gapY={5} p={5} pt={4}>
<Col gapY={1} mt={0}>
<Text fontSize={2} fontWeight="medium">
Security Preferences
</Text>
<Text gray>
Manage sessions, login credentials and web access
</Text>
</Col>
<Col gapY={1}>
<Text color="black">
Log out of this session
</Text>
<Text mb={3} gray>
{allSessions
? 'You will be logged out of all browsers that have currently logged into your Urbit.'
: 'You will be logged out of your Urbit on this browser.'}
</Text>
<StatelessCheckboxField
mb={3}
selected={allSessions}
onChange={() => setAllSessions(s => !s)}
>
<Text>Log out of all sessions</Text>
</StatelessCheckboxField>
<form method="post" action="/~/logout">
{allSessions && <input type="hidden" name="all" />}
<Button
primary
destructive
border={1}
style={{ cursor: 'pointer' }}
>
Logout
</Button>
</form>
</Col>
</Col>
</>
);
}

View File

@ -11,7 +11,6 @@ import DisplayForm from './components/lib/DisplayForm';
import { LeapSettings } from './components/lib/LeapSettings';
import { NotificationPreferences } from './components/lib/NotificationPref';
import S3Form from './components/lib/S3Form';
import SecuritySettings from './components/lib/Security';
import { DmSettings } from './components/lib/DmSettings';
import ShortcutSettings from './components/lib/ShortcutSettings';
@ -117,11 +116,6 @@ return;
<SidebarItem icon='Messages' text='Direct Messages' hash='dm' />
<SidebarItem icon='Node' text='CalmEngine' hash='calm' />
<SidebarItem icon='EastCarat' text='Shortcuts' hash='shortcuts' />
<SidebarItem
icon='Locked'
text='Devices + Security'
hash='security'
/>
</Col>
</Col>
<Col flexGrow={1} overflowY='auto'>
@ -133,7 +127,6 @@ return;
{hash === 's3' && <S3Form />}
{hash === 'leap' && <LeapSettings />}
{hash === 'calm' && <CalmPrefs />}
{hash === 'security' && <SecuritySettings />}
{hash === 'debug' && <DebugPane />}
</SettingsItem>
</Col>

View File

@ -3,6 +3,7 @@ import React, { ReactElement, useCallback } from 'react';
import { Link } from 'react-router-dom';
import useMetadataState, { usePreview } from '~/logic/state/metadata';
import { PropFunc } from '~/types';
import { createJoinParams } from '../landscape/components/Join/Join';
import { MetadataIcon } from '../landscape/components/MetadataIcon';
type GroupLinkProps = {
@ -26,7 +27,7 @@ const { preview } = usePreview(resource);
<Row
{...rest}
as={Link}
to={joined ? `/~landscape/ship/${name}` : { search: `?join-kind=groups&join-path=/ship/${name}`}}
to={joined ? `/~landscape/ship/${name}` : { search: createJoinParams('groups', `/ship/${name}`) }}
flexShrink={1}
alignItems="center"
width="100%"

View File

@ -40,8 +40,9 @@ export function MentionText(props: MentionTextProps) {
export function Mention(props: {
ship: string;
first?: boolean;
emphasis?: 'bold' | 'italic';
} & PropFunc<typeof Text>) {
const { ship, first = false, ...rest } = props;
const { ship, first = false, emphasis, ...rest } = props;
const contact = useContact(`~${deSig(ship)}`);
const showNickname = useShowNickname(contact);
const name = showNickname ? contact?.nickname : cite(ship);
@ -51,8 +52,10 @@ export function Mention(props: {
marginLeft={first? 0 : 1}
marginRight={1}
px={1}
bold={emphasis === 'bold' ? true : false}
bg='washedBlue'
color='blue'
fontStyle={emphasis === 'italic' ? 'italic' : undefined}
fontSize={showNickname ? 1 : 0}
mono={!showNickname}
title={showNickname ? cite(ship) : contact?.nickname}

View File

@ -34,11 +34,14 @@ const FixedOverlay = styled(Col)`
transition: all 0.1s ease-out;
`;
type ProfileOverlayProps = BoxProps & {
ship: string;
children?: ReactNode;
color?: string;
};
interface ProfileOverlayProps extends BoxProps {
/**
* A valid patp (without sig)
*/
ship: string,
children?: ReactNode,
color?: string,
}
const selSettings = (s: SettingsState) => [s.calm.hideAvatars, s.calm.hideNicknames];

View File

@ -167,9 +167,11 @@ export function ShipSearch<I extends string, V extends Value<I>>(
name={id}
render={(arrayHelpers) => {
const onAdd = (ship: string) => {
setFieldValue(name(), ship);
inputIdx.current += 1;
arrayHelpers.push('');
if (!pills.includes(ship)) {
setFieldValue(name(), ship);
inputIdx.current += 1;
arrayHelpers.push('');
}
};
const onRemove = (idx: number) => {

View File

@ -34,6 +34,72 @@ interface GraphMentionNode {
ship: string;
}
const addEmphasisToMention = (contents: Content[], content: Content, index: number) => {
const prevContent = contents[index - 1];
const nextContent = contents[index + 1];
if (
'text' in content &&
(content.text.trim() === '**' || content.text.trim() === '*' )
) {
return {
text: ''
};
}
if(
'text' in content &&
content.text.endsWith('*') &&
!content.text.startsWith('*') &&
nextContent !== undefined &&
'mention' in nextContent
) {
if (content.text.charAt((content.text.length - 2)) === '*') {
return { text: content.text.slice(0, content.text.length - 2) };
}
return { text: content.text.slice(0, content.text.length - 1) };
}
if (
'text' in content &&
content.text.startsWith('*') &&
!content.text.endsWith('*') &&
prevContent !== undefined &&
'mention' in contents[index - 1]
) {
if (content.text.charAt(1) === '*') {
return { text: content.text.slice(2, content.text.length) };
}
return { text: content.text.slice(1, content.text.length) };
}
if (
'mention' in content &&
prevContent !== undefined &&
'text' in prevContent &&
// @ts-ignore type guard above covers this.
prevContent.text.endsWith('*') &&
nextContent !== undefined &&
'text' in contents[index + 1] &&
// @ts-ignore type guard above covers this.
nextContent.text.startsWith('*')
) {
if (
// @ts-ignore covered by typeguard in conditions
prevContent.text.charAt(prevContent.text.length - 2) === '*' &&
// @ts-ignore covered by typeguard in conditions
nextContent.text.charAt(nextContent.text[1]) === '*'
) {
return {
mention: content.mention,
emphasis: 'bold'
};
}
return {
mention: content.mention,
emphasis: 'italic'
};
}
return content;
};
const codeToMdAst = (content: CodeContent) => {
return {
type: 'root',
@ -100,7 +166,8 @@ const contentToMdAst = (tall: boolean) => (
children: [
{
type: 'graph-mention',
ship: content.mention
ship: content.mention,
emphasis: content.emphasis
}
]
}
@ -343,7 +410,9 @@ const renderers = {
list: ({ depth, ordered, children }) => {
return ordered ? <Ol>{children}</Ol> : <Ul>{children}</Ul>;
},
'graph-mention': ({ ship }) => <Mention ship={ship} />,
'graph-mention': (obj) => {
return <Mention ship={obj.ship} emphasis={obj.emphasis} />;
},
image: ({ url, tall }) => (
<Box mt="1" mb="2" flexShrink={0}>
<RemoteContent key={url} url={url} tall={tall} />
@ -439,7 +508,10 @@ export const GraphContent = React.memo((
transcluded = 0,
...rest
} = props;
const [, ast] = stitchAsts(contents.map(contentToMdAst(tall)));
const [, ast] = stitchAsts(
contents
.map((content, index) => addEmphasisToMention(contents, content, index))
.map(contentToMdAst(tall)));
return (
<Box {...rest}>
<Graphdown transcluded={transcluded} ast={ast} tall={tall} />

View File

@ -9,15 +9,16 @@ import {
ContinuousProgressBar
} from '@tlon/indigo-react';
import { Formik, Form } from 'formik';
import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import { useHistory, useLocation } from 'react-router-dom';
import useGroupState from '~/logic/state/group';
import { useInviteForResource } from '~/logic/state/invite';
import { usePreview } from '~/logic/state/metadata';
import useMetadataState, { usePreview } from '~/logic/state/metadata';
import { joinError, joinLoad, JoinProgress, join, JoinRequest, decline, Invite } from '@urbit/api';
import airlock from '~/logic/api';
import { useQuery } from '~/logic/lib/useQuery';
import { JoinDesc, JoinSkeleton } from './Skeleton';
import { preSig } from '~/logic/lib/util';
interface InviteWithUid extends Invite {
uid: string;
@ -148,8 +149,9 @@ function JoinError(props: {
desc: JoinDesc;
request: JoinRequest;
modal: boolean;
dismiss: () => void;
}) {
const { desc, request, modal } = props;
const { dismiss, desc, request, modal } = props;
const { preview } = usePreview(desc.group);
const group = preview?.metadata?.title ?? desc.group;
const title = `Joining ${group} failed`;
@ -158,12 +160,26 @@ function JoinError(props: {
? 'You do not have the correct permissions'
: 'An unexpected error occurred';
const onRetry = () => {
useGroupState.getState().abortJoin(desc.group);
const [,,ship,name] = group.split('/');
airlock.poke(
join(ship, name, desc.kind, false, false)
);
};
const onAbort = () => {
useGroupState.getState().abortJoin(desc.group);
dismiss();
};
return (
<JoinSkeleton modal={modal} title={title} desc={desc}>
<Col p='4' gapY='4'>
<Text fontWeight='medium'>{explanation}</Text>
<Row>
<Button>Dismiss</Button>
<Row gapX="2">
<Button onClick={onRetry} primary>Retry</Button>
<Button onClick={onAbort} destructive>Abort</Button>
</Row>
</Col>
</JoinSkeleton>
@ -182,6 +198,8 @@ export function Join(props: JoinProps) {
const { group, kind } = desc;
const [, , ship, name] = group.split('/');
const graph = kind === 'graph';
const associations = useMetadataState(s => s.associations);
const joined = graph ? associations.graph[group] : associations.groups[group];
const finishedPath = redir
? redir
: graph
@ -189,14 +207,23 @@ export function Join(props: JoinProps) {
: `/~landscape/ship/${ship}/${name}`;
const history = useHistory();
const joinRequest = useGroupState((s) => s.pendingJoin[group]);
const joinRequest = useGroupState(s => s.pendingJoin[group]);
const [openedRequest, setOpenedRequest] = useState<JoinRequest>();
const invite = useInviteForResource(kind, ship, name);
const isDone = joinRequest && joinRequest.progress === 'done';
const isDone = openedRequest && openedRequest.progress === 'done' && joined;
const isErrored =
joinRequest && joinError.includes(joinRequest.progress as any);
openedRequest && joinError.includes(openedRequest.progress as any);
const isLoading =
joinRequest && joinLoad.includes(joinRequest.progress as any);
openedRequest && joinLoad.includes(openedRequest.progress as any);
// If we opened this modal from a join request,
// don't let the request getting deleted move us to the wrong state
useEffect(() => {
if (joinRequest) {
setOpenedRequest(joinRequest);
}
}, [joinRequest]);
useEffect(() => {
if (isDone && desc.kind == 'graph') {
@ -216,11 +243,11 @@ export function Join(props: JoinProps) {
modal={modal}
dismiss={dismiss}
desc={desc}
request={joinRequest}
request={openedRequest}
finished={finishedPath}
/>
) : isErrored ? (
<JoinError modal={modal} desc={desc} request={joinRequest} />
<JoinError dismiss={dismiss} modal={modal} desc={desc} request={openedRequest} />
) : (
<JoinInitial modal={modal} dismiss={dismiss} desc={desc} invite={invite} />
);
@ -243,7 +270,7 @@ export function JoinPrompt(props: JoinPromptProps) {
};
const onSubmit = async ({ link }: PromptFormSchema) => {
const path = `/ship/${link}`;
const path = `/ship/${preSig(link)}`;
history.push({
search: appendQuery({ 'join-path': path })
});
@ -336,21 +363,46 @@ export function JoinDone(props: JoinDoneProps) {
);
}
export function JoinRoute(props: { graph?: boolean; modal?: boolean }) {
const { graph = false } = props;
export interface JoinParams extends Record<string, string> {
'join-kind': JoinKind;
'join-path'?: string;
redir?: string;
}
export function createJoinParams(kind: JoinKind, path?: string, redirect?: string, inLink?: true): string;
export function createJoinParams(kind: JoinKind, path?: string, redirect?: string, inLink?: false): JoinParams;
export function createJoinParams(kind: JoinKind, path?: string, redirect?: string, inLink = true) {
const params = {
'join-kind': kind
};
if (path) {
params['join-path'] = path;
}
if (redirect) {
params['redir'] = redirect;
}
return inLink ? '?' + new URLSearchParams(params).toString() : params;
}
export function JoinRoute() {
const { query } = useQuery();
const history = useHistory();
const { pathname } = useLocation();
const kind = query.get('join-kind');
const path = query.get('join-path');
const path = query.get('join-path')?.replace('web+urbitgraph://group/', '');
const redir = query.get('redir');
if (!kind) {
return null;
}
const desc: JoinDesc = path
? {
group: path,
kind: graph ? 'graph' : 'groups',
kind: kind === 'graph' ? 'graph' : 'groups'
}
: undefined;

View File

@ -45,7 +45,7 @@ export function SidebarListHeader(props: {
const metadata = associations?.groups?.[groupPath]?.metadata;
const memberMetadata =
groupPath ? metadata.vip === 'member-metadata' : false;
groupPath && metadata ? metadata.vip === 'member-metadata' : false;
const isAdmin = memberMetadata || (role === 'admin') || (props.workspace?.type === 'home') || (props.workspace?.type === 'messages');

View File

@ -45,7 +45,9 @@ const makeTheme = (dark: boolean): ITheme => {
foreground: fg,
background: bg,
brightBlack: '#7f7f7f', // NOTE slogs
cursor: fg
cursor: fg,
cursorAccent: bg,
selection: fg
};
};
@ -66,7 +68,9 @@ const termConfig: ITerminalOptions = {
bellSound: bel,
//
// allows text selection by holding modifier (option, or shift)
macOptionClickForcesSelection: true
macOptionClickForcesSelection: true,
// prevent insertion of simulated arrow keys on-altclick
altClickMovesCursor: false
};
const csi = (cmd: string, ...args: number[]) => {

View File

@ -622,6 +622,9 @@
[%x %keys ~]
:- ~ :- ~ :- mar
!>(`update:store`[now.bowl [%keys ~(key by graphs)]])
[%x %archived-keys ~]
:- ~ :- ~ :- mar
!>(`update:store`[now.bowl [%keys ~(key by archive)]])
::
[%x %tag-queries *]
:- ~ :- ~ :- mar
@ -636,7 +639,7 @@
=/ =ship (slav %p i.t.t.path)
=/ =term i.t.t.t.path
=/ marked-graph=(unit marked-graph:store)
(~(get by graphs) [ship term])
(~(get by archive) [ship term])
?~ marked-graph [~ ~]
=* graph p.u.marked-graph
=* mark q.u.marked-graph

View File

@ -295,12 +295,14 @@
::
++ rollback
|^
=/ =request:view (~(got by joining) rid)
=/ =request:view (~(got by joining) rid)
?+ progress.request ~|(cannot-rollback/progress.request !!)
%start start
%added added
%metadata metadata
%start start
%added added
%metadata metadata
?(%no-perms %strange %abort) error
==
++ error jn-core
++ start jn-core
++ added (emit del-us:pass)
++ metadata (emit:added remove-pull-groups:pass)

View File

@ -22,6 +22,7 @@
[%4 observers=(map serial observer:sur)]
[%5 observers=(map serial observer:sur) warm-cache=_|]
[%6 state-0]
[%7 state-0]
==
::
+$ serial @uv
@ -35,7 +36,7 @@
--
::
%- agent:dbug
=| [%6 state-0]
=| [%7 state-0]
=* state -
::
^- agent:gall
@ -117,8 +118,10 @@
=| cards=(list card)
|-
?- -.old-state
%6
%7
[cards this(state old-state)]
%6
$(-.old-state %7, cards :_(cards (act %warm-cache-all ~)))
::
%5
=. cards

View File

@ -1,10 +1,10 @@
:~ title+'Groups'
info+'A suite of applications to communicate on Urbit'
color+0xee.5432
glob-http+['https://bootstrap.urbit.org/glob-0v3.m2nd4.9tg9d.vs9ls.9rj6u.7lqhg.glob' 0v3.m2nd4.9tg9d.vs9ls.9rj6u.7lqhg]
glob-http+['https://bootstrap.urbit.org/glob-0v1.5sbiv.4flu3.qfv1i.k2an0.65r45.glob' 0v1.5sbiv.4flu3.qfv1i.k2an0.65r45]
base+'landscape'
version+[1 0 4]
version+[1 0 8]
website+'https://tlon.io'
license+'MIT'
==

View File

@ -41,6 +41,7 @@ export interface AppReference {
export interface MentionContent {
mention: string;
emphasis?: 'bold' | 'italic';
}
export type Content =
| TextContent

File diff suppressed because it is too large Load Diff

View File

@ -1,9 +1,9 @@
:~ title+'Terminal'
info+'A web interface to your Urbit\'s command line.'
color+0x2e.4347
glob-http+['https://bootstrap.urbit.org/glob-0v1.fgmgl.utdgt.kdu3r.4e5f9.v58rk.glob' 0v1.fgmgl.utdgt.kdu3r.4e5f9.v58rk]
glob-http+['https://bootstrap.urbit.org/glob-0v7.1hgb7.euged.6oj3e.cdhdg.rah02.glob' 0v7.1hgb7.euged.6oj3e.cdhdg.rah02]
base+'webterm'
version+[1 0 0]
version+[1 0 1]
website+'https://tlon.io'
license+'MIT'
==