diff --git a/.gitattributes b/.gitattributes index 27a039ad1..199d0374b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -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 diff --git a/bin/brass.pill b/bin/brass.pill index 799a4e8de..99aaaee04 100644 --- a/bin/brass.pill +++ b/bin/brass.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:9a56f675d2a6c5dafa92a9e2d55040d994f3d3d27a1ed827bd87d1158b1e69d0 -size 3749183 +oid sha256:ae4a7a69fe81c5f2114d7b7360c05602f614fe66b96d1db4c3dc0c2a2a5d856e +size 7536000 diff --git a/bin/solid.pill b/bin/solid.pill index 1da0adbc3..32d8e9113 100644 --- a/bin/solid.pill +++ b/bin/solid.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c29577dc949ac0689ba3c97ad13b812ea6c3c6cc9d255b770d2da95fd9af84b9 -size 23121802 +oid sha256:bcab0698de6efda1bbac54b0833da5e853bca058919110aa5668aa63fb40626e +size 9392699 diff --git a/pkg/arvo/app/azimuth-tracker.hoon b/pkg/arvo/app/azimuth-tracker.hoon index 3bb450579..c9629c71d 100644 --- a/pkg/arvo/app/azimuth-tracker.hoon +++ b/pkg/arvo/app/azimuth-tracker.hoon @@ -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]) diff --git a/pkg/arvo/app/azimuth.hoon b/pkg/arvo/app/azimuth.hoon index 634505fde..b737d7845 100644 --- a/pkg/arvo/app/azimuth.hoon +++ b/pkg/arvo/app/azimuth.hoon @@ -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 ð-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)"]~ + :: =: 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)" + =/ 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)" + =/ =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)" + =/ 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) diff --git a/pkg/arvo/app/azimuth/logs.eth-logs b/pkg/arvo/app/azimuth/logs.eth-logs deleted file mode 100644 index 1a6f1d9b0..000000000 Binary files a/pkg/arvo/app/azimuth/logs.eth-logs and /dev/null differ diff --git a/pkg/arvo/app/azimuth/version-0.azimuth-snapshot b/pkg/arvo/app/azimuth/version-0.azimuth-snapshot new file mode 100644 index 000000000..a664ca92f Binary files /dev/null and b/pkg/arvo/app/azimuth/version-0.azimuth-snapshot differ diff --git a/pkg/arvo/app/claz.hoon b/pkg/arvo/app/claz.hoon index 5beb81c37..a8f1f42ce 100644 --- a/pkg/arvo/app/claz.hoon +++ b/pkg/arvo/app/claz.hoon @@ -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] diff --git a/pkg/arvo/app/dojo.hoon b/pkg/arvo/app/dojo.hoon index affd134c7..938d9f25a 100644 --- a/pkg/arvo/app/dojo.hoon +++ b/pkg/arvo/app/dojo.hoon @@ -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) diff --git a/pkg/arvo/app/eth-watcher.hoon b/pkg/arvo/app/eth-watcher.hoon index 18aefdd9c..47b50375c 100644 --- a/pkg/arvo/app/eth-watcher.hoon +++ b/pkg/arvo/app/eth-watcher.hoon @@ -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 diff --git a/pkg/arvo/app/hood.hoon b/pkg/arvo/app/hood.hoon index d5f861e03..d916c1b55 100644 --- a/pkg/arvo/app/hood.hoon +++ b/pkg/arvo/app/hood.hoon @@ -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] diff --git a/pkg/arvo/app/roller-rpc.hoon b/pkg/arvo/app/roller-rpc.hoon index cca6d7af2..4133058c0 100644 --- a/pkg/arvo/app/roller-rpc.hoon +++ b/pkg/arvo/app/roller-rpc.hoon @@ -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 diff --git a/pkg/arvo/app/roller.hoon b/pkg/arvo/app/roller.hoon index 4a3bd7202..b2d1d6305 100644 --- a/pkg/arvo/app/roller.hoon +++ b/pkg/arvo/app/roller.hoon @@ -31,14 +31,16 @@ :: |% +$ app-state - $: %2 + $: %4 :: pending: the next l2 txs to be sent :: sending: l2 txs awaiting l2 confirmation, ordered by nonce :: finding: sig+raw-tx hash reverse lookup for txs in sending map :: history: status of l2 txs by ethereum address, timestamp sorted :: ship-quota: number of txs submited per ship in the current slice + :: allowances: specific no of allowed transactions per given ship :: next-nonce: next l1 nonce to use :: next-batch: when then next l2 batch will be sent + :: next-slice: when the global quota will be reset :: pre: predicted l2 state :: own: ownership of azimuth points :: spo: residents and escapees, per sponsor @@ -48,8 +50,10 @@ finding=(map keccak ?(%confirmed %failed [=time l1-tx-pointer])) history=(map address:ethereum (tree hist-tx)) ship-quota=(map ship @ud) + allowances=(map ship (unit @ud)) next-nonce=(unit @ud) next-batch=time + next-slice=time pre=^state:naive own=owners spo=sponsors @@ -64,6 +68,7 @@ :: chain-id: mainnet, ropsten, local (https://chainid.network/) :: resend-time: time to resend a batch with higher gas prie :: update-rate: frequency to update the roller's predicted state + :: fallback-gas-price: default batch gas price :: pk=@ slice=@dr @@ -75,36 +80,140 @@ chain-id=@ resend-time=@dr update-rate=@dr + fallback-gas-price=@ud == -:: 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:dice) -:: orh: ordered tx history by (decreasing) timestamp -:: -++ orh ((on time roll-tx) gth) :: +$ action - $% :: we need to include the address in submit so pending txs show up - :: in the tx history, but because users can send the wrong - :: address, in +apply-tx:predicted state, we just replace - :: the provided address, with the one used when the message was signed; - :: - :: we need to do it there to know the correct nonce that the signed - :: message should have included. + $% :: submit: request to add a l2 tx to the pending queue :: [%submit force=? =address:naive sig=@ tx=part-tx] + :: cancel: cancels a pending transaction + :: + :: a signed message ("cancel: 0xkeccak") is used as ownership validation + :: [%cancel sig=@ keccak=@ =l2-tx =ship] - [%commit ~] ::TODO maybe pk=(unit @) later + :: commit: manually commit a batch of pending txs + :: + :: TODO: maybe pk=(unit @) later + :: + [%commit ~] + :: config: configure the roller + :: [%config config] + :: assign: assign an allowance to a ship for submitting l2 txs + :: + [%assign =ship quota=(unit @ud)] + :: refuel: bumps the next-gas-price of a sending tx + :: + [%refuel nonce=@ address=(unit address:ethereum) gas=@ud] == :: -+$ card card:agent:gall -:: ++$ card card:agent:gall ++ lverb & -- +:: Helpers +:: +=> |% + :: TODO /lib/sys.hoon? + :: + ++ sys + |% + ++ b + |% + ++ wait + |= [=wire =time] + ^- card + [%pass wire %arvo %b %wait time] + -- + -- + :: TODO /lib/spider.hoon? + :: + ++ spider + |% + ++ start-thread + |= [=bowl:gall =wire thread=term arg=vase] + ^- (list card) + =/ =beak byk.bowl(r da+now.bowl) + =/ tid=@ta (rap 3 thread '--' (scot %uv eny.bowl) ~) + =/ args [~ `tid beak thread arg] + :~ [%pass wire %agent [our.bowl %spider] %watch /thread-result/[tid]] + [%pass wire %agent [our.bowl %spider] %poke %spider-start !>(args)] + == + :: + ++ leave + |= [agent=@p =path] + ^- card + [%pass path %agent [agent %spider] %leave ~] + -- + :: + ++ get-l1-address + |= [=tx:naive nas=^state:naive] + ^- (unit address:ethereum) + ?~ point=(get:orp:dice points.nas ship.from.tx) ~ + =< `address + (proxy-from-point:naive proxy.from.tx u.point) + :: + ++ timer + |% + :: +set-roller: %wait until next whole frequency + :: + ++ set-roller + |= [frequency=@dr now=@da] + ^- [=card =time] + =+ time=(mul +((div now frequency)) frequency) + [(wait:b:sys /timer time) time] + :: +set-roller: %wait until next whole :slice + :: + ++ set-quota + |= [slice=@dr now=@da] + ^- [=card =time] + =+ time=(mul +((div now slice)) slice) + [(wait:b:sys /quota-timer time) time] + -- + :: TODO: move address to state? + :: + ++ get-address + |= pk=@ + ^- address:ethereum + (address-from-prv:key:ethereum pk) + -- +:: Cards +:: +=> |% + ++ emit + |= updates=(list update) + =| cards=(list card) + |- ^- (list card) + ?~ updates (flop cards) + =* up i.updates + =/ [address=@t last-owner=(unit @t)] + ?- -.up + %tx + :_ ~ + (scot %ux address.pend-tx.up) + :: + %point + :- (scot %ux address.to.up) + ?~(from.up ~ `(scot %ux address.u.from.up)) + == + =. cards + %+ welp + ^- (list card) + ?- -.i.updates + %tx + [%give %fact ~[/txs/[address]] tx+!>(up)]~ + :: + %point + =/ =cage point+!>(up) + %+ weld + [%give %fact ~[/points/[address]] cage]~ + ?~ last-owner ~ + [%give %fact ~[/points/[u.last-owner]] cage]~ + == + cards + :: + $(updates t.updates) + -- :: =| app-state =* state - @@ -121,18 +230,20 @@ :: ++ on-init ^- (quip card _this) - =: frequency ~h1 - quota 7 - slice ~d7 - resend-time ~m5 - update-rate ~m5 - contract naive:local-contracts:azimuth - chain-id chain-id:local-contracts:azimuth + =: frequency ~h1 + quota 25 + slice ~d7 + resend-time ~m5 + update-rate ~m5 + contract naive:local-contracts:azimuth + chain-id chain-id:local-contracts:azimuth + fallback-gas-price 10.000.000.000 == - =^ card next-batch set-roller:timer + =^ card-1 next-batch (set-roller:timer frequency now.bowl) + =^ card-2 next-slice (set-quota:timer slice now.bowl) :_ this - :~ card - (set-quota:timer slice) + :~ card-1 + card-2 [%pass /azimuth-events %agent [our.bowl %azimuth] %watch /event] == :: @@ -141,15 +252,15 @@ |= old=vase ^- (quip card _this) =| cards=(list card) - :: new additions to app-state - :: - =| spo=(map ship [residents=(set ship) requests=(set ship)]) |^ =+ !<(old-state=app-states old) =? cards ?=(%0 -.old-state) - [(set-quota:timer slice)]~ + [card:(set-quota:timer slice now.bowl)]~ =? old-state ?=(%0 -.old-state) ^- state-1 + =| ship-quota=(map ship @ud) + =/ [slice=@dr quota=@ud resend-time=@dr update-rate=@dr] + [~d7 7 ~m5 ~m1] =, old-state :* %1 pending sending finding history @@ -159,7 +270,8 @@ resend-time update-rate == =? old-state ?=(%1 -.old-state) - ^- app-state + ^- state-2 + =| spo=(map ship [residents=(set ship) requests=(set ship)]) =, old-state :* %2 pending sending finding history @@ -168,10 +280,35 @@ frequency endpoint contract chain-id resend-time update-rate == - ?> ?=(%2 -.old-state) + =? old-state ?=(%2 -.old-state) + ^- state-3 + =, old-state + =| allowances=(map ship (unit @ud)) + =/ next-slice=time (mul +((div now.bowl slice)) slice) + :* %3 + pending sending finding history + ship-quota allowances + next-nonce next-batch next-slice + pre own spo pk slice quota derive + frequency endpoint contract chain-id + resend-time update-rate + == + =? old-state ?=(%3 -.old-state) + ^- app-state + =, old-state + =/ fallback-gas-price=@ud 10.000.000.000 + :* %4 + pending sending finding history + ship-quota allowances + next-nonce next-batch next-slice + pre own spo pk slice quota derive + frequency endpoint contract chain-id + resend-time update-rate fallback-gas-price + == + ?> ?=(%4 -.old-state) [cards this(state old-state)] :: - ++ app-states $%(state-0 state-1 app-state) + ++ app-states $%(state-0 state-1 state-2 state-3 app-state) ++ state-0 $: %0 pending=(list pend-tx) @@ -212,6 +349,55 @@ resend-time=@dr update-rate=@dr == + :: + ++ state-2 + $: %2 + pending=(list pend-tx) + sending=(tree [l1-tx-pointer send-tx]) + finding=(map keccak ?(%confirmed %failed [=time l1-tx-pointer])) + history=(map address:ethereum (tree hist-tx)) + ship-quota=(map ship @ud) + next-nonce=(unit @ud) + next-batch=time + pre=^state:naive + own=owners + spo=sponsors + pk=@ + slice=@dr + quota=@ud + derive=? + frequency=@dr + endpoint=(unit @t) + contract=@ux + chain-id=@ + resend-time=@dr + update-rate=@dr + == + ++ state-3 + $: %3 + pending=(list pend-tx) + sending=(tree [l1-tx-pointer send-tx]) + finding=(map keccak ?(%confirmed %failed [=time l1-tx-pointer])) + history=(map address:ethereum (tree hist-tx)) + ship-quota=(map ship @ud) + allowances=(map ship (unit @ud)) + next-nonce=(unit @ud) + next-batch=time + next-slice=time + pre=^state:naive + own=owners + spo=sponsors + pk=@ + slice=@dr + quota=@ud + derive=? + frequency=@dr + endpoint=(unit @t) + contract=@ux + chain-id=@ + resend-time=@dr + update-rate=@dr + == -- :: ++ on-poke @@ -229,13 +415,14 @@ :: /x/pending -> %noun (list pend-tx) :: /x/pending/[~ship] -> %noun (list pend-tx) :: /x/pending/[0xadd.ress] -> %noun (list pend-tx) - :: /x/tx/[0xke.ccak]/[@ud]status -> %noun tx-status + :: /x/tx/[0xke.ccak]/status -> %noun tx-status :: /x/history/[0xadd.ress] -> %noun (list hist-tx) :: /x/nonce/[~ship]/[proxy] -> %noun (unit @) :: /x/spawned/[~star] -> %noun (list ship) :: /x/unspawned/[~star] -> %noun (list ship) :: /x/sponsored/[~point] -> %noun [(list ship) (list ship)] :: /x/next-batch -> %atom time + :: /x/next-slice -> %atom time :: /x/point/[~ship] -> %noun point:naive :: /x/ships/[0xadd.ress] -> %noun (list ship) :: /x/config -> %noun config @@ -249,209 +436,44 @@ :: /x/quota -> %atom @ud :: /x/slice -> %atom @dr :: /x/over-quota/[~ship] -> %atom ? + :: /x/ship-quota/[~ship] -> %atom @ud + :: /x/allowances -> %noun (map @p (unit @ud)) + :: /x/allowance/[~ship] -> %noun (unit @ud) :: /x/ready -> %atom ? :: ++ on-peek |= =path ^- (unit (unit cage)) - |^ ?+ path ~ [%x %pending ~] ``noun+!>(pending) - [%x %pending @ ~] (pending-by i.t.t.path) - [%x %tx @ %status ~] (status i.t.t.path) - [%x %pending-tx @ ~] (transaction i.t.t.path) - [%x %history @ ~] (history i.t.t.path) - [%x %nonce @ @ ~] (nonce i.t.t.path i.t.t.t.path) - [%x %spawned @ ~] (spawned i.t.t.path) - [%x %unspawned @ ~] (unspawned i.t.t.path) - [%x %sponsored @ ~] (sponsored i.t.t.path) + [%x %pending @ ~] (pending-by:on-peek:do i.t.t.path) + [%x %tx @ %status ~] (status:on-peek:do i.t.t.path) + [%x %pending-tx @ ~] (transaction:on-peek:do i.t.t.path) + [%x %history @ ~] (history:on-peek:do i.t.t.path) + [%x %nonce @ @ ~] (nonce:on-peek:do i.t.t.path i.t.t.t.path) + [%x %spawned @ ~] (spawned:on-peek:do i.t.t.path) + [%x %unspawned @ ~] (unspawned:on-peek:do i.t.t.path) + [%x %sponsored @ ~] (sponsored:on-peek:do i.t.t.path) [%x %next-batch ~] ``atom+!>(next-batch) - [%x %point @ ~] (point i.t.t.path) - [%x %ships @ ~] (ships i.t.t.path) - [%x %config ~] config + [%x %next-slice ~] ``atom+!>(next-slice) + [%x %point @ ~] (point:on-peek:do i.t.t.path) + [%x %ships @ ~] (ships:on-peek:do i.t.t.path) + [%x %config ~] config:on-peek:do [%x %chain-id ~] ``atom+!>(chain-id) - [%x %owned @ ~] (points-proxy %own i.t.t.path) - [%x %transfers @ ~] (points-proxy %transfer i.t.t.path) - [%x %manager @ ~] (points-proxy %manage i.t.t.path) - [%x %voting @ ~] (points-proxy %vote i.t.t.path) - [%x %spawning @ ~] (points-proxy %spawn i.t.t.path) + [%x %owned @ ~] (points-proxy:on-peek:do %own i.t.t.path) + [%x %transfers @ ~] (points-proxy:on-peek:do %transfer i.t.t.path) + [%x %manager @ ~] (points-proxy:on-peek:do %manage i.t.t.path) + [%x %voting @ ~] (points-proxy:on-peek:do %vote i.t.t.path) + [%x %spawning @ ~] (points-proxy:on-peek:do %spawn i.t.t.path) [%x %predicted ~] ``noun+!>(pre) [%x %quota ~] ``atom+!>(quota) [%x %slice ~] ``atom+!>(slice) - [%x %over-quota @ ~] (over-quota i.t.t.path) + [%x %over-quota @ ~] (over-quota:on-peek:do i.t.t.path) + [%x %ship-quota @ ~] (ship-quota:on-peek:do i.t.t.path) + [%x %allowances ~] ``noun+!>(allowances) + [%x %allowance @ ~] (allowance:on-peek:do i.t.t.path) [%x %ready ~] ``atom+!>(?=(^ points.pre)) == - :: - ++ pending-by - |= wat=@t - ?~ who=(slaw %p wat) - :: by-address - :: - ?~ wer=(slaw %ux wat) - [~ ~] - =; pending=(list pend-tx) - ``noun+!>(pending) - %+ skim pending - |= pend-tx - :: TODO: use this instead? =(u.wer address) - :: - ?~ addr=(get-l1-address tx.raw-tx pre) | - =(u.wer u.addr) - :: by-ship - :: - =; pending=(list pend-tx) - ``noun+!>(pending) - %+ skim pending - |= pend-tx - =(u.who ship.from.tx.raw-tx) - :: - ++ status - |= wat=@t - ?~ keccak=(slaw %ux wat) - [~ ~] - :+ ~ ~ - :- %noun - !> ^- tx-status - ?^ status=(~(get by finding) u.keccak) - ?@ u.status [u.status ~] - [%sending `+.u.status] - :: TODO: potentially slow! - =; known=? - [?:(known %pending %unknown) ~] - %+ lien pending - |= pend-tx - =(u.keccak (hash-raw-tx:lib raw-tx)) - :: - ++ transaction - |= wat=@t - ?~ keccak=(slaw %ux wat) - [~ ~] - :+ ~ ~ - :- %noun - !> ^- (unit pend-tx) - :: TODO: potentially slow! - |- - ?~ pending ~ - =* tx i.pending - ?: =(u.keccak (hash-tx:lib raw.raw-tx.tx)) - `tx - $(pending t.pending) - :: - ++ history - |= wat=@t - :+ ~ ~ - :- %noun - !> ^- (list hist-tx) - ?~ addr=(slaw %ux wat) ~ - ?~ hist=(~(get by ^history) u.addr) ~ - (tap:orh u.hist) - :: - ++ nonce - |= [who=@t proxy=@t] - ?~ who=(slaw %p who) - [~ ~] - ?. ?=(proxy:naive proxy) - [~ ~] - :+ ~ ~ - :- %noun - !> ^- (unit @) - ?~ point=(get:orp points.pre u.who) - ~ - =< `nonce - (proxy-from-point:naive proxy u.point) - :: - ++ spawned - |= wat=@t - :+ ~ ~ - :- %noun - !> ^- (list @p) - ?~ star=(slaw %p wat) ~ - =; range - (turn range head) - :: range exclusive [star first-moon-last-planet] - :: - %- tap:orp - (lot:orp points.pre [`u.star `(cat 3 u.star 0x1.ffff)]) - :: - ++ unspawned - |= wat=@t - :+ ~ ~ - :- %noun - !> ^- (list @p) - ?~ star=(slaw %p wat) ~ - =/ spawned=(set @p) - =; points - (~(gas in *(set @p)) (turn points head)) - %- tap:orp - (lot:orp points.pre [`u.star `(cat 3 u.star 0x1.ffff)]) - =/ children=(list @p) - (turn (gulf 0x1 0xffff) |=(a=@ (cat 3 u.star a))) - %+ murn children - |= =ship - ?: (~(has in spawned) ship) ~ - `ship - :: - ++ sponsored - |= wat=@t - :+ ~ ~ - :- %noun - !> ^- [(list ship) (list ship)] - ?~ who=(slaw %p wat) [~ ~] - ?~ sponsor=(~(get by spo) u.who) - [~ ~] - :- ~(tap in residents.u.sponsor) - ~(tap in requests.u.sponsor) - :: - ++ point - |= wat=@t - ?~ ship=(rush wat ;~(pfix sig fed:ag)) - ``noun+!>(*(unit point:naive)) - ``noun+!>((get:orp points.pre u.ship)) - :: - ++ ships - |= wat=@t - :+ ~ ~ - :- %noun - !> ^- (list ship) - ?~ addr=(slaw %ux wat) - ~ - =/ proxies=(list proxy:naive) - ~[%own %spawn %manage %vote %transfer] - %+ roll proxies - |= [=proxy:naive ships=(list ship)] - %+ weld ships - ~(tap in (~(get ju own) [proxy u.addr])) - :: - ++ config - :+ ~ ~ - :- %noun - !> ^- roller-config - :* next-batch - frequency - resend-time - update-rate - contract - chain-id - slice - quota - == - :: - ++ points-proxy - |= [=proxy:naive wat=@t] - :+ ~ ~ - :- %noun - !> ^- (list ship) - ?~ addr=(slaw %ux wat) - ~ - ~(tap in (~(get ju own) [proxy u.addr])) - :: - ++ over-quota - |= wat=@t - ?~ who=(slaw %p wat) [~ ~] - =/ [exceeded=? *] (quota-exceeded u.who) - ``atom+!>(exceeded) - :: - -- :: ++ on-arvo |= [=wire =sign-arvo] @@ -459,7 +481,7 @@ ?+ wire (on-arvo:def wire sign-arvo) [%timer ~] ?+ +<.sign-arvo (on-arvo:def wire sign-arvo) - %wake =^(cards state on-timer:do [cards this]) + %wake =^(cards state (on-timer:do &) [cards this]) == [%quota-timer ~] ?+ +<.sign-arvo (on-arvo:def wire sign-arvo) @@ -469,9 +491,8 @@ [%predict ~] ?+ +<.sign-arvo (on-arvo:def wire sign-arvo) %wake - =. own.state canonical-owners:do =^ effects state - (predicted-state canonical-state):do + (predicted-state canonical):do [(emit effects) this(derive &)] == :: @@ -494,35 +515,44 @@ :_ this |^ ?+ path (on-watch:def path) - [%txs @ ~] [%give %fact ~ (give-txs i.t.path)]~ - [%points @ ~] [%give %fact ~ (give-points i.t.path)]~ + [%txs @ ~] ?>(?=(^ (slaw %ux i.t.path)) ~) + [%points @ ~] ?>(?=(^ (slaw %ux i.t.path)) ~) + [%connect @ ~] [%give %fact ~ (init i.t.path)]~ == :: - ++ give-points + ++ init |= wat=@t ^- cage - :- %points - !> ^- (list [ship point:naive]) - ?~ addr=(slaw %ux wat) ~ - =/ proxies=(list proxy:naive) - ~[%own %spawn %manage %vote %transfer] - %+ roll proxies - |= [=proxy:naive points=(list [ship point:naive])] - %+ weld points - :: - %+ roll ~(tap in (~(get ju own) [proxy u.addr])) - |= [=ship points=_points] - %+ snoc points - [ship (need (get:orp points.pre ship))] + :- %roller-data + !> ^- roller-data + ?~ addr=(slaw %ux wat) !! + =/ [=owners =sponsors =points:naive] + (give-points u.addr) + =/ txs=(tree hist-tx) (give-history u.addr) + [chain-id points txs owners sponsors] :: - ++ give-txs - |= wat=@t - ^- cage - :- %txs - !> ^- (list hist-tx) - ?~ addr=(slaw %ux wat) ~ - ?~ hist=(~(get by history) u.addr) ~ - (tap:orh u.hist) + ++ give-points + |= =address:ethereum + ^- [owners sponsors points:naive] + =/ controlled=(list [proxy:naive ship]) + (controlled-ships:dice address own) + %+ roll controlled + |= [[=proxy:naive =ship] =owners =sponsors =points:naive] + =/ sponsoring (~(get by spo.state) ship) + :+ (~(put ju owners) [proxy address] ship) + :: + ?~ sponsoring sponsors + (~(put by sponsors) ship u.sponsoring) + :: + %+ put:orp:dice points + [ship (need (get:orp:dice points.pre ship))] + :: + ++ give-history + |= =address:ethereum + ^- (tree hist-tx) + ?~ hist=(~(get by history) address) + ~ + u.hist -- :: ++ on-leave on-leave:def @@ -550,7 +580,7 @@ [~ this] %- (slog leaf+"{(trip dap.bowl)} couldn't start thread" u.p.sign) :_ this - [(leave:spider:do wire)]~ + [(leave:spider:do our.bowl wire)]~ :: %watch-ack ?~ p.sign @@ -568,7 +598,7 @@ =+ !<([=term =tang] q.cage.sign) %- (slog leaf+"{(trip dap.bowl)} failed" leaf+ tang) =^ cards state - (on-batch-result:do address nonce %.n^[%error 'thread failed']) + (on-batch-result:do address nonce %.n^[%crash 'thread failed']) [cards this] :: %thread-done @@ -599,14 +629,9 @@ :: %naive-state ~& > %received-azimuth-state - :: cache naive and ownership state - :: - =+ !<([nas=^state:naive own=owners spo=sponsors] q.cage.sign) - =: own.state own - spo.state spo - == + =+ !<([nas=^state:naive =indices] q.cage.sign) =^ effects state - (predicted-state:do nas) + (predicted-state:do nas indices) [(emit effects) this] == == @@ -621,7 +646,7 @@ [~ this] %- (slog leaf+"{(trip dap.bowl)} couldn't start thread" u.p.sign) :_ this - [(leave:spider:do wire)]~ + [(leave:spider:do our.bowl wire)]~ :: %watch-ack ?~ p.sign @@ -657,7 +682,7 @@ [~ this] %- (slog leaf+"{(trip dap.bowl)} couldn't start thread" u.p.sign) :_ this - [(leave:spider:do wire)]~ + [(leave:spider:do our.bowl wire)]~ :: %watch-ack ?~ p.sign @@ -687,122 +712,49 @@ -- :: |_ =bowl:gall -::TODO /lib/sys.hoon? -++ sys - |% - ++ b - |% - ++ wait - |= [=wire =time] - ^- card - [%pass wire %arvo %b %wait time] - -- - -- -::TODO /lib/spider.hoon? -++ spider - |% - ++ start-thread - |= [=wire thread=term arg=vase] - ^- (list card) - =/ =beak byk.bowl(r da+now.bowl) - =/ tid=@ta (rap 3 thread '--' (scot %uv eny.bowl) ~) - =/ args [~ `tid beak thread arg] - :~ [%pass wire %agent [our.bowl %spider] %watch /thread-result/[tid]] - [%pass wire %agent [our.bowl %spider] %poke %spider-start !>(args)] +:: +canonical: current naive, ownership, and sponsorship state +:: +++ canonical + |^ nas^own^spo + :: + ++ nas + .^ ^state:naive + %gx + (scot %p our.bowl) + %azimuth + (scot %da now.bowl) + /nas/noun == :: - ++ leave - |= =path - ^- card - [%pass path %agent [our.bowl %spider] %leave ~] - -- -:: -:: -++ emit - |= updates=(list update) - |- ^- (list card) - ?~ updates ~ - =* up i.updates - =/ [address=@t last-owner=(unit @t)] - ?- -.up - %tx - :_ ~ - (scot %ux address.up) - :: - %point - :- (scot %ux address.new.up) - ?~(old.up ~ `(scot %ux address.u.old.up)) + ++ own + .^ owners + %gx + (scot %p our.bowl) + %azimuth + (scot %da now.bowl) + /own/noun == - %+ weld - $(updates t.updates) - ^- (list card) - ?- -.i.updates - %tx - [%give %fact ~[/txs/[address]] tx+!>(roll-tx.up)]~ :: - %point - %+ weld - [%give %fact ~[/points/[address]] point+!>([ship point]:up)]~ - ?~ last-owner ~ - [%give %fact ~[/points/[u.last-owner]] point+!>([ship point]:up)]~ - == -:: -++ part-tx-to-full - |= =part-tx - ^- [octs tx:naive] - ?- -.part-tx - %raw - ?~ batch=(parse-raw-tx:naive 0 q.raw.part-tx) - ~? lverb [dap.bowl %parse-failed] - :: TODO: maybe return a unit if parsing fails? - :: - !! - [raw tx]:-.u.batch - :: - %don [(gen-tx-octs:lib +.part-tx) +.part-tx] - %ful +.part-tx - == -:: +canonical-state: current l2 state from /app/azimuth -:: -++ canonical-state - .^ ^state:naive - %gx - (scot %p our.bowl) - %azimuth - (scot %da now.bowl) - /nas/noun - == -:: +canonical-owners: current azimuth point ownership -:: -++ canonical-owners - .^ owners - %gx - (scot %p our.bowl) - %azimuth - (scot %da now.bowl) - /own/noun - == -:: +canonical-sponsors: current azimuth sponsorship -:: -++ canonical-sponsors - .^ sponsors - %gx - (scot %p our.bowl) - %azimuth - (scot %da now.bowl) - /spo/noun - == + ++ spo + .^ sponsors + %gx + (scot %p our.bowl) + %azimuth + (scot %da now.bowl) + /spo/noun + == + -- :: +predicted-state :: :: derives predicted state from applying pending & sending txs to :: the provided naive state, discarding invalid txs in the process :: ++ predicted-state - |= nas=^state:naive + |= [nas=^state:naive =indices] ^- (quip update _state) =: pre nas - own canonical-owners - spo canonical-sponsors + own own.indices + spo spo.indices == |^ =^ [nes=_sending updates-1=(list update)] state @@ -818,7 +770,7 @@ ++ apply-sending =| ups=(list update) =/ valid=_sending ~ - =+ sorted=(tap:ors sending) + =+ sorted=(tap:ors:dice sending) |- ^+ [[valid ups] state] ?~ sorted [[valid ups] state] :: @@ -830,7 +782,7 @@ :: we only hear updates for this nonce if it has been sent :: =. valid ::=? valid sent.val - %^ put:ors valid + %^ put:ors:dice valid key :: TODO: too much functional hackery? val(txs (turn new-valid (cork tail (cork tail tail)))) @@ -839,64 +791,54 @@ ++ apply-txs |= [txs=(list pend-tx) type=?(%pending %sending) nonce=(unit @ud)] =/ valid=_txs ~ - =| ups=(list update) - |- ^+ [[valid ups] state] - ?~ txs [[(flop valid) ups] state] + =| updates=(list update) + |- ^+ [[valid updates] state] + ?~ txs + :_ state + [(flop valid) (flop updates)] :: =* tx i.txs =* raw-tx raw-tx.i.txs =* ship ship.from.tx.raw-tx.i.txs =/ =keccak (hash-raw-tx:lib raw-tx) - =/ sign-address=(unit @ux) - (extract-address:lib raw-tx pre chain-id) - =^ [gud=? nups=_ups] state + =^ [gud=? up-1=_updates] state (try-apply pre force.tx raw-tx) - :: TODO: only replace address if !=(address.tx sign-address)? - :: - =? tx &(gud ?=(^ sign-address)) - tx(address u.sign-address) =/ =roll-tx [ship type keccak (l2-tx +<.tx.raw-tx)] - =? nups !gud - %+ snoc nups - [%tx address.tx roll-tx(status %failed)] =? valid gud [tx valid] - =? history !gud - =/ =time + =^ up-2 history + ?: gud [~ history] + =. time.tx ?: ?=(%pending type) time.tx =+ wer=(~(got by finding) keccak) ?>(?=(^ wer) time.wer) - =+ txs=(~(got by history) address.tx) - =. txs +:(del:orh txs time) - %+ ~(put by history) address.tx - %+ put:orh txs - [time roll-tx(status %failed)] + (update-history:dice history [tx]~ %failed) =? finding !gud (~(put by finding) keccak %failed) - $(txs t.txs, ups (weld ups nups)) + =. updates :(welp up-2 up-1 updates) + $(txs t.txs) -- :: +try-apply: maybe apply the given l2 tx to the naive state :: ++ try-apply |= [nas=^state:naive force=? =raw-tx:naive] ^- [[? ups=(list update)] _state] - =/ [success=? ups=(list update) predicted=_nas owners=_own sponsors=_spo] + =/ [success=? updates=(list update) predicted=_nas =indices] (apply-raw-tx:dice force chain-id raw-tx nas own spo) - :- [success ups] - state(pre predicted, own owners, spo sponsors) -:: -++ get-l1-address - |= [=tx:naive nas=^state:naive] - ^- (unit address:ethereum) - ?~ point=(get:orp points.nas ship.from.tx) ~ - =< `address - (proxy-from-point:naive proxy.from.tx u.point) + =: pre predicted + own own.indices + spo spo.indices + == + [[success updates] state] :: ++ on-action |= =action ^- (quip card _state) =+ local=(team:title our.bowl src.bowl) + |^ ?- -.action - %commit ?>(local on-timer) + %commit ?>(local (on-timer |)) %config ?>(local (on-config +.action)) + %assign ?>(local `state(allowances (~(put by allowances) +.action))) + %refuel ?>(local (refuel-tx +.action)) %cancel (cancel-tx +.action) :: %submit @@ -912,12 +854,30 @@ (part-tx-to-full tx.action) == == + :: + ++ part-tx-to-full + |= =part-tx + ^- [octs tx:naive] + ?- -.part-tx + %raw + ?~ batch=(parse-raw-tx:naive 0 q.raw.part-tx) + ~? lverb [dap.bowl %parse-failed] + :: TODO: maybe return a unit if parsing fails? + :: + !! + [raw tx]:-.u.batch + :: + %don [(gen-tx-octs:lib +.part-tx) +.part-tx] + %ful +.part-tx + == + -- :: ++ on-config |= =config ^- (quip card _state) ?- -.config %frequency [~ state(frequency frequency.config)] + %fallback [~ state(fallback-gas-price gas.config)] %resend-time [~ state(resend-time time.config)] %update-rate [~ state(update-rate rate.config)] %slice [~ state(slice slice.config)] @@ -941,15 +901,12 @@ == :: %setkey + =? pk.config =((end [3 2] pk.config) '0x') + (rsh [3 2] pk.config) ?~ pk=(de:base16:mimes:html pk.config) `state [(get-nonce q.u.pk /nonce) state(pk q.u.pk)] == -:: TODO: move address to state? -:: -++ get-address - ^- address:ethereum - (address-from-prv:key:ethereum pk) :: +cancel-tx: cancel a pending transaction :: ++ cancel-tx @@ -987,12 +944,27 @@ %_ state history =+ txs=(~(got by history) u.addr) - =. txs +:(del:orh txs u.time) + =. txs +:(del:orh:dice txs u.time) %+ ~(put by history) u.addr - %^ put:orh txs + %^ put:orh:dice txs u.time [ship %cancelled keccak l2-tx] == +:: +refuel-tx: bumps the gas price for a sending tx +:: +++ refuel-tx + |= [nonce=@ud address=(unit address:ethereum) gas=@ud] + ^- (quip card _state) + =/ batch=[address:ethereum @ud] + :_ nonce + ?^(address u.address (get-address pk.state)) + =. sending + ?~ send-tx=(get:ors:dice sending batch) + sending + %^ put:ors:dice sending + batch + u.send-tx(next-gas-price gas) + `state :: +take-tx: accept submitted l2 tx into the :pending list :: ++ take-tx @@ -1001,10 +973,14 @@ =* ship ship.from.tx.raw-tx.pend-tx =/ [exceeded=? next-quota=@] (quota-exceeded ship) ?: exceeded [~ state] + =/ sign-address=(unit @ux) + (extract-address:lib raw-tx.pend-tx pre chain-id) + =? address.pend-tx ?=(^ sign-address) + (need sign-address) =^ [gud=? cards-1=(list update)] state - (try-apply pre [force raw-tx]:pend-tx) + (try-apply pre [force raw-tx]:pend-tx) =^ cards-2 history - (update-history [pend-tx]~ ?:(gud %pending %failed)) + (update-history:dice history [pend-tx]~ ?:(gud %pending %failed)) ?. gud :_ state :: %point and (%failed) %tx updates @@ -1021,33 +997,17 @@ (emit cards-2) :: %tx updates :: ?. derive ~ - :: defer updating predicted naive/ownership state from canonical + :: defer updating predicted state from canonical :: [(wait:b:sys /predict (add update-rate now.bowl))]~ == -:: -++ timer - |% - :: +set-roller: %wait until next whole :frequency - :: - ++ set-roller - ^- [=card =time] - =+ time=(mul +((div now.bowl frequency)) frequency) - [(wait:b:sys /timer time) time] - :: +set-roller: %wait until next whole :slice - :: - ++ set-quota - |= slice=@dr - ^- card - =+ time=(mul +((div now.bowl slice)) slice) - (wait:b:sys /quota-timer time) - -- :: +on-timer: every :frequency, freeze :pending txs roll and start sending it :: ++ on-timer + |= new=? ^- (quip card _state) =^ updates-1 state - (predicted-state canonical-state) + (predicted-state canonical) =^ cards state ?: =(~ pending) [~ state] ?~ next-nonce @@ -1056,20 +1016,21 @@ :: when the thread that's sending the previous batch :: has come back and confirms that it was sent to L1 :: - ?: out-of-sync + ?: pending-batch :: this would postpone sending the batch for a whole "frequency" :: TODO: set up a timer to retry this in ~mX ? :: ~? lverb [dap.bowl %nonce-out-sync] [~ state] - =/ nonce=@ud u.next-nonce - =^ updates-2 history (update-history pending %sending) + =/ nonce=@ud u.next-nonce + =^ updates-2 history (update-history:dice history pending %sending) + =/ =address:ethereum (get-address pk) =: pending ~ derive & next-nonce `+(u.next-nonce) :: sending - %^ put:ors sending - [get-address nonce] + %^ put:ors:dice sending + [address nonce] [0 | (turn pending (cork tail (cork tail tail)))] :: finding @@ -1082,68 +1043,77 @@ ;: welp (emit updates-1) (emit updates-2) - (send-roll get-address nonce) + (send-roll address nonce) == - =^ card next-batch set-roller:timer - [[card cards] state] + ?. new cards^state + =^ card next-batch + (set-roller:timer frequency now.bowl) + [card cards]^state :: +on-quota-timer: resets tx quota for all ships :: ++ on-quota-timer ^- (quip card _state) - :- [(set-quota:timer slice)]~ + =^ card next-slice (set-quota:timer slice now.bowl) + :- [card]~ state(ship-quota *(map ship @ud)) -:: -++ update-history - |= [txs=(list pend-tx) =status] - ^- [(list update) _history] - %+ roll txs - |= [pend-tx ups=(list update) sih=_history] - =/ =roll-tx - :* ship.from.tx.raw-tx - status - (hash-raw-tx:lib raw-tx) - (l2-tx +<.tx.raw-tx) - == - =/ txs=(tree hist-tx) - ?~ txs=(~(get by sih) address) ~ - u.txs - =? txs ?=(^ txs) +:(del:orh txs time) - :- (snoc ups tx+[address roll-tx]) - %+ ~(put by sih) address - (put:orh txs [time roll-tx]) :: +get-nonce: retrieves the latest nonce :: ++ get-nonce |= [pk=@ =wire] ^- (list card) ?~ endpoint ~?(lverb [dap.bowl %no-endpoint] ~) - (start-thread:spider wire [%roller-nonce !>([u.endpoint pk])]) + (start-thread:spider bowl wire [%roller-nonce !>([u.endpoint pk])]) :: ++ quota-exceeded |= =ship - ^- [? @ud] - ?~ quota=(~(get by ship-quota) ship) - [| 1] - [(gte u.quota quota.state) +(u.quota)] -:: +out-of-sync: checks if the previous nonce has been sent + ^- [exceeded=? next-quota=@ud] + =/ quota=(unit @ud) (~(get by ship-quota) ship) + =/ allow=(unit (unit @ud)) (~(get by allowances) ship) + ?~ quota + :_ 1 + ?~ allow | + ?~(u.allow | =(u.u.allow 0)) + :_ +(u.quota) + ?~ allow + (gte u.quota quota.state) + :: ship has been whitelisted ("?~ u.allow" means no quota restrictions) + :: + ?~(u.allow | (gte u.quota u.u.allow)) +:: +pending-batch: checks if the previous nonce has been sent :: -++ out-of-sync +:: If %.y, the roller has been trying to send a batch for a whole frequency. +:: +:: The cause of not sending the previous batch can happen because +:: of thread failure (see line 1251) or because the private key loaded onto +:: the roller was used for something other than signing L2 batches right +:: after the send-batch thread started. +:: +:: After reaching this state, any subsequents attempts have failed (L: 1251) +:: (prior to updating the sending nonce if we hit the on-out-of-sync case) +:: which would possibly require a manual intervention (e.g. changing the +:: ethereum node URL, adding funds to the roller's address, manually bumping +:: the fall-back-gas-price or refueling the current batch with higher gas) +:: +++ pending-batch ^- ? - ?~ newest-batch=(ram:ors sending) | + ?~ newest-batch=(ram:ors:dice sending) | !=(sent.val.u.newest-batch &) -:: +on-out-of-sync +:: +on-out-of-sync: handles a mismatch between current and expected l1 nonce :: ++ on-out-of-sync |= [nonce=@ud failed-nonce=@ud] - :: we only care about nonces >= than the one that failed + ^- (quip card _state) + ~& > %begin-on-out-of-sync + =/ =address:ethereum (get-address pk) + :: we only consider nonces >= than the one that failed :: =/ failed-sending=(list [l1-tx-pointer send-tx]) - %- tap:ors + %- tap:ors:dice :: (range exclusive) :: - (lot:ors sending [`[get-address (dec failed-nonce)] ~]) + (lot:ors:dice sending [`[address (dec failed-nonce)] ~]) =/ confirmed-sending=_sending - (lot:ors sending [~ `[get-address failed-nonce]]) + (lot:ors:dice sending [~ `[address failed-nonce]]) =/ [nes=_sending nif=_finding sih=_history] %- tail %+ roll failed-sending @@ -1158,14 +1128,14 @@ =* txs txs.q :: TODO: this shouldn't be needed ?: (lth nonce.p failed-nonce) - ~& ["weird case" nonce+nonce.p] + ~& >>> [%on-out-of-sync nonce+nonce.p failed+failed-nonce] [new-nonce sending finding history] :+ +(new-nonce) - update-sending + fix-sending process-l2-txs :: - ++ update-sending - (put:ors sending [p(nonce new-nonce) q(sent %.n)]) + ++ fix-sending + (put:ors:dice sending [p(nonce new-nonce) q(sent %.n)]) :: ++ process-l2-txs %+ roll txs.q @@ -1175,24 +1145,24 @@ ?~ val=(~(get by nif) keccak) [nif sih] ?. ?=(^ u.val) [nif sih] - :- (update-finding u.val) - (update-history time.u.val address.u.val) + :- (fix-finding u.val) + (fix-history time.u.val address.u.val) :: - ++ update-finding + ++ fix-finding |= val=[time l1-tx-pointer] ^+ nif (~(put by nif) keccak val(nonce.+ new-nonce)) :: - ++ update-history + ++ fix-history |= [=time =address:ethereum] ^+ sih =* ship ship.from.tx.raw-tx =/ l2-tx (l2-tx +<.tx.raw-tx) =/ =roll-tx [ship %sending keccak l2-tx] =+ txs=(~(got by sih) address) - =. txs +:(del:orh txs time) + =. txs +:(del:orh:dice txs time) %+ ~(put by sih) address - (put:orh txs [time roll-tx]) + (put:orh:dice txs [time roll-tx]) -- -- =: sending nes @@ -1200,24 +1170,31 @@ history sih next-nonce `+(nonce) == - [(send-roll get-address nonce) state] + ~& > %end-on-out-of-sync + [(send-roll address nonce) state] :: +send-roll: start thread to submit roll from :sending to l1 :: ++ send-roll |= [=address:ethereum =nonce:naive] ^- (list card) - :: if this nonce isn't in the sending queue anymore, it's done - :: - ?. (has:ors sending [address nonce]) - ~? lverb [dap.bowl %done-sending [address nonce]] - ~ ?~ endpoint ~? lverb [dap.bowl %no-endpoint] ~ + :: if this nonce isn't in the sending queue anymore, it's done + :: + ?. (has:ors:dice sending [address nonce]) + ~? lverb [dap.bowl %done-sending [address nonce]] + ~ + :: if there are no txs for this nonce, don't send it + :: + ?: =(0 (lent txs:(got:ors:dice sending [address nonce]))) + ~& >>> [dap.bowl %empty-nonce] + ~ :: start the thread, passing in the l2 txs to use :: TODO should go ahead and set resend timer in case thread hangs, or nah? :: - %+ start-thread:spider + %^ start-thread:spider + bowl /send/(scot %ux address)/(scot %ud nonce) :- %roller-send !> ^- rpc-send-roll @@ -1226,9 +1203,10 @@ chain-id pk nonce + fallback-gas-price :: =< [next-gas-price txs] - (got:ors sending [address nonce]) + (got:ors:dice sending [address nonce]) == :: +on-batch-result: await resend after thread success or failure :: @@ -1238,38 +1216,60 @@ :: print error if there was one :: ~? ?=(%| -.result) [dap.bowl %send-error +.p.result] - =/ =send-tx (got:ors sending [address nonce]) - =? sending ?=(%& -.result) - %^ put:ors sending + :: if this nonce was removed from the queue by a + :: previous resend-with-higher-gas thread, it's done + :: + ?. (has:ors:dice sending [address nonce]) + ~? lverb [dap.bowl %done-sending [address nonce]] + `state + ?: ?=([%| %not-sent %batch-parse-error] result) + :: if we tried to send a malformed batch, remove it from the queue + :: + ~& >>> [dap.bowl %removing-malformed-batch] + =^ * sending + (del:ors:dice sending [address nonce]) + `state + =/ =send-tx (got:ors:dice sending [address nonce]) + =? sending ?| ?=(%& -.result) + ?=([%| %crash *] result) + == + %^ put:ors:dice sending [address nonce] :: update gas price for this tx in state - :: and set it as sent to L1 :: - send-tx(next-gas-price p.result, sent &) + ?: ?=(%& -.result) + send-tx(next-gas-price p.result, sent &) + :: if the thread crashed, we don't know the gas used, + :: so we udpate it manually, same as the thread would do + :: + %_ send-tx + next-gas-price + ?: =(0 next-gas-price.send-tx) + fallback-gas-price + (add next-gas-price.send-tx 5.000.000.000) + == :_ state - ?: ?| ?=(%& -.result) - :: a general error shouldn't innitiate - :: the out-of-sync nonce thread - :: - ?=([%| %error *] result) - :: this accounts for a resend with higher gas - :: for a previous nonce, so we shouldn't start - :: the out-of-sync nonce thread - :: - ?& sent.send-tx - ?=([%| %not-sent *] result) - == == - :_ ~ - :: resend the l1 tx in five minutes + ?: ?& !sent.send-tx + ?=([%| %not-sent %behind-nonce] result) + == + :: start out-of-sync flow if our L1 nonce is behind + :: and this transaction hasn't been sent out yet :: - %+ wait:b:sys - /resend/(scot %ux address)/(scot %ud nonce) - (add resend-time now.bowl) - :: TODO: this only accounts for the case where the nonce is out of sync, - :: reaching this because of lower funds needs to be addressed manually + ~& > [dap.bowl %start-refresh-nonce-thread] + (get-nonce pk.state /refresh-nonce/(scot %ud nonce)) + :: resend the l1 tx in five minutes if: :: - ?> ?=(%not-sent -.p.result) - (get-nonce pk.state /refresh-nonce/(scot %ud nonce)) + :: - the thread succeeds and returns the next gas price + :: - the thread failed because: + :: - the roll's eth addres doesn't have enough funds to pay + :: - the thread crashes + :: - the sending L1 nonce is ahead of the expected one + :: - a general ethereum error + :: + :_ ~ + %+ wait:b:sys + /resend/(scot %ux address)/(scot %ud nonce) + (add resend-time now.bowl) :: +on-naive-diff: process l2 tx confirmations :: ++ on-naive-diff @@ -1281,7 +1281,7 @@ :_ state(derive ?:(derive | derive)) %+ weld cards ?. derive ~ - :: defer updating predicted naive/ownership state from canonical + :: defer updating state from canonical :: [(wait:b:sys /predict (add update-rate now.bowl))]~ :: @@ -1296,16 +1296,17 @@ ~? &(?=(%confirmed u.wer) ?=(~ err.diff)) [dap.bowl %weird-double-confirm from.tx.raw-tx.diff] [~ state] - =* nonce nonce.u.wer - =* address address.u.wer - =* ship ship.from.tx.raw-tx.diff - =* time time.u.wer - =* tx tx.raw-tx.diff - =/ l2-tx (l2-tx +<.tx) + =* nonce nonce.u.wer + =* tx-address address.u.wer + =* ship ship.from.tx.raw-tx.diff + =* time time.u.wer + =* tx tx.raw-tx.diff + =/ l2-tx (l2-tx +<.tx) :: remove the tx from the sending map :: =. sending - ?~ sen=(get:ors sending [get-address nonce]) + =/ =address:ethereum (get-address pk) + ?~ sen=(get:ors:dice sending [address nonce]) ~? lverb [dap.bowl %weird-double-remove nonce+nonce] sending ?~ nin=(find [raw-tx.diff]~ txs.u.sen) @@ -1313,12 +1314,13 @@ sending =. txs.u.sen (oust [u.nin 1] txs.u.sen) ?~ txs.u.sen - ~? lverb [dap.bowl %done-with-nonce [get-address nonce]] + ~? lverb + [dap.bowl %done-with-nonce [address nonce]] =^ * sending - (del:ors sending [get-address nonce]) + (del:ors:dice sending [address nonce]) sending ^+ sending - (put:ors sending [get-address nonce] u.sen) + (put:ors:dice sending [address nonce] u.sen) :: update the finding map with the new status :: =. finding @@ -1330,9 +1332,195 @@ %failed :: =^ updates history - %+ update-history - [| address time raw-tx.diff]~ - ?~(err.diff %confirmed %failed) + %^ update-history:dice + history + [| tx-address time raw-tx.diff]~ + ?~(err.diff %confirmed %failed) [(emit updates) state] :: +++ on-peek + |% + ++ pending-by + |= wat=@t + ?~ who=(slaw %p wat) + :: by-address + :: + ?~ wer=(slaw %ux wat) + [~ ~] + =; pending=(list pend-tx) + ``noun+!>(pending) + %+ skim pending + |= pend-tx + :: TODO: use this instead? =(u.wer address) + :: + ?~ addr=(get-l1-address tx.raw-tx pre) | + =(u.wer u.addr) + :: by-ship + :: + =; pending=(list pend-tx) + ``noun+!>(pending) + %+ skim pending + |= pend-tx + =(u.who ship.from.tx.raw-tx) + :: + ++ status + |= wat=@t + ?~ keccak=(slaw %ux wat) + [~ ~] + :+ ~ ~ + :- %noun + !> ^- tx-status + ?^ status=(~(get by finding) u.keccak) + ?@ u.status [u.status ~] + [%sending `+.u.status] + :: TODO: potentially slow! + =; known=? + [?:(known %pending %unknown) ~] + %+ lien pending + |= pend-tx + =(u.keccak (hash-raw-tx:lib raw-tx)) + :: + ++ transaction + |= wat=@t + ?~ keccak=(slaw %ux wat) + [~ ~] + :+ ~ ~ + :- %noun + !> ^- (unit pend-tx) + :: TODO: potentially slow! + |- + ?~ pending ~ + =* tx i.pending + ?: =(u.keccak (hash-tx:lib raw.raw-tx.tx)) + `tx + $(pending t.pending) + :: + ++ history + |= wat=@t + :+ ~ ~ + :- %noun + !> ^- (list hist-tx) + ?~ addr=(slaw %ux wat) ~ + ?~ hist=(~(get by ^history) u.addr) ~ + (tap:orh:dice u.hist) + :: + ++ nonce + |= [who=@t proxy=@t] + ?~ who=(slaw %p who) + [~ ~] + ?. ?=(proxy:naive proxy) + [~ ~] + :+ ~ ~ + :- %noun + !> ^- (unit @) + ?~ point=(get:orp:dice points.pre u.who) + ~ + =< `nonce + (proxy-from-point:naive proxy u.point) + :: + ++ spawned + |= wat=@t + :+ ~ ~ + :- %noun + !> ^- (list @p) + ?~ star=(slaw %p wat) ~ + =; range + (turn range head) + :: range exclusive [star first-moon-last-planet] + :: + %- tap:orp:dice + (lot:orp:dice points.pre [`u.star `(cat 3 u.star 0x1.ffff)]) + :: + ++ unspawned + |= wat=@t + :+ ~ ~ + :- %noun + !> ^- (list @p) + ?~ star=(slaw %p wat) ~ + =/ spawned=(set @p) + =; points + (~(gas in *(set @p)) (turn points head)) + %- tap:orp:dice + (lot:orp:dice points.pre [`u.star `(cat 3 u.star 0x1.ffff)]) + =/ children=(list @p) + (turn (gulf 0x1 0xffff) |=(a=@ (cat 3 u.star a))) + %+ murn children + |= =ship + ?: (~(has in spawned) ship) ~ + `ship + :: + ++ sponsored + |= wat=@t + :+ ~ ~ + :- %noun + !> ^- [(list ship) (list ship)] + ?~ who=(slaw %p wat) [~ ~] + ?~ sponsor=(~(get by spo) u.who) + [~ ~] + :- ~(tap in residents.u.sponsor) + ~(tap in requests.u.sponsor) + :: + ++ point + |= wat=@t + ?~ ship=(rush wat ;~(pfix sig fed:ag)) + ``noun+!>(*(unit point:naive)) + ``noun+!>((get:orp:dice points.pre u.ship)) + :: + ++ ships + |= wat=@t + :+ ~ ~ + :- %noun + !> ^- (list ship) + ?~ addr=(slaw %ux wat) ~ + (turn (controlled-ships:dice u.addr own) tail) + :: + ++ config + :+ ~ ~ + :- %noun + !> ^- roller-config + :* next-batch + frequency + resend-time + update-rate + contract + chain-id + slice + quota + == + :: + ++ points-proxy + |= [=proxy:naive wat=@t] + :+ ~ ~ + :- %noun + !> ^- (list ship) + ?~ addr=(slaw %ux wat) + ~ + ~(tap in (~(get ju own) [proxy u.addr])) + :: + ++ over-quota + |= wat=@t + ?~ who=(slaw %p wat) [~ ~] + =/ [exceeded=? *] (quota-exceeded u.who) + ``atom+!>(exceeded) + :: + ++ ship-quota + |= wat=@t + ?~ who=(slaw %p wat) [~ ~] + =/ [exceeded=? next-quota=@ud] (quota-exceeded u.who) + :+ ~ ~ + :- %atom + !> ^- @ud + ?: exceeded 0 + (sub quota.state (dec next-quota)) + :: + ++ allowance + |= wat=@t + ?~ who=(slaw %p wat) [~ ~] + :+ ~ ~ + :- %noun + !> ^- (unit @ud) + ?^ allow=(~(get by allowances) u.who) + u.allow + `quota.state + -- -- diff --git a/pkg/arvo/gen/hood/moon-breach.hoon b/pkg/arvo/gen/hood/moon-breach.hoon index 6d69fc67f..7ae8f7209 100644 --- a/pkg/arvo/gen/hood/moon-breach.hoon +++ b/pkg/arvo/gen/hood/moon-breach.hoon @@ -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] diff --git a/pkg/arvo/gen/hood/moon-cycle-keys.hoon b/pkg/arvo/gen/hood/moon-cycle-keys.hoon index a57cc9c13..f0cee0966 100644 --- a/pkg/arvo/gen/hood/moon-cycle-keys.hoon +++ b/pkg/arvo/gen/hood/moon-cycle-keys.hoon @@ -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] diff --git a/pkg/arvo/gen/hood/moon.hoon b/pkg/arvo/gen/hood/moon.hoon index ca6f0aaf1..84ec5cfe2 100644 --- a/pkg/arvo/gen/hood/moon.hoon +++ b/pkg/arvo/gen/hood/moon.hoon @@ -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] diff --git a/pkg/arvo/gen/roller/assign.hoon b/pkg/arvo/gen/roller/assign.hoon new file mode 100644 index 000000000..7f2811b8e --- /dev/null +++ b/pkg/arvo/gen/roller/assign.hoon @@ -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] diff --git a/pkg/arvo/gen/roller/refuel.hoon b/pkg/arvo/gen/roller/refuel.hoon new file mode 100644 index 000000000..4b6a001a2 --- /dev/null +++ b/pkg/arvo/gen/roller/refuel.hoon @@ -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] diff --git a/pkg/arvo/lib/azimuth-roll-rpc.hoon b/pkg/arvo/lib/azimuth-roll-rpc.hoon index baf502807..7bd33374b 100644 --- a/pkg/arvo/lib/azimuth-roll-rpc.hoon +++ b/pkg/arvo/lib/azimuth-roll-rpc.hoon @@ -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)}") -- diff --git a/pkg/arvo/lib/claz.hoon b/pkg/arvo/lib/claz.hoon index 520d57fa2..1a34ae9ff 100644 --- a/pkg/arvo/lib/claz.hoon +++ b/pkg/arvo/lib/claz.hoon @@ -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 diff --git a/pkg/arvo/lib/dice.hoon b/pkg/arvo/lib/dice.hoon index 076a5fc9a..55f918d83 100644 --- a/pkg/arvo/lib/dice.hoon +++ b/pkg/arvo/lib/dice.hoon @@ -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] -- diff --git a/pkg/arvo/lib/hood/drum.hoon b/pkg/arvo/lib/hood/drum.hoon index bccebc46e..0ec1b4959 100644 --- a/pkg/arvo/lib/hood/drum.hoon +++ b/pkg/arvo/lib/hood/drum.hoon @@ -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) diff --git a/pkg/arvo/lib/hood/helm.hoon b/pkg/arvo/lib/hood/helm.hoon index 9cee30851..055cec9f3 100644 --- a/pkg/arvo/lib/hood/helm.hoon +++ b/pkg/arvo/lib/hood/helm.hoon @@ -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) diff --git a/pkg/arvo/mar/azimuth/snapshot.hoon b/pkg/arvo/mar/azimuth/snapshot.hoon new file mode 100644 index 000000000..e30f82ba6 --- /dev/null +++ b/pkg/arvo/mar/azimuth/snapshot.hoon @@ -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 +-- diff --git a/pkg/arvo/sur/claz.hoon b/pkg/arvo/sur/claz.hoon index e28299fbd..2b3677ed8 100644 --- a/pkg/arvo/sur/claz.hoon +++ b/pkg/arvo/sur/claz.hoon @@ -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 diff --git a/pkg/arvo/sur/dice.hoon b/pkg/arvo/sur/dice.hoon index 2ba9e310f..d88c66cde 100644 --- a/pkg/arvo/sur/dice.hoon +++ b/pkg/arvo/sur/dice.hoon @@ -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] +:: -- diff --git a/pkg/arvo/sys/arvo.hoon b/pkg/arvo/sys/arvo.hoon index a0cbfcc2c..3c85edda6 100644 --- a/pkg/arvo/sys/arvo.hoon +++ b/pkg/arvo/sys/arvo.hoon @@ -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 diff --git a/pkg/arvo/sys/lull.hoon b/pkg/arvo/sys/lull.hoon index 2e457aa4c..cef2295a1 100644 --- a/pkg/arvo/sys/lull.hoon +++ b/pkg/arvo/sys/lull.hoon @@ -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])] diff --git a/pkg/arvo/sys/vane/ames.hoon b/pkg/arvo/sys/vane/ames.hoon index 41742600b..6a3f8e7e4 100644 --- a/pkg/arvo/sys/vane/ames.hoon +++ b/pkg/arvo/sys/vane/ames.hoon @@ -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) :: diff --git a/pkg/arvo/sys/vane/jael.hoon b/pkg/arvo/sys/vane/jael.hoon index 46533ab34..d335f2359 100644 --- a/pkg/arvo/sys/vane/jael.hoon +++ b/pkg/arvo/sys/vane/jael.hoon @@ -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) :: diff --git a/pkg/arvo/sys/zuse.hoon b/pkg/arvo/sys/zuse.hoon index 753b531a2..6967e6883 100644 --- a/pkg/arvo/sys/zuse.hoon +++ b/pkg/arvo/sys/zuse.hoon @@ -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 '')] (star -)) diff --git a/pkg/arvo/ted/azimuth/snap-logs.hoon b/pkg/arvo/ted/azimuth/snap-logs.hoon new file mode 100644 index 000000000..4e513440c --- /dev/null +++ b/pkg/arvo/ted/azimuth/snap-logs.hoon @@ -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: {}" + leaf+"block-hash: {}" + == +:: +=/ =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')) diff --git a/pkg/arvo/ted/azimuth/snap-state.hoon b/pkg/arvo/ted/azimuth/snap-state.hoon new file mode 100644 index 000000000..93c22a01c --- /dev/null +++ b/pkg/arvo/ted/azimuth/snap-state.hoon @@ -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: {}" + leaf+"block-hash: {}" + == +:: +=/ =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')) diff --git a/pkg/arvo/ted/eth-watcher.hoon b/pkg/arvo/ted/eth-watcher.hoon index 5e53e03e3..d06ace4a1 100644 --- a/pkg/arvo/ted/eth-watcher.hoon +++ b/pkg/arvo/ted/eth-watcher.hoon @@ -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 diff --git a/pkg/arvo/ted/roller/send.hoon b/pkg/arvo/ted/roller/send.hoon index 443f0cb5f..6302f34f2 100644 --- a/pkg/arvo/ted/roller/send.hoon +++ b/pkg/arvo/ted/roller/send.hoon @@ -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] diff --git a/pkg/arvo/tests/sys/zuse/crypto/secp256k1.hoon b/pkg/arvo/tests/sys/zuse/crypto/secp256k1.hoon index ee27c2ef8..03ef63f8d 100644 --- a/pkg/arvo/tests/sys/zuse/crypto/secp256k1.hoon +++ b/pkg/arvo/tests/sys/zuse/crypto/secp256k1.hoon @@ -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) -- diff --git a/pkg/base-dev/lib/azimuth.hoon b/pkg/base-dev/lib/azimuth.hoon index 32f5c03a7..d9c6a1b2e 100644 --- a/pkg/base-dev/lib/azimuth.hoon +++ b/pkg/base-dev/lib/azimuth.hoon @@ -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 diff --git a/pkg/base-dev/lib/pill.hoon b/pkg/base-dev/lib/pill.hoon index 95e49b8b5..56e01b677 100644 --- a/pkg/base-dev/lib/pill.hoon +++ b/pkg/base-dev/lib/pill.hoon @@ -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 diff --git a/pkg/base-dev/lib/shoe.hoon b/pkg/base-dev/lib/shoe.hoon index 0348e10e5..cd4ab18db 100644 --- a/pkg/base-dev/lib/shoe.hoon +++ b/pkg/base-dev/lib/shoe.hoon @@ -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 diff --git a/pkg/garden/desk.docket-0 b/pkg/garden/desk.docket-0 index 8c07fb65c..84ed3c858 100644 --- a/pkg/garden/desk.docket-0 +++ b/pkg/garden/desk.docket-0 @@ -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' == diff --git a/pkg/grid/package-lock.json b/pkg/grid/package-lock.json index 08a3d69e8..c22112641 100644 --- a/pkg/grid/package-lock.json +++ b/pkg/grid/package-lock.json @@ -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", diff --git a/pkg/grid/package.json b/pkg/grid/package.json index 17d59ae36..41555e27f 100644 --- a/pkg/grid/package.json +++ b/pkg/grid/package.json @@ -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", diff --git a/pkg/grid/src/components/Checkbox.tsx b/pkg/grid/src/components/Checkbox.tsx new file mode 100644 index 000000000..5f4de6be4 --- /dev/null +++ b/pkg/grid/src/components/Checkbox.tsx @@ -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 = ({ + 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 ( +
+ + + + + + +
+ ); +}; diff --git a/pkg/grid/src/components/icons/Lock.tsx b/pkg/grid/src/components/icons/Lock.tsx new file mode 100644 index 000000000..93f0f13ae --- /dev/null +++ b/pkg/grid/src/components/icons/Lock.tsx @@ -0,0 +1,20 @@ +import React from 'react'; + +export const Lock = (props: React.SVGProps) => ( + + + +); diff --git a/pkg/grid/src/nav/SystemPreferences.tsx b/pkg/grid/src/nav/SystemPreferences.tsx index 78ca87f4c..50e08fc5b 100644 --- a/pkg/grid/src/nav/SystemPreferences.tsx +++ b/pkg/grid/src/nav/SystemPreferences.tsx @@ -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')} > -
+
-