diff --git a/.github/actions/restore-node/action.yml b/.github/actions/restore-node/action.yml index de2c7d4fe788..9cb37d4e3d19 100644 --- a/.github/actions/restore-node/action.yml +++ b/.github/actions/restore-node/action.yml @@ -131,21 +131,23 @@ runs: sudo apt-get update sudo apt-get install libbsd-dev fi + + # Preserve the original package.json to restore it after Endo replacements. + cp -a package.json package.json.orig + # Replace the Endo packages with the ones built from the checked-out branch. if test -e ~/endo; then scripts/get-packed-versions.sh ~/endo | scripts/resolve-versions.sh fi yarn install - if ! cmp -s <(git cat-file blob HEAD:package.json) package.json; then - # In the event that the package.json has been modified by Endo - # replacements, we need to have a yarn-installed.sum that matches - # the unmodified package.json. As long as we don't explicitly `yarn - # install` anywhere other than in this action and in the bin/agd - # script, we should be able to reuse even Endo-overridden built caches - # successfully. - git checkout HEAD -- package.json - fi + # In the event that the package.json has been modified by Endo + # replacements, we need to have a yarn-installed timestamp that + # corresponds to the unmodified package.json. As long as we don't + # explicitly `yarn install` anywhere other than in this action and in + # the bin/agd script, we should be able to reuse even Endo-overridden + # built caches successfully. + mv package.json.orig package.json if test -e ~/endo; then # Stage the redirected `yarn install` consequences. diff --git a/a3p-integration/README.md b/a3p-integration/README.md index 7c30ea352a2f..9139b146c85f 100644 --- a/a3p-integration/README.md +++ b/a3p-integration/README.md @@ -1,6 +1,6 @@ # Overview -This folder contains an end-to-end integration test executed against a synthetic agoric-3 chain. The test performs a chain software upgrade to the software contained in the enclosing `agoric-sdk` repository, then executes a series of functional tests verifying the upgrade accomplished its goal. +This directory contains an end-to-end integration test executed against a synthetic agoric-3 chain. The test performs a chain software upgrade to the software contained in the enclosing `agoric-sdk` repository, then executes a series of functional tests verifying the upgrade accomplished its goal. # How to run @@ -38,9 +38,17 @@ yarn test --debug -m "proposal-name" ## Package layering -Proposals are packages under the `/a3p-integration/proposals` folder, and are separate from each other, from the `a3p-integration` test environment, and from the enclosing `agoric-sdk` repository. They run inside the docker image, and cannot access SDK code. The are lower case, and executed in lexical order. +Proposals are packages under the `/a3p-integration/proposals` folder, and are +separate from each other, from the `a3p-integration` test environment, and from +the enclosing `agoric-sdk` repository. They run inside the docker image, and +cannot access SDK code. Their names must be lower case. -In the release branches, the end-to-end `a3p-integration` test usually only has a single proposal package named `a:upgrade-NN`, which performs a chain software upgrade proposal to the corresponding upgrade plan. In the `master` branch, there may also be core-eval proposal packages, either before or after the chain software upgrade proposal. +In the release branches, the end-to-end `a3p-integration` test usually only has +a single proposal package named `a:upgrade-NN`, which performs a chain software +upgrade proposal to the corresponding upgrade plan. In the `master` branch, the +next release's changes are staged in `a:upgrade-next`. There may also be +core-eval proposal packages, either before or after the chain software upgrade +proposal. The details of a proposal package are configured through the `agoricProposal` field of its `package.json`. @@ -51,16 +59,36 @@ More details about synthetic-chain proposals can be found in the [`agoric-3-prop For a chain software upgrade proposal, the `type` is `"Software Upgrade Proposal"`, and the relevant fields are `sdkImageTag`, `planName` and `upgradeInfo`. - `sdkImageTag` is the docker image tag to use that contains the upgraded chain software. It has a value of `unreleased`, which is the tag for the image that is built from the enclosing `agoric-sdk` repository. + - `planName` is the "upgrade name" included in the proposal which must match the value in the upgraded chain software. In the `master` branch its value is `UNRELEASED_UPGRADE`. In the release branches, it's `agoric-upgrade-NN`. -- `upgradeInfo` contains other details passed to the governance proposal. In particular, the info can have a `coreProposal` field which instruct the chain software to run other core proposals besides the one already configured in the chain software's upgrade handler (see `CoreProposalSteps` in `/golang/cosmos/app/app.go`). This field is likely not relevant for release branches. -For an example, see `a:upgrade-next` in master. +- `upgradeInfo` contains other details passed to the governance proposal. In + particular, it can have a `coreProposals` field which instructs the chain + software to run other core proposals in addition to the one configured in the + chain software's upgrade handler (see `CoreProposalSteps` in + `/golang/cosmos/app/app.go`). + - See **Generating core-eval submissions** below for details. + +For an (evolving) example, see `a:upgrade-next` in master. ### Core-eval proposal -The `type` of a core-eval proposal is `"/agoric.swingset.CoreEvalProposal"`, and content is submitted from a `submission` subfolder. +The `type` of a core-eval proposal is `"/agoric.swingset.CoreEvalProposal"`. By +default, the submission in the subdir `submission` is evaluated. The proposal +package can override this by providing an `eval.sh` that is executed instead. +See [run_eval.sh](https://github.com/Agoric/agoric-3-proposals/blob/main/packages/synthetic-chain/public/upgrade-test-scripts/run_eval.sh) + +If the proposal is planned to be executed after the chain software upgrade, and +the source of the proposal is in `agoric-sdk`, don't commit the built proposal +because CI willl test that instead of the most recent code. + -If the proposal is planned to be executed after the chain software upgrade, and the source of the proposal is in `agoric-sdk`, it's recommended to not check-in the `submission` content in source control and instead generate it automatically when testing. Since proposals cannot access SDK code, a script can be used to generate the `submission` content. Until there is [native support for build scripts in the `synthetic-chain` tool](https://github.com/Agoric/agoric-3-proposals/issues/87), `a3p-integration`'s `build:submissions` step invokes `/script/generate-a3p-submission.sh` in `agoric-sdk` before starting the upgrade test. +Instead, generate it automatically in each test run. Since proposals cannot +access SDK code, a script can be used to generate the `submission` content. +Until there is [native support for build scripts in the `synthetic-chain` +tool](https://github.com/Agoric/agoric-3-proposals/issues/87), +`a3p-integration`'s `build:submissions` step invokes +`generate-a3p-submissions.sh` in `agoric-sdk` before starting the upgrade test. For core eval proposals executing before the chain software upgrade, the `submission` should be checked in, since bundles built from newer software may not be compatible with older chains. @@ -97,13 +125,44 @@ make -C ../packages/deployment docker-build-sdk ## Generating core-eval submissions -Some core-eval proposals `submission` content are generated from the `agoric-sdk` -code, and must be rebuilt every time there is a change. The -`scripts/generate-a3p-submission.sh` script contains commands to generate the -core-eval content and move it to the expected proposal package's submission -directory. It is executed as part of `a3p-integration`'s `build:submissions` step. -Each proposal that requires such a build step should add an `sdk-generate` property -in its `agoricProposal` config. +In a3p-integration, many core-eval proposals' `submission` content has to be +generated from the local `agoric-sdk`, and must be rebuilt every time there is a +change. The `scripts/generate-a3p-submissions.sh` script contains commands to +generate the core-eval content and move it to the expected proposal package's +submission directory. The generation is executed as part of `a3p-integration`'s +`build:submissions` step. Each proposal that requires such a build step should +add an entry to the `sdk-generate` array in the `agoricProposal` section of +`package.json`. + +Submissions that don't need to pass in options or generate references to source +bundles can be written directly in a `foo-submission` subdirectory of the +proposal. These would include a .js script, accompanied by a similarly-named +-permit.json file (which can contain just `true` or a complete permission +manifest.) The submission should return the script, which can take +BootstrapPowers as a parameter. + +If the submission does require bundle references or other options to be +provided, it should be written as two parts: a core eval (in +`.../vats/proposals`) and a builder for it (in `.../builders/scripts/vats`). + +The `generate-a3p-submissions.sh` script reads instructions from +`agoricProposal.sdk-generate` in `package.json`. That field contains a list of +strings, each of which describes a single submission. If there is only one +submission, it can use the default directory name `submission` by specifying +only the name of the script file in `builders/scripts/vars`: +```json +"sdk-generate": ["test-localchain"], +``` +If there are multiple submissions, each entry has to specify the script name and +a distinct directory name. +```json +"sdk-generate": [ + "probe-zcf-bundle probe-submission", + "updatePriceFeeds priceFeed-submission", + "add-auction newAuction-submission" +], +``` + ## Building synthetic-chain images diff --git a/a3p-integration/package.json b/a3p-integration/package.json index 025fccf678e0..3882c279d1ff 100644 --- a/a3p-integration/package.json +++ b/a3p-integration/package.json @@ -1,7 +1,7 @@ { "private": true, "agoricSyntheticChain": { - "fromTag": "use-upgrade-13" + "fromTag": "latest" }, "scripts": { "build": "yarn run build:sdk && yarn run build:submissions && yarn run build:synthetic-chain", @@ -12,8 +12,8 @@ "doctor": "yarn synthetic-chain doctor" }, "dependencies": { - "@agoric/synthetic-chain": "^0.0.7" + "@agoric/synthetic-chain": "^0.0.10" }, - "packageManager": "yarn@4.1.0", + "packageManager": "yarn@4.1.1", "license": "Apache-2.0" } diff --git a/a3p-integration/proposals/a:upgrade-next/README.md b/a3p-integration/proposals/a:upgrade-next/README.md index 88dcff4be62f..2393dff7fcdc 100644 --- a/a3p-integration/proposals/a:upgrade-next/README.md +++ b/a3p-integration/proposals/a:upgrade-next/README.md @@ -7,3 +7,5 @@ in `agoric-sdk/golang/cosmos/app/app.go`. This test also includes a core proposal in its `upgradeInfo`. This is executed after the core proposals defined in the software's upgrade handler. See `agoricProposal` in `package.json`. + +The "binaries" property of `upgradeInfo` is now required since Cosmos SDK 0.46, however it cannot be computed for an unreleased upgrade. To disable the check, `releaseNotes` is set to `false`. diff --git a/a3p-integration/proposals/a:upgrade-next/ante-fees.test.js b/a3p-integration/proposals/a:upgrade-next/ante-fees.test.js deleted file mode 100644 index b32a938a664c..000000000000 --- a/a3p-integration/proposals/a:upgrade-next/ante-fees.test.js +++ /dev/null @@ -1,74 +0,0 @@ -import test from 'ava'; - -import { CHAINID, GOV1ADDR, GOV2ADDR, agd } from '@agoric/synthetic-chain'; - -test(`ante handler sends fee only to vbank/reserve`, async t => { - const [feeCollector, vbankReserve] = await Promise.all( - // Look up addresses for fee collector and reserve accounts. - ['fee_collector', 'vbank/reserve'].map(async name => { - const { - account: { - '@type': moduleAcct, - base_account: { address }, - }, - } = await agd.query('auth', 'module-account', name); - - t.is( - moduleAcct, - '/cosmos.auth.v1beta1.ModuleAccount', - `${name} is a module account`, - ); - return address; - }), - ); - - const getBalances = addresses => - Promise.all( - addresses.map(async address => { - const { balances } = await agd.query('bank', 'balances', address); - return balances; - }), - ); - - const [feeCollectorStartBalances, vbankReserveStartBalances] = - await getBalances([feeCollector, vbankReserve]); - - // Send a transaction with a known fee. - const feeAmount = 999n; - const feeDenom = 'uist'; - const result = await agd.tx( - `bank send ${GOV1ADDR} ${GOV2ADDR} 1234ubld --fees=${feeAmount}${feeDenom} \ - --from=${GOV1ADDR} --chain-id=${CHAINID} --keyring-backend=test --yes`, - ); - t.like(result, { code: 0 }); - - const [feeCollectorEndBalances, vbankReserveEndBalances] = await getBalances([ - feeCollector, - vbankReserve, - ]); - t.deepEqual(feeCollectorEndBalances, feeCollectorStartBalances); - - // The reserve balances should have increased by exactly the fee (possibly - // from zero, in which case start balances wouldn't include its denomination). - const feeDenomIndex = vbankReserveStartBalances.findIndex( - ({ denom }) => denom === feeDenom, - ); - const preFeeAmount = - feeDenomIndex < 0 - ? 0n - : BigInt(vbankReserveStartBalances[feeDenomIndex].amount); - const beforeCount = - feeDenomIndex < 0 ? vbankReserveStartBalances.length : feeDenomIndex; - - const vbankReserveExpectedBalances = [ - ...vbankReserveStartBalances.slice(0, beforeCount), - { amount: String(preFeeAmount + feeAmount), denom: feeDenom }, - ...vbankReserveStartBalances.slice(beforeCount + 1), - ]; - - t.deepEqual( - vbankReserveEndBalances, - vbankReserveExpectedBalances, - 'vbank/reserve should receive the fee', - ); -}); diff --git a/a3p-integration/proposals/a:upgrade-next/exit-reclaim.test.js b/a3p-integration/proposals/a:upgrade-next/exit-reclaim.test.js new file mode 100644 index 000000000000..c2bf31a52419 --- /dev/null +++ b/a3p-integration/proposals/a:upgrade-next/exit-reclaim.test.js @@ -0,0 +1,36 @@ +import test from 'ava'; +import { $ } from 'execa'; +import { execFileSync } from 'node:child_process'; +import { makeAgd, waitForBlock } from './synthetic-chain-excerpt.js'; + +const offerId = 'bad-invitation-15'; // cf. prepare.sh +const from = 'gov1'; + +test('exitOffer tool reclaims stuck payment', async t => { + const showAndExec = (file, args, opts) => { + console.log('$', file, ...args); + return execFileSync(file, args, opts); + }; + const agd = makeAgd({ execFileSync: showAndExec }).withOpts({ + keyringBackend: 'test', + }); + + const addr = await agd.lookup(from); + t.log(from, 'addr', addr); + + const getBalance = async target => { + const { balances } = await agd.query(['bank', 'balances', addr]); + const { amount } = balances.find(({ denom }) => denom === target); + return Number(amount); + }; + + const before = await getBalance('uist'); + t.log('uist balance before:', before); + + await $`node ./exitOffer.js --id ${offerId} --from ${from}`; + + await waitForBlock(2); + const after = await getBalance('uist'); + t.log('uist balance after:', after); + t.true(after > before); +}); diff --git a/a3p-integration/proposals/a:upgrade-next/exitOffer.js b/a3p-integration/proposals/a:upgrade-next/exitOffer.js new file mode 100644 index 000000000000..fb6d2242b855 --- /dev/null +++ b/a3p-integration/proposals/a:upgrade-next/exitOffer.js @@ -0,0 +1,97 @@ +// Note: limit imports to node modules for portability +import { parseArgs, promisify } from 'node:util'; +import { execFile } from 'node:child_process'; +import { writeFile, mkdtemp, rm } from 'node:fs/promises'; +import { join } from 'node:path'; + +const options = /** @type {const} */ ({ + id: { type: 'string' }, + from: { type: 'string' }, + bin: { type: 'string', default: '/usr/src/agoric-sdk/node_modules/.bin' }, +}); + +const Usage = ` +Try to exit an offer, reclaiming any associated payments. + + node exitOffer.js --id ID --from FROM [--bin PATH] + +Options: + --id + --from
+ + --bin default: ${options.bin.default} +`; + +const badUsage = () => { + const reason = new Error(Usage); + reason.name = 'USAGE'; + throw reason; +}; + +const { stringify: q } = JSON; +// limited to JSON data: no remotables/promises; no undefined. +const toCapData = data => ({ body: `#${q(data)}`, slots: [] }); + +const { entries } = Object; +/** + * @param {Record} obj - e.g. { color: 'blue' } + * @returns {string[]} - e.g. ['--color', 'blue'] + */ +const flags = obj => + entries(obj) + .map(([k, v]) => [`--${k}`, v]) + .flat(); + +const execP = promisify(execFile); + +const showAndRun = (file, args) => { + console.log('$', file, ...args); + return execP(file, args); +}; + +const withTempFile = async (tail, fn) => { + const tmpDir = await mkdtemp('offers-'); + const tmpFile = join(tmpDir, tail); + try { + const result = await fn(tmpFile); + return result; + } finally { + await rm(tmpDir, { recursive: true, force: true }).catch(err => + console.error(err), + ); + } +}; + +const doAction = async (action, from) => { + await withTempFile('offer.json', async tmpOffer => { + await writeFile(tmpOffer, q(toCapData(action))); + + const out = await showAndRun('agoric', [ + 'wallet', + ...flags({ 'keyring-backend': 'test' }), + 'send', + ...flags({ offer: tmpOffer, from }), + ]); + return out.stdout; + }); +}; + +const main = async (argv, env) => { + const { values } = parseArgs({ args: argv.slice(2), options }); + const { id: offerId, from, bin } = values; + (offerId && from) || badUsage(); + + env.PATH = `${bin}:${env.PATH}`; + const action = { method: 'tryExitOffer', offerId }; + const out = await doAction(action, from); + console.log(out); +}; + +main(process.argv, process.env).catch(e => { + if (e.name === 'USAGE' || e.code === 'ERR_PARSE_ARGS_UNKNOWN_OPTION') { + console.error(e.message); + } else { + console.error(e); + } + process.exit(1); +}); diff --git a/a3p-integration/proposals/a:upgrade-next/initial.test.js b/a3p-integration/proposals/a:upgrade-next/initial.test.js new file mode 100644 index 000000000000..15b12c33697e --- /dev/null +++ b/a3p-integration/proposals/a:upgrade-next/initial.test.js @@ -0,0 +1,19 @@ +import test from 'ava'; + +import { getVatDetails } from '@agoric/synthetic-chain'; + +const vats = { + network: { incarnation: 0 }, + ibc: { incarnation: 0 }, + localchain: { incarnation: 0 }, + walletFactory: { incarnation: 3 }, + zoe: { incarnation: 1 }, +}; + +test(`vat details`, async t => { + await null; + for (const [vatName, expected] of Object.entries(vats)) { + const actual = await getVatDetails(vatName); + t.like(actual, expected, `${vatName} details mismatch`); + } +}); diff --git a/a3p-integration/proposals/a:upgrade-next/invite-submission/README.md b/a3p-integration/proposals/a:upgrade-next/invite-submission/README.md deleted file mode 100644 index 345d5cd67f20..000000000000 --- a/a3p-integration/proposals/a:upgrade-next/invite-submission/README.md +++ /dev/null @@ -1,8 +0,0 @@ -These files enable a test of the walletFactory changes, by -verifying that upgraded wallets that aren't backed by vbanks can still add -assets, in this case an invitation. - -sendInvite is a secondary submission, which is transmitted in ../wallet-repair.test.js. -Some template values in the `.tjs` file are replaced before submitting the -core-eval. The test then verifies that the invitation details were written to -the wallet in vstorage. diff --git a/a3p-integration/proposals/a:upgrade-next/invite-submission/sendInvite-permit.json b/a3p-integration/proposals/a:upgrade-next/invite-submission/sendInvite-permit.json deleted file mode 100644 index 27ba77ddaf61..000000000000 --- a/a3p-integration/proposals/a:upgrade-next/invite-submission/sendInvite-permit.json +++ /dev/null @@ -1 +0,0 @@ -true diff --git a/a3p-integration/proposals/a:upgrade-next/invite-submission/sendInvite.tjs b/a3p-integration/proposals/a:upgrade-next/invite-submission/sendInvite.tjs deleted file mode 100644 index e0ac35562552..000000000000 --- a/a3p-integration/proposals/a:upgrade-next/invite-submission/sendInvite.tjs +++ /dev/null @@ -1,39 +0,0 @@ -#! false node --ignore-this-line -/* global E */ - -/// -/// - -// to be replaced before execution -const addr = '{{ADDRESS}}'; - -/** - * verify that a pre-existing wallet has an invitation purse that is still monitored - * - * @param {BootstrapPowers} powers - */ -const sendInvitation = async powers => { - console.log('sendInvitation start'); - // namesByAddress is broken #8113 - const { - consume: { namesByAddressAdmin, zoe }, - instance: { - consume: { reserve }, - }, - } = powers; - const pf = E(zoe).getPublicFacet(reserve); - const anInvitation = await E(pf).makeAddCollateralInvitation(); - - await E(namesByAddressAdmin).reserve(addr); - // don't trigger the namesByAddressAdmin.readonly() bug - const addressAdmin = E(namesByAddressAdmin).lookupAdmin(addr); - - await E(addressAdmin).reserve('depositFacet'); - const addressHub = E(addressAdmin).readonly(); - const addressDepositFacet = E(addressHub).lookup('depositFacet'); - - await E(addressDepositFacet).receive(anInvitation); - console.log('ADDED an invitation to a purse!'); -}; - -sendInvitation; diff --git a/a3p-integration/proposals/a:upgrade-next/package.json b/a3p-integration/proposals/a:upgrade-next/package.json index 5a87cb35e113..ba29668f9bc6 100644 --- a/a3p-integration/proposals/a:upgrade-next/package.json +++ b/a3p-integration/proposals/a:upgrade-next/package.json @@ -1,6 +1,6 @@ { "agoricProposal": { - "releaseNotes": "TBD", + "releaseNotes": false, "sdkImageTag": "unreleased", "planName": "UNRELEASED_UPGRADE", "upgradeInfo": { @@ -14,7 +14,7 @@ "type": "module", "license": "Apache-2.0", "dependencies": { - "@agoric/synthetic-chain": "^0.0.7", + "@agoric/synthetic-chain": "^0.0.10", "ava": "^5.3.1" }, "ava": { @@ -27,5 +27,5 @@ "scripts": { "agops": "yarn --cwd /usr/src/agoric-sdk/ --silent agops" }, - "packageManager": "yarn@4.1.0" + "packageManager": "yarn@4.1.1" } diff --git a/a3p-integration/proposals/a:upgrade-next/post.test.js b/a3p-integration/proposals/a:upgrade-next/post.test.js deleted file mode 100644 index 3b59ddd5ae78..000000000000 --- a/a3p-integration/proposals/a:upgrade-next/post.test.js +++ /dev/null @@ -1,30 +0,0 @@ -import test from 'ava'; - -import { getIncarnation } from '@agoric/synthetic-chain'; - -test(`Ensure Network Vat was installed`, async t => { - const incarnation = await getIncarnation('network'); - t.is(incarnation, 0); -}); - -test(`Ensure IBC Vat was installed`, async t => { - const incarnation = await getIncarnation('ibc'); - t.is(incarnation, 0); -}); - -test(`Ensure Local Chain Vat was installed`, async t => { - const incarnation = await getIncarnation('localchain'); - t.is(incarnation, 0); -}); - -test(`Smart Wallet vat was upgraded`, async t => { - const incarnation = await getIncarnation('walletFactory'); - - t.is(incarnation, 2); -}); - -test(`Zoe vat was upgraded`, async t => { - const incarnation = await getIncarnation('zoe'); - - t.is(incarnation, 1); -}); diff --git a/a3p-integration/proposals/a:upgrade-next/prepare.sh b/a3p-integration/proposals/a:upgrade-next/prepare.sh index 9c72d81215c1..febb39d835f6 100755 --- a/a3p-integration/proposals/a:upgrade-next/prepare.sh +++ b/a3p-integration/proposals/a:upgrade-next/prepare.sh @@ -1,9 +1,29 @@ #!/bin/bash # Exit when any command fails -set -e +set -uxeo pipefail # Place here any actions that should happen before the upgrade is proposed. The # actions are executed in the previous chain software, and the effects are # persisted so they can be used in the steps after the upgrade is complete, # such as in the "use" or "test" steps, or further proposal layers. + +printISTBalance() { + addr=$(agd keys show -a "$1" --keyring-backend=test) + agd query bank balances "$addr" -o json \ + | jq -c '.balances[] | select(.denom=="uist")' + +} + +echo TEST: Offer with bad invitation +printISTBalance gov1 + +badInvitationOffer=$(mktemp) +cat > "$badInvitationOffer" << 'EOF' +{"body":"#{\"method\":\"executeOffer\",\"offer\":{\"id\":\"bad-invitation-15\",\"invitationSpec\":{\"callPipe\":[[\"badMethodName\"]],\"instancePath\":[\"reserve\"],\"source\":\"agoricContract\"},\"proposal\":{\"give\":{\"Collateral\":{\"brand\":\"$0.Alleged: IST brand\",\"value\":\"+15000\"}}}}}","slots":["board0257"]} +EOF + +PATH=/usr/src/agoric-sdk/node_modules/.bin:$PATH +agops perf satisfaction --keyring-backend=test send --executeOffer "$badInvitationOffer" --from gov1 || true + +printISTBalance gov1 diff --git a/a3p-integration/proposals/a:upgrade-next/probeZcfBundleCap.test.js b/a3p-integration/proposals/a:upgrade-next/probeZcfBundleCap.test.js index 88ecf5d09292..ef27a73f6498 100644 --- a/a3p-integration/proposals/a:upgrade-next/probeZcfBundleCap.test.js +++ b/a3p-integration/proposals/a:upgrade-next/probeZcfBundleCap.test.js @@ -24,13 +24,4 @@ test('upgrade Zoe to verify ZcfBundleCap endures', async t => { detailsBefore.incarnation + 2, 'wf incarnation must increase by 2', ); - - // The test restarts the WalletFactory, so it'll use the recently assigned - // ZCF bundle. It then restarts Zoe, so it'll revert to whichever ZCF bundle - // made it to persistent store. We then restart the Wallet Factory and see if - // it's gone back to the ZCF that Zoe initially knew about. If we could get the - // ZCF bundleID here from the probe, we'd explicitly check for that. Instead, - // we have to be content that it did indeed use the newly assigned bundle in - // manual tests. - t.not(detailsAfter.bundleID, detailsBefore.bundleID); }); diff --git a/a3p-integration/proposals/a:upgrade-next/provisioning.test.js b/a3p-integration/proposals/a:upgrade-next/provisioning.test.js index a827faa567f4..e31ffbb89a86 100644 --- a/a3p-integration/proposals/a:upgrade-next/provisioning.test.js +++ b/a3p-integration/proposals/a:upgrade-next/provisioning.test.js @@ -25,13 +25,13 @@ const replaceTemplateValuesInFile = async (fileName, replacements) => { await writeFile(`${fileName}.js`, script); }; -test(`provisioning vat was upgraded`, async t => { +test.serial(`provisioning vat was upgraded`, async t => { const incarnation = await getIncarnation('provisioning'); t.is(incarnation, 1); }); -test(`send invitation via namesByAddress`, async t => { +test.serial(`send invitation via namesByAddress`, async t => { const addr = await getUser('gov1'); await replaceTemplateValuesInFile(`${SUBMISSION_DIR}/send-script`, { diff --git a/a3p-integration/proposals/a:upgrade-next/synthetic-chain-excerpt.js b/a3p-integration/proposals/a:upgrade-next/synthetic-chain-excerpt.js new file mode 100644 index 000000000000..ff0211591ee7 --- /dev/null +++ b/a3p-integration/proposals/a:upgrade-next/synthetic-chain-excerpt.js @@ -0,0 +1,166 @@ +/** + * @file work-around: importing @agoric/synthetic-chain hangs XXX + */ +// @ts-check +import { $ } from 'execa'; + +const waitForBootstrap = async () => { + const endpoint = 'localhost'; + while (true) { + const { stdout: json } = await $({ + reject: false, + })`curl -s --fail -m 15 ${`${endpoint}:26657/status`}`; + + if (json.length === 0) { + continue; + } + + const data = JSON.parse(json); + + if (data.jsonrpc !== '2.0') { + continue; + } + + const lastHeight = data.result.sync_info.latest_block_height; + + if (lastHeight !== '1') { + return lastHeight; + } + + await new Promise(r => setTimeout(r, 2000)); + } +}; + +export const waitForBlock = async (times = 1) => { + console.log(times); + let time = 0; + while (time < times) { + const block1 = await waitForBootstrap(); + while (true) { + const block2 = await waitForBootstrap(); + + if (block1 !== block2) { + console.log('block produced'); + break; + } + + await new Promise(r => setTimeout(r, 1000)); + } + time += 1; + } +}; + +const { freeze } = Object; + +const agdBinary = 'agd'; + +/** + * @param {{execFileSync: typeof import('child_process').execFileSync }} io + * @returns + */ +export const makeAgd = ({ execFileSync }) => { + /** + * @param {{ + * home?: string; + * keyringBackend?: string; + * rpcAddrs?: string[]; + * }} opts + */ + const make = ({ home, keyringBackend, rpcAddrs } = {}) => { + const keyringArgs = [ + ...(home ? ['--home', home] : []), + ...(keyringBackend ? [`--keyring-backend`, keyringBackend] : []), + ]; + if (rpcAddrs) { + assert.equal( + rpcAddrs.length, + 1, + 'XXX rpcAddrs must contain only one entry', + ); + } + const nodeArgs = [...(rpcAddrs ? [`--node`, rpcAddrs[0]] : [])]; + + const exec = (args, opts) => execFileSync(agdBinary, args, opts).toString(); + + const outJson = ['--output', 'json']; + + const ro = freeze({ + status: async () => JSON.parse(exec([...nodeArgs, 'status'])), + query: async qArgs => { + const out = exec(['query', ...qArgs, ...nodeArgs, ...outJson], { + encoding: 'utf-8', + stdio: ['ignore', 'pipe', 'ignore'], + }); + + try { + return JSON.parse(out); + } catch (e) { + console.error(e); + console.info('output:', out); + } + }, + }); + const nameHub = freeze({ + /** + * NOTE: synchronous I/O + */ + lookup: (...path) => { + if (!Array.isArray(path)) { + // TODO: use COND || Fail`` + throw TypeError(); + } + if (path.length !== 1) { + throw Error(`path length limited to 1: ${path.length}`); + } + const [name] = path; + const txt = exec(['keys', 'show', `--address`, name, ...keyringArgs]); + return txt.trim(); + }, + }); + const rw = freeze({ + /** + * @param {string[]} txArgs + * @param {{ chainId: string, from: string, yes?: boolean }} opts + */ + tx: async (txArgs, { chainId, from, yes }) => { + const yesArg = yes ? ['--yes'] : []; + const args = [ + ...nodeArgs, + ...[`--chain-id`, chainId], + ...keyringArgs, + ...[`--from`, from], + 'tx', + ...['--broadcast-mode', 'block'], + ...['--gas', 'auto'], + ...['--gas-adjustment', '1.3'], + ...txArgs, + ...yesArg, + ...outJson, + ]; + const out = exec(args); + try { + return JSON.parse(out); + } catch (e) { + console.error(e); + console.info('output:', out); + } + }, + ...ro, + ...nameHub, + readOnly: () => ro, + nameHub: () => nameHub, + keys: { + add: (name, mnemonic) => { + return execFileSync( + agdBinary, + [...keyringArgs, 'keys', 'add', name, '--recover'], + { input: mnemonic }, + ).toString(); + }, + }, + withOpts: opts => make({ home, keyringBackend, rpcAddrs, ...opts }), + }); + return rw; + }; + return make(); +}; diff --git a/a3p-integration/proposals/a:upgrade-next/test.sh b/a3p-integration/proposals/a:upgrade-next/test.sh index a2e9eec7c6a7..6c8533d07f04 100755 --- a/a3p-integration/proposals/a:upgrade-next/test.sh +++ b/a3p-integration/proposals/a:upgrade-next/test.sh @@ -3,6 +3,9 @@ # Place here any test that should be executed using the executed proposal. # The effects of this step are not persisted in further proposal layers. -yarn ava post.test.js -GLOBIGNORE=post.test.js -yarn ava *.test.js +# test the state right after upgrade +yarn ava initial.test.js + +# test more, in ways that changes system state +GLOBIGNORE=initial.test.js +yarn ava ./*.test.js diff --git a/a3p-integration/proposals/a:upgrade-next/wallet-repairs.test.js b/a3p-integration/proposals/a:upgrade-next/wallet-repairs.test.js deleted file mode 100755 index 6d50acb1d2f1..000000000000 --- a/a3p-integration/proposals/a:upgrade-next/wallet-repairs.test.js +++ /dev/null @@ -1,46 +0,0 @@ -import { readFile, writeFile } from 'node:fs/promises'; - -import test from 'ava'; - -import { agd, getUser, evalBundles } from '@agoric/synthetic-chain'; - -const SUBMISSION_DIR = 'invite-submission'; - -/** - * @param {string} fileName base file name without .tjs extension - * @param {Record} replacements - */ -const replaceTemplateValuesInFile = async (fileName, replacements) => { - let script = await readFile(`${fileName}.tjs`, 'utf-8'); - for (const [template, value] of Object.entries(replacements)) { - script = script.replaceAll(`{{${template}}}`, value); - } - await writeFile(`${fileName}.js`, script); -}; - -test('smartWallet repairs', async t => { - const gov1Address = await getUser('gov1'); - - await replaceTemplateValuesInFile(`${SUBMISSION_DIR}/sendInvite`, { - ADDRESS: gov1Address, - }); - - await evalBundles(SUBMISSION_DIR); - - // agd query vstorage data published.wallet.$GOV1ADDR.current -o json \ - // |& jq '.value | fromjson | .values[0] | fromjson | .body[1:] \ - // | fromjson | .purses ' - const walletCurrent = await agd.query( - 'vstorage', - 'data', - `published.wallet.${gov1Address}.current`, - ); - - const body = JSON.parse(JSON.parse(walletCurrent.value).values[0]); - const bodyTruncated = JSON.parse(body.body.substring(1)); - const invitePurseBalance = bodyTruncated.purses[0].balance; - t.truthy(invitePurseBalance.value[0], 'expecting a non-empty purse'); - const description = invitePurseBalance.value[0].description; - - t.is(description, 'Add Collateral', 'invitation purse should not be empty'); -}); diff --git a/a3p-integration/proposals/a:upgrade-next/yarn.lock b/a3p-integration/proposals/a:upgrade-next/yarn.lock index f56cdd73ed91..f99f929ef775 100644 --- a/a3p-integration/proposals/a:upgrade-next/yarn.lock +++ b/a3p-integration/proposals/a:upgrade-next/yarn.lock @@ -5,9 +5,9 @@ __metadata: version: 8 cacheKey: 10c0 -"@agoric/synthetic-chain@npm:^0.0.7": - version: 0.0.7 - resolution: "@agoric/synthetic-chain@npm:0.0.7" +"@agoric/synthetic-chain@npm:^0.0.10": + version: 0.0.10 + resolution: "@agoric/synthetic-chain@npm:0.0.10" dependencies: "@endo/zip": "npm:^1.0.1" better-sqlite3: "npm:^9.4.0" @@ -15,7 +15,7 @@ __metadata: execa: "npm:^8.0.1" bin: synthetic-chain: dist/cli/cli.js - checksum: 10c0/ae53a9c4837eecc7db5020c8e0ac46f02a5a8ae6679adfe5e32365d6895f8ca8eb1da2dad3b3dc7a545ec801275b1a53d68bb0737db462ec9ea82bbcffe37374 + checksum: 10c0/c75308830cbe879ba865e285a20529ac82da1434c778046b27c790e426a8139369c3ef904939905ad73109202a336925733448109a85bc19aa2d350ebdb2a520 languageName: node linkType: hard @@ -1820,7 +1820,7 @@ __metadata: version: 0.0.0-use.local resolution: "root-workspace-0b6124@workspace:." dependencies: - "@agoric/synthetic-chain": "npm:^0.0.7" + "@agoric/synthetic-chain": "npm:^0.0.10" ava: "npm:^5.3.1" languageName: unknown linkType: soft diff --git a/a3p-integration/proposals/b:localchain/package.json b/a3p-integration/proposals/b:localchain/package.json index df60d88da4e5..562e03412bad 100644 --- a/a3p-integration/proposals/b:localchain/package.json +++ b/a3p-integration/proposals/b:localchain/package.json @@ -9,7 +9,7 @@ "type": "module", "license": "Apache-2.0", "dependencies": { - "@agoric/synthetic-chain": "^0.0.7", + "@agoric/synthetic-chain": "^0.0.10", "ava": "^5.3.1" }, "ava": { @@ -19,5 +19,5 @@ "!submission" ] }, - "packageManager": "yarn@4.1.0" + "packageManager": "yarn@4.1.1" } diff --git a/a3p-integration/proposals/b:localchain/yarn.lock b/a3p-integration/proposals/b:localchain/yarn.lock index ec11b30e305f..2bcc71547238 100644 --- a/a3p-integration/proposals/b:localchain/yarn.lock +++ b/a3p-integration/proposals/b:localchain/yarn.lock @@ -5,9 +5,9 @@ __metadata: version: 8 cacheKey: 10c0 -"@agoric/synthetic-chain@npm:^0.0.7": - version: 0.0.7 - resolution: "@agoric/synthetic-chain@npm:0.0.7" +"@agoric/synthetic-chain@npm:^0.0.10": + version: 0.0.10 + resolution: "@agoric/synthetic-chain@npm:0.0.10" dependencies: "@endo/zip": "npm:^1.0.1" better-sqlite3: "npm:^9.4.0" @@ -15,7 +15,7 @@ __metadata: execa: "npm:^8.0.1" bin: synthetic-chain: dist/cli/cli.js - checksum: 10c0/ae53a9c4837eecc7db5020c8e0ac46f02a5a8ae6679adfe5e32365d6895f8ca8eb1da2dad3b3dc7a545ec801275b1a53d68bb0737db462ec9ea82bbcffe37374 + checksum: 10c0/c75308830cbe879ba865e285a20529ac82da1434c778046b27c790e426a8139369c3ef904939905ad73109202a336925733448109a85bc19aa2d350ebdb2a520 languageName: node linkType: hard @@ -1820,7 +1820,7 @@ __metadata: version: 0.0.0-use.local resolution: "root-workspace-0b6124@workspace:." dependencies: - "@agoric/synthetic-chain": "npm:^0.0.7" + "@agoric/synthetic-chain": "npm:^0.0.10" ava: "npm:^5.3.1" languageName: unknown linkType: soft diff --git a/a3p-integration/proposals/c:stake-bld/package.json b/a3p-integration/proposals/c:stake-bld/package.json index 6986733391f1..f39ade82c280 100644 --- a/a3p-integration/proposals/c:stake-bld/package.json +++ b/a3p-integration/proposals/c:stake-bld/package.json @@ -10,7 +10,7 @@ "license": "Apache-2.0", "dependencies": { "@agoric/internal": "0.3.3-dev-5676146.0", - "@agoric/synthetic-chain": "^0.0.7", + "@agoric/synthetic-chain": "^0.0.10", "@cosmjs/stargate": "^0.32.3", "@cosmjs/tendermint-rpc": "^0.32.3", "@endo/errors": "^1.1.0", @@ -24,5 +24,5 @@ "ava": { "concurrency": 1 }, - "packageManager": "yarn@4.1.0" + "packageManager": "yarn@4.1.1" } diff --git a/a3p-integration/proposals/c:stake-bld/yarn.lock b/a3p-integration/proposals/c:stake-bld/yarn.lock index e71afbd28dea..88543c08fbac 100644 --- a/a3p-integration/proposals/c:stake-bld/yarn.lock +++ b/a3p-integration/proposals/c:stake-bld/yarn.lock @@ -365,9 +365,9 @@ __metadata: languageName: node linkType: hard -"@agoric/synthetic-chain@npm:^0.0.7": - version: 0.0.7 - resolution: "@agoric/synthetic-chain@npm:0.0.7" +"@agoric/synthetic-chain@npm:^0.0.10": + version: 0.0.10 + resolution: "@agoric/synthetic-chain@npm:0.0.10" dependencies: "@endo/zip": "npm:^1.0.1" better-sqlite3: "npm:^9.4.0" @@ -375,7 +375,7 @@ __metadata: execa: "npm:^8.0.1" bin: synthetic-chain: dist/cli/cli.js - checksum: 10c0/ae53a9c4837eecc7db5020c8e0ac46f02a5a8ae6679adfe5e32365d6895f8ca8eb1da2dad3b3dc7a545ec801275b1a53d68bb0737db462ec9ea82bbcffe37374 + checksum: 10c0/c75308830cbe879ba865e285a20529ac82da1434c778046b27c790e426a8139369c3ef904939905ad73109202a336925733448109a85bc19aa2d350ebdb2a520 languageName: node linkType: hard @@ -4567,7 +4567,7 @@ __metadata: resolution: "root-workspace-0b6124@workspace:." dependencies: "@agoric/internal": "npm:0.3.3-dev-5676146.0" - "@agoric/synthetic-chain": "npm:^0.0.7" + "@agoric/synthetic-chain": "npm:^0.0.10" "@cosmjs/stargate": "npm:^0.32.3" "@cosmjs/tendermint-rpc": "npm:^0.32.3" "@endo/errors": "npm:^1.1.0" diff --git a/a3p-integration/proposals/z:acceptance/.gitignore b/a3p-integration/proposals/z:acceptance/.gitignore new file mode 100644 index 000000000000..2e83a4c6d68f --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/.gitignore @@ -0,0 +1 @@ +!*submission/ diff --git a/a3p-integration/proposals/z:acceptance/.yarnrc.yml b/a3p-integration/proposals/z:acceptance/.yarnrc.yml new file mode 100644 index 000000000000..3186f3f0795a --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/.yarnrc.yml @@ -0,0 +1 @@ +nodeLinker: node-modules diff --git a/a3p-integration/proposals/z:acceptance/README.md b/a3p-integration/proposals/z:acceptance/README.md new file mode 100644 index 000000000000..bd4999a3ac6c --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/README.md @@ -0,0 +1,6 @@ +# Inert proposal to test acceptance of the history of upgrades + +Its `type` is `/cosmos.params.v1beta1.ParameterChangeProposal` because that is +the lightest form of actual proposal to execute. It runs the `eval.sh` script, +which does nothing. + diff --git a/a3p-integration/proposals/a:upgrade-next/core-eval-test-submission/README.md b/a3p-integration/proposals/z:acceptance/core-eval-test-submission/README.md similarity index 100% rename from a3p-integration/proposals/a:upgrade-next/core-eval-test-submission/README.md rename to a3p-integration/proposals/z:acceptance/core-eval-test-submission/README.md diff --git a/a3p-integration/proposals/a:upgrade-next/core-eval-test-submission/send-script-permit.json b/a3p-integration/proposals/z:acceptance/core-eval-test-submission/send-script-permit.json similarity index 100% rename from a3p-integration/proposals/a:upgrade-next/core-eval-test-submission/send-script-permit.json rename to a3p-integration/proposals/z:acceptance/core-eval-test-submission/send-script-permit.json diff --git a/a3p-integration/proposals/a:upgrade-next/core-eval-test-submission/send-script.tjs b/a3p-integration/proposals/z:acceptance/core-eval-test-submission/send-script.tjs similarity index 100% rename from a3p-integration/proposals/a:upgrade-next/core-eval-test-submission/send-script.tjs rename to a3p-integration/proposals/z:acceptance/core-eval-test-submission/send-script.tjs diff --git a/a3p-integration/proposals/a:upgrade-next/core-eval.test.js b/a3p-integration/proposals/z:acceptance/core-eval.test.js similarity index 100% rename from a3p-integration/proposals/a:upgrade-next/core-eval.test.js rename to a3p-integration/proposals/z:acceptance/core-eval.test.js diff --git a/a3p-integration/proposals/z:acceptance/eval.sh b/a3p-integration/proposals/z:acceptance/eval.sh new file mode 100644 index 000000000000..612011ea52b5 --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/eval.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +# Do nothing because this is only testing the state resulting from previous proposals. diff --git a/a3p-integration/proposals/z:acceptance/initial.test.js b/a3p-integration/proposals/z:acceptance/initial.test.js new file mode 100644 index 000000000000..96b10c688bf3 --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/initial.test.js @@ -0,0 +1,3 @@ +import test from 'ava'; + +test.todo('initial test'); diff --git a/a3p-integration/proposals/z:acceptance/package.json b/a3p-integration/proposals/z:acceptance/package.json new file mode 100644 index 000000000000..f2f8101209c3 --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/package.json @@ -0,0 +1,22 @@ +{ + "agoricProposal": { + "type": "/cosmos.params.v1beta1.ParameterChangeProposal" + }, + "type": "module", + "license": "Apache-2.0", + "dependencies": { + "@agoric/synthetic-chain": "^0.0.10", + "ava": "^6.1.2" + }, + "ava": { + "concurrency": 1, + "timeout": "2m", + "files": [ + "!submission" + ] + }, + "scripts": { + "agops": "yarn --cwd /usr/src/agoric-sdk/ --silent agops" + }, + "packageManager": "yarn@4.1.1" +} diff --git a/a3p-integration/proposals/z:acceptance/test.sh b/a3p-integration/proposals/z:acceptance/test.sh new file mode 100755 index 000000000000..f165b2bc6138 --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/test.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# Place here any test that should be executed using the executed proposal. +# The effects of this step are not persisted in further proposal layers. + +# test the state right after the previous proposals +yarn ava initial.test.js + +# test more, in ways that change system state +GLOBIGNORE=initial.test.js +yarn ava ./*.test.js diff --git a/a3p-integration/proposals/z:acceptance/tsconfig.json b/a3p-integration/proposals/z:acceptance/tsconfig.json new file mode 100644 index 000000000000..02e3bea3c6d6 --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "noEmit": true, + "target": "esnext", + "module": "esnext", + "allowJs": true, + "checkJs": true, + "strict": false, + "strictNullChecks": true, + "noImplicitThis": true + } +} diff --git a/a3p-integration/proposals/z:acceptance/yarn.lock b/a3p-integration/proposals/z:acceptance/yarn.lock new file mode 100644 index 000000000000..007b7cbc0345 --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/yarn.lock @@ -0,0 +1,2477 @@ +# This file is generated by running "yarn install" inside your project. +# Manual changes might be lost - proceed with caution! + +__metadata: + version: 8 + cacheKey: 10c0 + +"@agoric/synthetic-chain@npm:^0.0.10": + version: 0.0.10 + resolution: "@agoric/synthetic-chain@npm:0.0.10" + dependencies: + "@endo/zip": "npm:^1.0.1" + better-sqlite3: "npm:^9.4.0" + chalk: "npm:^5.3.0" + execa: "npm:^8.0.1" + bin: + synthetic-chain: dist/cli/cli.js + checksum: 10c0/c75308830cbe879ba865e285a20529ac82da1434c778046b27c790e426a8139369c3ef904939905ad73109202a336925733448109a85bc19aa2d350ebdb2a520 + languageName: node + linkType: hard + +"@endo/zip@npm:^1.0.1": + version: 1.0.1 + resolution: "@endo/zip@npm:1.0.1" + checksum: 10c0/1074bdc10287f4c94b3423e130da88f9c6ba09c999483c1164b3eed061350a060d2dbe377cfa3b8d4a86b3f1c3aed5cbf0cdd78ee2bf2cb9b837caa2ebbf712f + languageName: node + linkType: hard + +"@isaacs/cliui@npm:^8.0.2": + version: 8.0.2 + resolution: "@isaacs/cliui@npm:8.0.2" + dependencies: + string-width: "npm:^5.1.2" + string-width-cjs: "npm:string-width@^4.2.0" + strip-ansi: "npm:^7.0.1" + strip-ansi-cjs: "npm:strip-ansi@^6.0.1" + wrap-ansi: "npm:^8.1.0" + wrap-ansi-cjs: "npm:wrap-ansi@^7.0.0" + checksum: 10c0/b1bf42535d49f11dc137f18d5e4e63a28c5569de438a221c369483731e9dac9fb797af554e8bf02b6192d1e5eba6e6402cf93900c3d0ac86391d00d04876789e + languageName: node + linkType: hard + +"@mapbox/node-pre-gyp@npm:^1.0.5": + version: 1.0.11 + resolution: "@mapbox/node-pre-gyp@npm:1.0.11" + dependencies: + detect-libc: "npm:^2.0.0" + https-proxy-agent: "npm:^5.0.0" + make-dir: "npm:^3.1.0" + node-fetch: "npm:^2.6.7" + nopt: "npm:^5.0.0" + npmlog: "npm:^5.0.1" + rimraf: "npm:^3.0.2" + semver: "npm:^7.3.5" + tar: "npm:^6.1.11" + bin: + node-pre-gyp: bin/node-pre-gyp + checksum: 10c0/2b24b93c31beca1c91336fa3b3769fda98e202fb7f9771f0f4062588d36dcc30fcf8118c36aa747fa7f7610d8cf601872bdaaf62ce7822bb08b545d1bbe086cc + languageName: node + linkType: hard + +"@nodelib/fs.scandir@npm:2.1.5": + version: 2.1.5 + resolution: "@nodelib/fs.scandir@npm:2.1.5" + dependencies: + "@nodelib/fs.stat": "npm:2.0.5" + run-parallel: "npm:^1.1.9" + checksum: 10c0/732c3b6d1b1e967440e65f284bd06e5821fedf10a1bea9ed2bb75956ea1f30e08c44d3def9d6a230666574edbaf136f8cfd319c14fd1f87c66e6a44449afb2eb + languageName: node + linkType: hard + +"@nodelib/fs.stat@npm:2.0.5, @nodelib/fs.stat@npm:^2.0.2": + version: 2.0.5 + resolution: "@nodelib/fs.stat@npm:2.0.5" + checksum: 10c0/88dafe5e3e29a388b07264680dc996c17f4bda48d163a9d4f5c1112979f0ce8ec72aa7116122c350b4e7976bc5566dc3ddb579be1ceaacc727872eb4ed93926d + languageName: node + linkType: hard + +"@nodelib/fs.walk@npm:^1.2.3": + version: 1.2.8 + resolution: "@nodelib/fs.walk@npm:1.2.8" + dependencies: + "@nodelib/fs.scandir": "npm:2.1.5" + fastq: "npm:^1.6.0" + checksum: 10c0/db9de047c3bb9b51f9335a7bb46f4fcfb6829fb628318c12115fbaf7d369bfce71c15b103d1fc3b464812d936220ee9bc1c8f762d032c9f6be9acc99249095b1 + languageName: node + linkType: hard + +"@npmcli/agent@npm:^2.0.0": + version: 2.2.0 + resolution: "@npmcli/agent@npm:2.2.0" + dependencies: + agent-base: "npm:^7.1.0" + http-proxy-agent: "npm:^7.0.0" + https-proxy-agent: "npm:^7.0.1" + lru-cache: "npm:^10.0.1" + socks-proxy-agent: "npm:^8.0.1" + checksum: 10c0/7b89590598476dda88e79c473766b67c682aae6e0ab0213491daa6083dcc0c171f86b3868f5506f22c09aa5ea69ad7dfb78f4bf39a8dca375d89a42f408645b3 + languageName: node + linkType: hard + +"@npmcli/fs@npm:^3.1.0": + version: 3.1.0 + resolution: "@npmcli/fs@npm:3.1.0" + dependencies: + semver: "npm:^7.3.5" + checksum: 10c0/162b4a0b8705cd6f5c2470b851d1dc6cd228c86d2170e1769d738c1fbb69a87160901411c3c035331e9e99db72f1f1099a8b734bf1637cc32b9a5be1660e4e1e + languageName: node + linkType: hard + +"@pkgjs/parseargs@npm:^0.11.0": + version: 0.11.0 + resolution: "@pkgjs/parseargs@npm:0.11.0" + checksum: 10c0/5bd7576bb1b38a47a7fc7b51ac9f38748e772beebc56200450c4a817d712232b8f1d3ef70532c80840243c657d491cf6a6be1e3a214cff907645819fdc34aadd + languageName: node + linkType: hard + +"@rollup/pluginutils@npm:^4.0.0": + version: 4.2.1 + resolution: "@rollup/pluginutils@npm:4.2.1" + dependencies: + estree-walker: "npm:^2.0.1" + picomatch: "npm:^2.2.2" + checksum: 10c0/3ee56b2c8f1ed8dfd0a92631da1af3a2dfdd0321948f089b3752b4de1b54dc5076701eadd0e5fc18bd191b77af594ac1db6279e83951238ba16bf8a414c64c48 + languageName: node + linkType: hard + +"@sindresorhus/merge-streams@npm:^2.1.0": + version: 2.3.0 + resolution: "@sindresorhus/merge-streams@npm:2.3.0" + checksum: 10c0/69ee906f3125fb2c6bb6ec5cdd84e8827d93b49b3892bce8b62267116cc7e197b5cccf20c160a1d32c26014ecd14470a72a5e3ee37a58f1d6dadc0db1ccf3894 + languageName: node + linkType: hard + +"@vercel/nft@npm:^0.26.2": + version: 0.26.4 + resolution: "@vercel/nft@npm:0.26.4" + dependencies: + "@mapbox/node-pre-gyp": "npm:^1.0.5" + "@rollup/pluginutils": "npm:^4.0.0" + acorn: "npm:^8.6.0" + acorn-import-attributes: "npm:^1.9.2" + async-sema: "npm:^3.1.1" + bindings: "npm:^1.4.0" + estree-walker: "npm:2.0.2" + glob: "npm:^7.1.3" + graceful-fs: "npm:^4.2.9" + micromatch: "npm:^4.0.2" + node-gyp-build: "npm:^4.2.2" + resolve-from: "npm:^5.0.0" + bin: + nft: out/cli.js + checksum: 10c0/d347fcd7f5371a83362732d0b1b80b9471a2ed3917d6324cc6037392099d6bdc8eae69f0db61bafc87ba2d62af03ef21efe62a7eb52c8eb20341ebcb58903f0d + languageName: node + linkType: hard + +"abbrev@npm:1": + version: 1.1.1 + resolution: "abbrev@npm:1.1.1" + checksum: 10c0/3f762677702acb24f65e813070e306c61fafe25d4b2583f9dfc935131f774863f3addd5741572ed576bd69cabe473c5af18e1e108b829cb7b6b4747884f726e6 + languageName: node + linkType: hard + +"abbrev@npm:^2.0.0": + version: 2.0.0 + resolution: "abbrev@npm:2.0.0" + checksum: 10c0/f742a5a107473946f426c691c08daba61a1d15942616f300b5d32fd735be88fef5cba24201757b6c407fd564555fb48c751cfa33519b2605c8a7aadd22baf372 + languageName: node + linkType: hard + +"acorn-import-attributes@npm:^1.9.2": + version: 1.9.5 + resolution: "acorn-import-attributes@npm:1.9.5" + peerDependencies: + acorn: ^8 + checksum: 10c0/5926eaaead2326d5a86f322ff1b617b0f698aa61dc719a5baa0e9d955c9885cc71febac3fb5bacff71bbf2c4f9c12db2056883c68c53eb962c048b952e1e013d + languageName: node + linkType: hard + +"acorn-walk@npm:^8.3.2": + version: 8.3.2 + resolution: "acorn-walk@npm:8.3.2" + checksum: 10c0/7e2a8dad5480df7f872569b9dccff2f3da7e65f5353686b1d6032ab9f4ddf6e3a2cb83a9b52cf50b1497fd522154dda92f0abf7153290cc79cd14721ff121e52 + languageName: node + linkType: hard + +"acorn@npm:^8.11.3, acorn@npm:^8.6.0": + version: 8.11.3 + resolution: "acorn@npm:8.11.3" + bin: + acorn: bin/acorn + checksum: 10c0/3ff155f8812e4a746fee8ecff1f227d527c4c45655bb1fad6347c3cb58e46190598217551b1500f18542d2bbe5c87120cb6927f5a074a59166fbdd9468f0a299 + languageName: node + linkType: hard + +"agent-base@npm:6": + version: 6.0.2 + resolution: "agent-base@npm:6.0.2" + dependencies: + debug: "npm:4" + checksum: 10c0/dc4f757e40b5f3e3d674bc9beb4f1048f4ee83af189bae39be99f57bf1f48dde166a8b0a5342a84b5944ee8e6ed1e5a9d801858f4ad44764e84957122fe46261 + languageName: node + linkType: hard + +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0": + version: 7.1.0 + resolution: "agent-base@npm:7.1.0" + dependencies: + debug: "npm:^4.3.4" + checksum: 10c0/fc974ab57ffdd8421a2bc339644d312a9cca320c20c3393c9d8b1fd91731b9bbabdb985df5fc860f5b79d81c3e350daa3fcb31c5c07c0bb385aafc817df004ce + languageName: node + linkType: hard + +"aggregate-error@npm:^3.0.0": + version: 3.1.0 + resolution: "aggregate-error@npm:3.1.0" + dependencies: + clean-stack: "npm:^2.0.0" + indent-string: "npm:^4.0.0" + checksum: 10c0/a42f67faa79e3e6687a4923050e7c9807db3848a037076f791d10e092677d65c1d2d863b7848560699f40fc0502c19f40963fb1cd1fb3d338a7423df8e45e039 + languageName: node + linkType: hard + +"ansi-regex@npm:^5.0.1": + version: 5.0.1 + resolution: "ansi-regex@npm:5.0.1" + checksum: 10c0/9a64bb8627b434ba9327b60c027742e5d17ac69277960d041898596271d992d4d52ba7267a63ca10232e29f6107fc8a835f6ce8d719b88c5f8493f8254813737 + languageName: node + linkType: hard + +"ansi-regex@npm:^6.0.1": + version: 6.0.1 + resolution: "ansi-regex@npm:6.0.1" + checksum: 10c0/cbe16dbd2c6b2735d1df7976a7070dd277326434f0212f43abf6d87674095d247968209babdaad31bb00882fa68807256ba9be340eec2f1004de14ca75f52a08 + languageName: node + linkType: hard + +"ansi-styles@npm:^4.0.0": + version: 4.3.0 + resolution: "ansi-styles@npm:4.3.0" + dependencies: + color-convert: "npm:^2.0.1" + checksum: 10c0/895a23929da416f2bd3de7e9cb4eabd340949328ab85ddd6e484a637d8f6820d485f53933446f5291c3b760cbc488beb8e88573dd0f9c7daf83dccc8fe81b041 + languageName: node + linkType: hard + +"ansi-styles@npm:^6.0.0, ansi-styles@npm:^6.1.0, ansi-styles@npm:^6.2.1": + version: 6.2.1 + resolution: "ansi-styles@npm:6.2.1" + checksum: 10c0/5d1ec38c123984bcedd996eac680d548f31828bd679a66db2bdf11844634dde55fec3efa9c6bb1d89056a5e79c1ac540c4c784d592ea1d25028a92227d2f2d5c + languageName: node + linkType: hard + +"aproba@npm:^1.0.3 || ^2.0.0": + version: 2.0.0 + resolution: "aproba@npm:2.0.0" + checksum: 10c0/d06e26384a8f6245d8c8896e138c0388824e259a329e0c9f196b4fa533c82502a6fd449586e3604950a0c42921832a458bb3aa0aa9f0ba449cfd4f50fd0d09b5 + languageName: node + linkType: hard + +"are-we-there-yet@npm:^2.0.0": + version: 2.0.0 + resolution: "are-we-there-yet@npm:2.0.0" + dependencies: + delegates: "npm:^1.0.0" + readable-stream: "npm:^3.6.0" + checksum: 10c0/375f753c10329153c8d66dc95e8f8b6c7cc2aa66e05cb0960bd69092b10dae22900cacc7d653ad11d26b3ecbdbfe1e8bfb6ccf0265ba8077a7d979970f16b99c + languageName: node + linkType: hard + +"argparse@npm:^1.0.7": + version: 1.0.10 + resolution: "argparse@npm:1.0.10" + dependencies: + sprintf-js: "npm:~1.0.2" + checksum: 10c0/b2972c5c23c63df66bca144dbc65d180efa74f25f8fd9b7d9a0a6c88ae839db32df3d54770dcb6460cf840d232b60695d1a6b1053f599d84e73f7437087712de + languageName: node + linkType: hard + +"array-find-index@npm:^1.0.1": + version: 1.0.2 + resolution: "array-find-index@npm:1.0.2" + checksum: 10c0/86b9485c74ddd324feab807e10a6de3f9c1683856267236fac4bb4d4667ada6463e106db3f6c540ae6b720e0442b590ec701d13676df4c6af30ebf4da09b4f57 + languageName: node + linkType: hard + +"arrgv@npm:^1.0.2": + version: 1.0.2 + resolution: "arrgv@npm:1.0.2" + checksum: 10c0/7e6e782e6b749923ac7cbc4048ef6fe0844c4a59bfc8932fcd4c44566ba25eed46501f94dd7cf3c7297da88f3f599ca056bfb77d0c2484aebc92f04239f69124 + languageName: node + linkType: hard + +"arrify@npm:^3.0.0": + version: 3.0.0 + resolution: "arrify@npm:3.0.0" + checksum: 10c0/2e26601b8486f29780f1f70f7ac05a226755814c2a3ab42e196748f650af1dc310cd575a11dd4b9841c70fd7460b2dd2b8fe6fb7a3375878e2660706efafa58e + languageName: node + linkType: hard + +"async-sema@npm:^3.1.1": + version: 3.1.1 + resolution: "async-sema@npm:3.1.1" + checksum: 10c0/a16da9f7f2dbdd00a969bf264b7ad331b59df3eac2b38f529b881c5cc8662594e68ed096d927ec2aabdc13454379cdc6d677bcdb0a3d2db338fb4be17957832b + languageName: node + linkType: hard + +"ava@npm:^6.1.2": + version: 6.1.2 + resolution: "ava@npm:6.1.2" + dependencies: + "@vercel/nft": "npm:^0.26.2" + acorn: "npm:^8.11.3" + acorn-walk: "npm:^8.3.2" + ansi-styles: "npm:^6.2.1" + arrgv: "npm:^1.0.2" + arrify: "npm:^3.0.0" + callsites: "npm:^4.1.0" + cbor: "npm:^9.0.1" + chalk: "npm:^5.3.0" + chunkd: "npm:^2.0.1" + ci-info: "npm:^4.0.0" + ci-parallel-vars: "npm:^1.0.1" + cli-truncate: "npm:^4.0.0" + code-excerpt: "npm:^4.0.0" + common-path-prefix: "npm:^3.0.0" + concordance: "npm:^5.0.4" + currently-unhandled: "npm:^0.4.1" + debug: "npm:^4.3.4" + emittery: "npm:^1.0.1" + figures: "npm:^6.0.1" + globby: "npm:^14.0.0" + ignore-by-default: "npm:^2.1.0" + indent-string: "npm:^5.0.0" + is-plain-object: "npm:^5.0.0" + is-promise: "npm:^4.0.0" + matcher: "npm:^5.0.0" + memoize: "npm:^10.0.0" + ms: "npm:^2.1.3" + p-map: "npm:^7.0.1" + package-config: "npm:^5.0.0" + picomatch: "npm:^3.0.1" + plur: "npm:^5.1.0" + pretty-ms: "npm:^9.0.0" + resolve-cwd: "npm:^3.0.0" + stack-utils: "npm:^2.0.6" + strip-ansi: "npm:^7.1.0" + supertap: "npm:^3.0.1" + temp-dir: "npm:^3.0.0" + write-file-atomic: "npm:^5.0.1" + yargs: "npm:^17.7.2" + peerDependencies: + "@ava/typescript": "*" + peerDependenciesMeta: + "@ava/typescript": + optional: true + bin: + ava: entrypoints/cli.mjs + checksum: 10c0/f35cb1f9bc716714e7c78a601985745774096e4ecd34f9310b858d5779307afa2245ad24274e2d55dd1022c226f4fbdb41947476300977f0b653be0e627adaa4 + languageName: node + linkType: hard + +"balanced-match@npm:^1.0.0": + version: 1.0.2 + resolution: "balanced-match@npm:1.0.2" + checksum: 10c0/9308baf0a7e4838a82bbfd11e01b1cb0f0cf2893bc1676c27c2a8c0e70cbae1c59120c3268517a8ae7fb6376b4639ef81ca22582611dbee4ed28df945134aaee + languageName: node + linkType: hard + +"base64-js@npm:^1.3.1": + version: 1.5.1 + resolution: "base64-js@npm:1.5.1" + checksum: 10c0/f23823513b63173a001030fae4f2dabe283b99a9d324ade3ad3d148e218134676f1ee8568c877cd79ec1c53158dcf2d2ba527a97c606618928ba99dd930102bf + languageName: node + linkType: hard + +"better-sqlite3@npm:^9.4.0": + version: 9.4.0 + resolution: "better-sqlite3@npm:9.4.0" + dependencies: + bindings: "npm:^1.5.0" + node-gyp: "npm:latest" + prebuild-install: "npm:^7.1.1" + checksum: 10c0/42b2edfa46d62763514b87122245a3513a5ff20f05fef4fb49fec33f3de0a51a29025596178f57c634b8013f16bbdf8169a308fb3e3b8d126d715788d72d1e74 + languageName: node + linkType: hard + +"bindings@npm:^1.4.0, bindings@npm:^1.5.0": + version: 1.5.0 + resolution: "bindings@npm:1.5.0" + dependencies: + file-uri-to-path: "npm:1.0.0" + checksum: 10c0/3dab2491b4bb24124252a91e656803eac24292473e56554e35bbfe3cc1875332cfa77600c3bac7564049dc95075bf6fcc63a4609920ff2d64d0fe405fcf0d4ba + languageName: node + linkType: hard + +"bl@npm:^4.0.3": + version: 4.1.0 + resolution: "bl@npm:4.1.0" + dependencies: + buffer: "npm:^5.5.0" + inherits: "npm:^2.0.4" + readable-stream: "npm:^3.4.0" + checksum: 10c0/02847e1d2cb089c9dc6958add42e3cdeaf07d13f575973963335ac0fdece563a50ac770ac4c8fa06492d2dd276f6cc3b7f08c7cd9c7a7ad0f8d388b2a28def5f + languageName: node + linkType: hard + +"blueimp-md5@npm:^2.10.0": + version: 2.19.0 + resolution: "blueimp-md5@npm:2.19.0" + checksum: 10c0/85d04343537dd99a288c62450341dcce7380d3454c81f8e5a971ddd80307d6f9ef51b5b92ad7d48aaaa92fd6d3a1f6b2f4fada068faae646887f7bfabc17a346 + languageName: node + linkType: hard + +"brace-expansion@npm:^1.1.7": + version: 1.1.11 + resolution: "brace-expansion@npm:1.1.11" + dependencies: + balanced-match: "npm:^1.0.0" + concat-map: "npm:0.0.1" + checksum: 10c0/695a56cd058096a7cb71fb09d9d6a7070113c7be516699ed361317aca2ec169f618e28b8af352e02ab4233fb54eb0168460a40dc320bab0034b36ab59aaad668 + languageName: node + linkType: hard + +"brace-expansion@npm:^2.0.1": + version: 2.0.1 + resolution: "brace-expansion@npm:2.0.1" + dependencies: + balanced-match: "npm:^1.0.0" + checksum: 10c0/b358f2fe060e2d7a87aa015979ecea07f3c37d4018f8d6deb5bd4c229ad3a0384fe6029bb76cd8be63c81e516ee52d1a0673edbe2023d53a5191732ae3c3e49f + languageName: node + linkType: hard + +"braces@npm:^3.0.2": + version: 3.0.2 + resolution: "braces@npm:3.0.2" + dependencies: + fill-range: "npm:^7.0.1" + checksum: 10c0/321b4d675791479293264019156ca322163f02dc06e3c4cab33bb15cd43d80b51efef69b0930cfde3acd63d126ebca24cd0544fa6f261e093a0fb41ab9dda381 + languageName: node + linkType: hard + +"buffer@npm:^5.5.0": + version: 5.7.1 + resolution: "buffer@npm:5.7.1" + dependencies: + base64-js: "npm:^1.3.1" + ieee754: "npm:^1.1.13" + checksum: 10c0/27cac81cff434ed2876058d72e7c4789d11ff1120ef32c9de48f59eab58179b66710c488987d295ae89a228f835fc66d088652dffeb8e3ba8659f80eb091d55e + languageName: node + linkType: hard + +"cacache@npm:^18.0.0": + version: 18.0.1 + resolution: "cacache@npm:18.0.1" + dependencies: + "@npmcli/fs": "npm:^3.1.0" + fs-minipass: "npm:^3.0.0" + glob: "npm:^10.2.2" + lru-cache: "npm:^10.0.1" + minipass: "npm:^7.0.3" + minipass-collect: "npm:^2.0.1" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + p-map: "npm:^4.0.0" + ssri: "npm:^10.0.0" + tar: "npm:^6.1.11" + unique-filename: "npm:^3.0.0" + checksum: 10c0/a31666805a80a8b16ad3f85faf66750275a9175a3480896f4f6d31b5d53ef190484fabd71bdb6d2ea5603c717fbef09f4af03d6a65b525c8ef0afaa44c361866 + languageName: node + linkType: hard + +"callsites@npm:^4.1.0": + version: 4.1.0 + resolution: "callsites@npm:4.1.0" + checksum: 10c0/91700844127a6dcd4792d231a12dd8e9ec10525eb9962180a8558417d7e3f443e52a4f14746ad2838eaf14f79431ee1539d13bd188da280f720a06a91bd1157a + languageName: node + linkType: hard + +"cbor@npm:^9.0.1": + version: 9.0.2 + resolution: "cbor@npm:9.0.2" + dependencies: + nofilter: "npm:^3.1.0" + checksum: 10c0/709d4378067e663107b3d63a02d123a7b33e28946b4c5cc40c102f2f0ba13b072a79adc4369bb87a4e743399fce45deec30463fc84d363ab7cb39192d0fe5f30 + languageName: node + linkType: hard + +"chalk@npm:^5.3.0": + version: 5.3.0 + resolution: "chalk@npm:5.3.0" + checksum: 10c0/8297d436b2c0f95801103ff2ef67268d362021b8210daf8ddbe349695333eb3610a71122172ff3b0272f1ef2cf7cc2c41fdaa4715f52e49ffe04c56340feed09 + languageName: node + linkType: hard + +"chownr@npm:^1.1.1": + version: 1.1.4 + resolution: "chownr@npm:1.1.4" + checksum: 10c0/ed57952a84cc0c802af900cf7136de643d3aba2eecb59d29344bc2f3f9bf703a301b9d84cdc71f82c3ffc9ccde831b0d92f5b45f91727d6c9da62f23aef9d9db + languageName: node + linkType: hard + +"chownr@npm:^2.0.0": + version: 2.0.0 + resolution: "chownr@npm:2.0.0" + checksum: 10c0/594754e1303672171cc04e50f6c398ae16128eb134a88f801bf5354fd96f205320f23536a045d9abd8b51024a149696e51231565891d4efdab8846021ecf88e6 + languageName: node + linkType: hard + +"chunkd@npm:^2.0.1": + version: 2.0.1 + resolution: "chunkd@npm:2.0.1" + checksum: 10c0/4e0c5aac6048ecedfa4cd0a5f6c4f010c70a7b7645aeca7bfeb47cb0733c3463054f0ced3f2667b2e0e67edd75d68a8e05481b01115ba3f8a952a93026254504 + languageName: node + linkType: hard + +"ci-info@npm:^4.0.0": + version: 4.0.0 + resolution: "ci-info@npm:4.0.0" + checksum: 10c0/ecc003e5b60580bd081d83dd61d398ddb8607537f916313e40af4667f9c92a1243bd8e8a591a5aa78e418afec245dbe8e90a0e26e39ca0825129a99b978dd3f9 + languageName: node + linkType: hard + +"ci-parallel-vars@npm:^1.0.1": + version: 1.0.1 + resolution: "ci-parallel-vars@npm:1.0.1" + checksum: 10c0/80952f699cbbc146092b077b4f3e28d085620eb4e6be37f069b4dbb3db0ee70e8eec3beef4ebe70ff60631e9fc743b9d0869678489f167442cac08b260e5ac08 + languageName: node + linkType: hard + +"clean-stack@npm:^2.0.0": + version: 2.2.0 + resolution: "clean-stack@npm:2.2.0" + checksum: 10c0/1f90262d5f6230a17e27d0c190b09d47ebe7efdd76a03b5a1127863f7b3c9aec4c3e6c8bb3a7bbf81d553d56a1fd35728f5a8ef4c63f867ac8d690109742a8c1 + languageName: node + linkType: hard + +"cli-truncate@npm:^4.0.0": + version: 4.0.0 + resolution: "cli-truncate@npm:4.0.0" + dependencies: + slice-ansi: "npm:^5.0.0" + string-width: "npm:^7.0.0" + checksum: 10c0/d7f0b73e3d9b88cb496e6c086df7410b541b56a43d18ade6a573c9c18bd001b1c3fba1ad578f741a4218fdc794d042385f8ac02c25e1c295a2d8b9f3cb86eb4c + languageName: node + linkType: hard + +"cliui@npm:^8.0.1": + version: 8.0.1 + resolution: "cliui@npm:8.0.1" + dependencies: + string-width: "npm:^4.2.0" + strip-ansi: "npm:^6.0.1" + wrap-ansi: "npm:^7.0.0" + checksum: 10c0/4bda0f09c340cbb6dfdc1ed508b3ca080f12992c18d68c6be4d9cf51756033d5266e61ec57529e610dacbf4da1c634423b0c1b11037709cc6b09045cbd815df5 + languageName: node + linkType: hard + +"code-excerpt@npm:^4.0.0": + version: 4.0.0 + resolution: "code-excerpt@npm:4.0.0" + dependencies: + convert-to-spaces: "npm:^2.0.1" + checksum: 10c0/b6c5a06e039cecd2ab6a0e10ee0831de8362107d1f298ca3558b5f9004cb8e0260b02dd6c07f57b9a0e346c76864d2873311ee1989809fdeb05bd5fbbadde773 + languageName: node + linkType: hard + +"color-convert@npm:^2.0.1": + version: 2.0.1 + resolution: "color-convert@npm:2.0.1" + dependencies: + color-name: "npm:~1.1.4" + checksum: 10c0/37e1150172f2e311fe1b2df62c6293a342ee7380da7b9cfdba67ea539909afbd74da27033208d01d6d5cfc65ee7868a22e18d7e7648e004425441c0f8a15a7d7 + languageName: node + linkType: hard + +"color-name@npm:~1.1.4": + version: 1.1.4 + resolution: "color-name@npm:1.1.4" + checksum: 10c0/a1a3f914156960902f46f7f56bc62effc6c94e84b2cae157a526b1c1f74b677a47ec602bf68a61abfa2b42d15b7c5651c6dbe72a43af720bc588dff885b10f95 + languageName: node + linkType: hard + +"color-support@npm:^1.1.2": + version: 1.1.3 + resolution: "color-support@npm:1.1.3" + bin: + color-support: bin.js + checksum: 10c0/8ffeaa270a784dc382f62d9be0a98581db43e11eee301af14734a6d089bd456478b1a8b3e7db7ca7dc5b18a75f828f775c44074020b51c05fc00e6d0992b1cc6 + languageName: node + linkType: hard + +"common-path-prefix@npm:^3.0.0": + version: 3.0.0 + resolution: "common-path-prefix@npm:3.0.0" + checksum: 10c0/c4a74294e1b1570f4a8ab435285d185a03976c323caa16359053e749db4fde44e3e6586c29cd051100335e11895767cbbd27ea389108e327d62f38daf4548fdb + languageName: node + linkType: hard + +"concat-map@npm:0.0.1": + version: 0.0.1 + resolution: "concat-map@npm:0.0.1" + checksum: 10c0/c996b1cfdf95b6c90fee4dae37e332c8b6eb7d106430c17d538034c0ad9a1630cb194d2ab37293b1bdd4d779494beee7786d586a50bd9376fd6f7bcc2bd4c98f + languageName: node + linkType: hard + +"concordance@npm:^5.0.4": + version: 5.0.4 + resolution: "concordance@npm:5.0.4" + dependencies: + date-time: "npm:^3.1.0" + esutils: "npm:^2.0.3" + fast-diff: "npm:^1.2.0" + js-string-escape: "npm:^1.0.1" + lodash: "npm:^4.17.15" + md5-hex: "npm:^3.0.1" + semver: "npm:^7.3.2" + well-known-symbols: "npm:^2.0.0" + checksum: 10c0/59b440f330df3a7c9aa148ba588b3e99aed86acab225b4f01ffcea34ace4cf11f817e31153254e8f38ed48508998dad40b9106951a743c334d751f7ab21afb8a + languageName: node + linkType: hard + +"console-control-strings@npm:^1.0.0, console-control-strings@npm:^1.1.0": + version: 1.1.0 + resolution: "console-control-strings@npm:1.1.0" + checksum: 10c0/7ab51d30b52d461412cd467721bb82afe695da78fff8f29fe6f6b9cbaac9a2328e27a22a966014df9532100f6dd85370460be8130b9c677891ba36d96a343f50 + languageName: node + linkType: hard + +"convert-to-spaces@npm:^2.0.1": + version: 2.0.1 + resolution: "convert-to-spaces@npm:2.0.1" + checksum: 10c0/d90aa0e3b6a27f9d5265a8d32def3c5c855b3e823a9db1f26d772f8146d6b91020a2fdfd905ce8048a73fad3aaf836fef8188c67602c374405e2ae8396c4ac46 + languageName: node + linkType: hard + +"cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.3": + version: 7.0.3 + resolution: "cross-spawn@npm:7.0.3" + dependencies: + path-key: "npm:^3.1.0" + shebang-command: "npm:^2.0.0" + which: "npm:^2.0.1" + checksum: 10c0/5738c312387081c98d69c98e105b6327b069197f864a60593245d64c8089c8a0a744e16349281210d56835bb9274130d825a78b2ad6853ca13cfbeffc0c31750 + languageName: node + linkType: hard + +"currently-unhandled@npm:^0.4.1": + version: 0.4.1 + resolution: "currently-unhandled@npm:0.4.1" + dependencies: + array-find-index: "npm:^1.0.1" + checksum: 10c0/32d197689ec32f035910202c1abb0dc6424dce01d7b51779c685119b380d98535c110ffff67a262fc7e367612a7dfd30d3d3055f9a6634b5a9dd1302de7ef11c + languageName: node + linkType: hard + +"date-time@npm:^3.1.0": + version: 3.1.0 + resolution: "date-time@npm:3.1.0" + dependencies: + time-zone: "npm:^1.0.0" + checksum: 10c0/aa3e2e930d74b0b9e90f69de7a16d3376e30f21f1f4ce9a2311d8fec32d760e776efea752dafad0ce188187265235229013036202be053fc2d7979813bfb6ded + languageName: node + linkType: hard + +"debug@npm:4, debug@npm:^4.3.4": + version: 4.3.4 + resolution: "debug@npm:4.3.4" + dependencies: + ms: "npm:2.1.2" + peerDependenciesMeta: + supports-color: + optional: true + checksum: 10c0/cedbec45298dd5c501d01b92b119cd3faebe5438c3917ff11ae1bff86a6c722930ac9c8659792824013168ba6db7c4668225d845c633fbdafbbf902a6389f736 + languageName: node + linkType: hard + +"decompress-response@npm:^6.0.0": + version: 6.0.0 + resolution: "decompress-response@npm:6.0.0" + dependencies: + mimic-response: "npm:^3.1.0" + checksum: 10c0/bd89d23141b96d80577e70c54fb226b2f40e74a6817652b80a116d7befb8758261ad073a8895648a29cc0a5947021ab66705cb542fa9c143c82022b27c5b175e + languageName: node + linkType: hard + +"deep-extend@npm:^0.6.0": + version: 0.6.0 + resolution: "deep-extend@npm:0.6.0" + checksum: 10c0/1c6b0abcdb901e13a44c7d699116d3d4279fdb261983122a3783e7273844d5f2537dc2e1c454a23fcf645917f93fbf8d07101c1d03c015a87faa662755212566 + languageName: node + linkType: hard + +"delegates@npm:^1.0.0": + version: 1.0.0 + resolution: "delegates@npm:1.0.0" + checksum: 10c0/ba05874b91148e1db4bf254750c042bf2215febd23a6d3cda2e64896aef79745fbd4b9996488bd3cafb39ce19dbce0fd6e3b6665275638befffe1c9b312b91b5 + languageName: node + linkType: hard + +"detect-libc@npm:^2.0.0": + version: 2.0.2 + resolution: "detect-libc@npm:2.0.2" + checksum: 10c0/a9f4ffcd2701525c589617d98afe5a5d0676c8ea82bcc4ed6f3747241b79f781d36437c59a5e855254c864d36a3e9f8276568b6b531c28d6e53b093a15703f11 + languageName: node + linkType: hard + +"eastasianwidth@npm:^0.2.0": + version: 0.2.0 + resolution: "eastasianwidth@npm:0.2.0" + checksum: 10c0/26f364ebcdb6395f95124fda411f63137a4bfb5d3a06453f7f23dfe52502905bd84e0488172e0f9ec295fdc45f05c23d5d91baf16bd26f0fe9acd777a188dc39 + languageName: node + linkType: hard + +"emittery@npm:^1.0.1": + version: 1.0.1 + resolution: "emittery@npm:1.0.1" + checksum: 10c0/2587f2f42bb5e004ba1cde61352d2151f4dd4f29eb79ad36f82e200da2faec9742d7bfca1492a024d60396e001e4b07d9b2b9c43be33547ff751ba8ff87c42ce + languageName: node + linkType: hard + +"emoji-regex@npm:^10.3.0": + version: 10.3.0 + resolution: "emoji-regex@npm:10.3.0" + checksum: 10c0/b4838e8dcdceb44cf47f59abe352c25ff4fe7857acaf5fb51097c427f6f75b44d052eb907a7a3b86f86bc4eae3a93f5c2b7460abe79c407307e6212d65c91163 + languageName: node + linkType: hard + +"emoji-regex@npm:^8.0.0": + version: 8.0.0 + resolution: "emoji-regex@npm:8.0.0" + checksum: 10c0/b6053ad39951c4cf338f9092d7bfba448cdfd46fe6a2a034700b149ac9ffbc137e361cbd3c442297f86bed2e5f7576c1b54cc0a6bf8ef5106cc62f496af35010 + languageName: node + linkType: hard + +"emoji-regex@npm:^9.2.2": + version: 9.2.2 + resolution: "emoji-regex@npm:9.2.2" + checksum: 10c0/af014e759a72064cf66e6e694a7fc6b0ed3d8db680427b021a89727689671cefe9d04151b2cad51dbaf85d5ba790d061cd167f1cf32eb7b281f6368b3c181639 + languageName: node + linkType: hard + +"encoding@npm:^0.1.13": + version: 0.1.13 + resolution: "encoding@npm:0.1.13" + dependencies: + iconv-lite: "npm:^0.6.2" + checksum: 10c0/36d938712ff00fe1f4bac88b43bcffb5930c1efa57bbcdca9d67e1d9d6c57cfb1200fb01efe0f3109b2ce99b231f90779532814a81370a1bd3274a0f58585039 + languageName: node + linkType: hard + +"end-of-stream@npm:^1.1.0, end-of-stream@npm:^1.4.1": + version: 1.4.4 + resolution: "end-of-stream@npm:1.4.4" + dependencies: + once: "npm:^1.4.0" + checksum: 10c0/870b423afb2d54bb8d243c63e07c170409d41e20b47eeef0727547aea5740bd6717aca45597a9f2745525667a6b804c1e7bede41f856818faee5806dd9ff3975 + languageName: node + linkType: hard + +"env-paths@npm:^2.2.0": + version: 2.2.1 + resolution: "env-paths@npm:2.2.1" + checksum: 10c0/285325677bf00e30845e330eec32894f5105529db97496ee3f598478e50f008c5352a41a30e5e72ec9de8a542b5a570b85699cd63bd2bc646dbcb9f311d83bc4 + languageName: node + linkType: hard + +"err-code@npm:^2.0.2": + version: 2.0.3 + resolution: "err-code@npm:2.0.3" + checksum: 10c0/b642f7b4dd4a376e954947550a3065a9ece6733ab8e51ad80db727aaae0817c2e99b02a97a3d6cecc648a97848305e728289cf312d09af395403a90c9d4d8a66 + languageName: node + linkType: hard + +"escalade@npm:^3.1.1": + version: 3.1.1 + resolution: "escalade@npm:3.1.1" + checksum: 10c0/afd02e6ca91ffa813e1108b5e7756566173d6bc0d1eb951cb44d6b21702ec17c1cf116cfe75d4a2b02e05acb0b808a7a9387d0d1ca5cf9c04ad03a8445c3e46d + languageName: node + linkType: hard + +"escape-string-regexp@npm:^2.0.0": + version: 2.0.0 + resolution: "escape-string-regexp@npm:2.0.0" + checksum: 10c0/2530479fe8db57eace5e8646c9c2a9c80fa279614986d16dcc6bcaceb63ae77f05a851ba6c43756d816c61d7f4534baf56e3c705e3e0d884818a46808811c507 + languageName: node + linkType: hard + +"escape-string-regexp@npm:^5.0.0": + version: 5.0.0 + resolution: "escape-string-regexp@npm:5.0.0" + checksum: 10c0/6366f474c6f37a802800a435232395e04e9885919873e382b157ab7e8f0feb8fed71497f84a6f6a81a49aab41815522f5839112bd38026d203aea0c91622df95 + languageName: node + linkType: hard + +"esprima@npm:^4.0.0": + version: 4.0.1 + resolution: "esprima@npm:4.0.1" + bin: + esparse: ./bin/esparse.js + esvalidate: ./bin/esvalidate.js + checksum: 10c0/ad4bab9ead0808cf56501750fd9d3fb276f6b105f987707d059005d57e182d18a7c9ec7f3a01794ebddcca676773e42ca48a32d67a250c9d35e009ca613caba3 + languageName: node + linkType: hard + +"estree-walker@npm:2.0.2, estree-walker@npm:^2.0.1": + version: 2.0.2 + resolution: "estree-walker@npm:2.0.2" + checksum: 10c0/53a6c54e2019b8c914dc395890153ffdc2322781acf4bd7d1a32d7aedc1710807bdcd866ac133903d5629ec601fbb50abe8c2e5553c7f5a0afdd9b6af6c945af + languageName: node + linkType: hard + +"esutils@npm:^2.0.3": + version: 2.0.3 + resolution: "esutils@npm:2.0.3" + checksum: 10c0/9a2fe69a41bfdade834ba7c42de4723c97ec776e40656919c62cbd13607c45e127a003f05f724a1ea55e5029a4cf2de444b13009f2af71271e42d93a637137c7 + languageName: node + linkType: hard + +"execa@npm:^8.0.1": + version: 8.0.1 + resolution: "execa@npm:8.0.1" + dependencies: + cross-spawn: "npm:^7.0.3" + get-stream: "npm:^8.0.1" + human-signals: "npm:^5.0.0" + is-stream: "npm:^3.0.0" + merge-stream: "npm:^2.0.0" + npm-run-path: "npm:^5.1.0" + onetime: "npm:^6.0.0" + signal-exit: "npm:^4.1.0" + strip-final-newline: "npm:^3.0.0" + checksum: 10c0/2c52d8775f5bf103ce8eec9c7ab3059909ba350a5164744e9947ed14a53f51687c040a250bda833f906d1283aa8803975b84e6c8f7a7c42f99dc8ef80250d1af + languageName: node + linkType: hard + +"expand-template@npm:^2.0.3": + version: 2.0.3 + resolution: "expand-template@npm:2.0.3" + checksum: 10c0/1c9e7afe9acadf9d373301d27f6a47b34e89b3391b1ef38b7471d381812537ef2457e620ae7f819d2642ce9c43b189b3583813ec395e2938319abe356a9b2f51 + languageName: node + linkType: hard + +"exponential-backoff@npm:^3.1.1": + version: 3.1.1 + resolution: "exponential-backoff@npm:3.1.1" + checksum: 10c0/160456d2d647e6019640bd07111634d8c353038d9fa40176afb7cd49b0548bdae83b56d05e907c2cce2300b81cae35d800ef92fefb9d0208e190fa3b7d6bb579 + languageName: node + linkType: hard + +"fast-diff@npm:^1.2.0": + version: 1.3.0 + resolution: "fast-diff@npm:1.3.0" + checksum: 10c0/5c19af237edb5d5effda008c891a18a585f74bf12953be57923f17a3a4d0979565fc64dbc73b9e20926b9d895f5b690c618cbb969af0cf022e3222471220ad29 + languageName: node + linkType: hard + +"fast-glob@npm:^3.3.2": + version: 3.3.2 + resolution: "fast-glob@npm:3.3.2" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.4" + checksum: 10c0/42baad7b9cd40b63e42039132bde27ca2cb3a4950d0a0f9abe4639ea1aa9d3e3b40f98b1fe31cbc0cc17b664c9ea7447d911a152fa34ec5b72977b125a6fc845 + languageName: node + linkType: hard + +"fastq@npm:^1.6.0": + version: 1.15.0 + resolution: "fastq@npm:1.15.0" + dependencies: + reusify: "npm:^1.0.4" + checksum: 10c0/5ce4f83afa5f88c9379e67906b4d31bc7694a30826d6cc8d0f0473c966929017fda65c2174b0ec89f064ede6ace6c67f8a4fe04cef42119b6a55b0d465554c24 + languageName: node + linkType: hard + +"figures@npm:^6.0.1": + version: 6.1.0 + resolution: "figures@npm:6.1.0" + dependencies: + is-unicode-supported: "npm:^2.0.0" + checksum: 10c0/9159df4264d62ef447a3931537de92f5012210cf5135c35c010df50a2169377581378149abfe1eb238bd6acbba1c0d547b1f18e0af6eee49e30363cedaffcfe4 + languageName: node + linkType: hard + +"file-uri-to-path@npm:1.0.0": + version: 1.0.0 + resolution: "file-uri-to-path@npm:1.0.0" + checksum: 10c0/3b545e3a341d322d368e880e1c204ef55f1d45cdea65f7efc6c6ce9e0c4d22d802d5629320eb779d006fe59624ac17b0e848d83cc5af7cd101f206cb704f5519 + languageName: node + linkType: hard + +"fill-range@npm:^7.0.1": + version: 7.0.1 + resolution: "fill-range@npm:7.0.1" + dependencies: + to-regex-range: "npm:^5.0.1" + checksum: 10c0/7cdad7d426ffbaadf45aeb5d15ec675bbd77f7597ad5399e3d2766987ed20bda24d5fac64b3ee79d93276f5865608bb22344a26b9b1ae6c4d00bd94bf611623f + languageName: node + linkType: hard + +"find-up-simple@npm:^1.0.0": + version: 1.0.0 + resolution: "find-up-simple@npm:1.0.0" + checksum: 10c0/de1ad5e55c8c162f5600fe3297bb55a3da5cd9cb8c6755e463ec1d52c4c15a84e312a68397fb5962d13263b3dbd4ea294668c465ccacc41291d7cc97588769f9 + languageName: node + linkType: hard + +"foreground-child@npm:^3.1.0": + version: 3.1.1 + resolution: "foreground-child@npm:3.1.1" + dependencies: + cross-spawn: "npm:^7.0.0" + signal-exit: "npm:^4.0.1" + checksum: 10c0/9700a0285628abaeb37007c9a4d92bd49f67210f09067638774338e146c8e9c825c5c877f072b2f75f41dc6a2d0be8664f79ffc03f6576649f54a84fb9b47de0 + languageName: node + linkType: hard + +"fs-constants@npm:^1.0.0": + version: 1.0.0 + resolution: "fs-constants@npm:1.0.0" + checksum: 10c0/a0cde99085f0872f4d244e83e03a46aa387b74f5a5af750896c6b05e9077fac00e9932fdf5aef84f2f16634cd473c63037d7a512576da7d5c2b9163d1909f3a8 + languageName: node + linkType: hard + +"fs-minipass@npm:^2.0.0": + version: 2.1.0 + resolution: "fs-minipass@npm:2.1.0" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10c0/703d16522b8282d7299337539c3ed6edddd1afe82435e4f5b76e34a79cd74e488a8a0e26a636afc2440e1a23b03878e2122e3a2cfe375a5cf63c37d92b86a004 + languageName: node + linkType: hard + +"fs-minipass@npm:^3.0.0": + version: 3.0.3 + resolution: "fs-minipass@npm:3.0.3" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10c0/63e80da2ff9b621e2cb1596abcb9207f1cf82b968b116ccd7b959e3323144cce7fb141462200971c38bbf2ecca51695069db45265705bed09a7cd93ae5b89f94 + languageName: node + linkType: hard + +"fs.realpath@npm:^1.0.0": + version: 1.0.0 + resolution: "fs.realpath@npm:1.0.0" + checksum: 10c0/444cf1291d997165dfd4c0d58b69f0e4782bfd9149fd72faa4fe299e68e0e93d6db941660b37dd29153bf7186672ececa3b50b7e7249477b03fdf850f287c948 + languageName: node + linkType: hard + +"gauge@npm:^3.0.0": + version: 3.0.2 + resolution: "gauge@npm:3.0.2" + dependencies: + aproba: "npm:^1.0.3 || ^2.0.0" + color-support: "npm:^1.1.2" + console-control-strings: "npm:^1.0.0" + has-unicode: "npm:^2.0.1" + object-assign: "npm:^4.1.1" + signal-exit: "npm:^3.0.0" + string-width: "npm:^4.2.3" + strip-ansi: "npm:^6.0.1" + wide-align: "npm:^1.1.2" + checksum: 10c0/75230ccaf216471e31025c7d5fcea1629596ca20792de50c596eb18ffb14d8404f927cd55535aab2eeecd18d1e11bd6f23ec3c2e9878d2dda1dc74bccc34b913 + languageName: node + linkType: hard + +"get-caller-file@npm:^2.0.5": + version: 2.0.5 + resolution: "get-caller-file@npm:2.0.5" + checksum: 10c0/c6c7b60271931fa752aeb92f2b47e355eac1af3a2673f47c9589e8f8a41adc74d45551c1bc57b5e66a80609f10ffb72b6f575e4370d61cc3f7f3aaff01757cde + languageName: node + linkType: hard + +"get-east-asian-width@npm:^1.0.0": + version: 1.2.0 + resolution: "get-east-asian-width@npm:1.2.0" + checksum: 10c0/914b1e217cf38436c24b4c60b4c45289e39a45bf9e65ef9fd343c2815a1a02b8a0215aeec8bf9c07c516089004b6e3826332481f40a09529fcadbf6e579f286b + languageName: node + linkType: hard + +"get-stream@npm:^8.0.1": + version: 8.0.1 + resolution: "get-stream@npm:8.0.1" + checksum: 10c0/5c2181e98202b9dae0bb4a849979291043e5892eb40312b47f0c22b9414fc9b28a3b6063d2375705eb24abc41ecf97894d9a51f64ff021511b504477b27b4290 + languageName: node + linkType: hard + +"github-from-package@npm:0.0.0": + version: 0.0.0 + resolution: "github-from-package@npm:0.0.0" + checksum: 10c0/737ee3f52d0a27e26332cde85b533c21fcdc0b09fb716c3f8e522cfaa9c600d4a631dec9fcde179ec9d47cca89017b7848ed4d6ae6b6b78f936c06825b1fcc12 + languageName: node + linkType: hard + +"glob-parent@npm:^5.1.2": + version: 5.1.2 + resolution: "glob-parent@npm:5.1.2" + dependencies: + is-glob: "npm:^4.0.1" + checksum: 10c0/cab87638e2112bee3f839ef5f6e0765057163d39c66be8ec1602f3823da4692297ad4e972de876ea17c44d652978638d2fd583c6713d0eb6591706825020c9ee + languageName: node + linkType: hard + +"glob@npm:^10.2.2, glob@npm:^10.3.10": + version: 10.3.10 + resolution: "glob@npm:10.3.10" + dependencies: + foreground-child: "npm:^3.1.0" + jackspeak: "npm:^2.3.5" + minimatch: "npm:^9.0.1" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry: "npm:^1.10.1" + bin: + glob: dist/esm/bin.mjs + checksum: 10c0/13d8a1feb7eac7945f8c8480e11cd4a44b24d26503d99a8d8ac8d5aefbf3e9802a2b6087318a829fad04cb4e829f25c5f4f1110c68966c498720dd261c7e344d + languageName: node + linkType: hard + +"glob@npm:^7.1.3": + version: 7.2.3 + resolution: "glob@npm:7.2.3" + dependencies: + fs.realpath: "npm:^1.0.0" + inflight: "npm:^1.0.4" + inherits: "npm:2" + minimatch: "npm:^3.1.1" + once: "npm:^1.3.0" + path-is-absolute: "npm:^1.0.0" + checksum: 10c0/65676153e2b0c9095100fe7f25a778bf45608eeb32c6048cf307f579649bcc30353277b3b898a3792602c65764e5baa4f643714dfbdfd64ea271d210c7a425fe + languageName: node + linkType: hard + +"globby@npm:^14.0.0": + version: 14.0.1 + resolution: "globby@npm:14.0.1" + dependencies: + "@sindresorhus/merge-streams": "npm:^2.1.0" + fast-glob: "npm:^3.3.2" + ignore: "npm:^5.2.4" + path-type: "npm:^5.0.0" + slash: "npm:^5.1.0" + unicorn-magic: "npm:^0.1.0" + checksum: 10c0/749a6be91cf455c161ebb5c9130df3991cb9fd7568425db850a8279a6cf45acd031c5069395beb7aeb4dd606b64f0d6ff8116c93726178d8e6182fee58c2736d + languageName: node + linkType: hard + +"graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": + version: 4.2.11 + resolution: "graceful-fs@npm:4.2.11" + checksum: 10c0/386d011a553e02bc594ac2ca0bd6d9e4c22d7fa8cfbfc448a6d148c59ea881b092db9dbe3547ae4b88e55f1b01f7c4a2ecc53b310c042793e63aa44cf6c257f2 + languageName: node + linkType: hard + +"has-unicode@npm:^2.0.1": + version: 2.0.1 + resolution: "has-unicode@npm:2.0.1" + checksum: 10c0/ebdb2f4895c26bb08a8a100b62d362e49b2190bcfd84b76bc4be1a3bd4d254ec52d0dd9f2fbcc093fc5eb878b20c52146f9dfd33e2686ed28982187be593b47c + languageName: node + linkType: hard + +"http-cache-semantics@npm:^4.1.1": + version: 4.1.1 + resolution: "http-cache-semantics@npm:4.1.1" + checksum: 10c0/ce1319b8a382eb3cbb4a37c19f6bfe14e5bb5be3d09079e885e8c513ab2d3cd9214902f8a31c9dc4e37022633ceabfc2d697405deeaf1b8f3552bb4ed996fdfc + languageName: node + linkType: hard + +"http-proxy-agent@npm:^7.0.0": + version: 7.0.0 + resolution: "http-proxy-agent@npm:7.0.0" + dependencies: + agent-base: "npm:^7.1.0" + debug: "npm:^4.3.4" + checksum: 10c0/a11574ff39436cee3c7bc67f259444097b09474605846ddd8edf0bf4ad8644be8533db1aa463426e376865047d05dc22755e638632819317c0c2f1b2196657c8 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^5.0.0": + version: 5.0.1 + resolution: "https-proxy-agent@npm:5.0.1" + dependencies: + agent-base: "npm:6" + debug: "npm:4" + checksum: 10c0/6dd639f03434003577c62b27cafdb864784ef19b2de430d8ae2a1d45e31c4fd60719e5637b44db1a88a046934307da7089e03d6089ec3ddacc1189d8de8897d1 + languageName: node + linkType: hard + +"https-proxy-agent@npm:^7.0.1": + version: 7.0.2 + resolution: "https-proxy-agent@npm:7.0.2" + dependencies: + agent-base: "npm:^7.0.2" + debug: "npm:4" + checksum: 10c0/7735eb90073db087e7e79312e3d97c8c04baf7ea7ca7b013382b6a45abbaa61b281041a98f4e13c8c80d88f843785bcc84ba189165b4b4087b1e3496ba656d77 + languageName: node + linkType: hard + +"human-signals@npm:^5.0.0": + version: 5.0.0 + resolution: "human-signals@npm:5.0.0" + checksum: 10c0/5a9359073fe17a8b58e5a085e9a39a950366d9f00217c4ff5878bd312e09d80f460536ea6a3f260b5943a01fe55c158d1cea3fc7bee3d0520aeef04f6d915c82 + languageName: node + linkType: hard + +"iconv-lite@npm:^0.6.2": + version: 0.6.3 + resolution: "iconv-lite@npm:0.6.3" + dependencies: + safer-buffer: "npm:>= 2.1.2 < 3.0.0" + checksum: 10c0/98102bc66b33fcf5ac044099d1257ba0b7ad5e3ccd3221f34dd508ab4070edff183276221684e1e0555b145fce0850c9f7d2b60a9fcac50fbb4ea0d6e845a3b1 + languageName: node + linkType: hard + +"ieee754@npm:^1.1.13": + version: 1.2.1 + resolution: "ieee754@npm:1.2.1" + checksum: 10c0/b0782ef5e0935b9f12883a2e2aa37baa75da6e66ce6515c168697b42160807d9330de9a32ec1ed73149aea02e0d822e572bca6f1e22bdcbd2149e13b050b17bb + languageName: node + linkType: hard + +"ignore-by-default@npm:^2.1.0": + version: 2.1.0 + resolution: "ignore-by-default@npm:2.1.0" + checksum: 10c0/3a6040dac25ed9da39dee73bf1634fdd1e15b0eb7cf52a6bdec81c310565782d8811c104ce40acb3d690d61c5fc38a91c78e6baee830a8a2232424dbc6b66981 + languageName: node + linkType: hard + +"ignore@npm:^5.2.4": + version: 5.3.0 + resolution: "ignore@npm:5.3.0" + checksum: 10c0/dc06bea5c23aae65d0725a957a0638b57e235ae4568dda51ca142053ed2c352de7e3bc93a69b2b32ac31966a1952e9a93c5ef2e2ab7c6b06aef9808f6b55b571 + languageName: node + linkType: hard + +"imurmurhash@npm:^0.1.4": + version: 0.1.4 + resolution: "imurmurhash@npm:0.1.4" + checksum: 10c0/8b51313850dd33605c6c9d3fd9638b714f4c4c40250cff658209f30d40da60f78992fb2df5dabee4acf589a6a82bbc79ad5486550754bd9ec4e3fc0d4a57d6a6 + languageName: node + linkType: hard + +"indent-string@npm:^4.0.0": + version: 4.0.0 + resolution: "indent-string@npm:4.0.0" + checksum: 10c0/1e1904ddb0cb3d6cce7cd09e27a90184908b7a5d5c21b92e232c93579d314f0b83c246ffb035493d0504b1e9147ba2c9b21df0030f48673fba0496ecd698161f + languageName: node + linkType: hard + +"indent-string@npm:^5.0.0": + version: 5.0.0 + resolution: "indent-string@npm:5.0.0" + checksum: 10c0/8ee77b57d92e71745e133f6f444d6fa3ed503ad0e1bcd7e80c8da08b42375c07117128d670589725ed07b1978065803fa86318c309ba45415b7fe13e7f170220 + languageName: node + linkType: hard + +"inflight@npm:^1.0.4": + version: 1.0.6 + resolution: "inflight@npm:1.0.6" + dependencies: + once: "npm:^1.3.0" + wrappy: "npm:1" + checksum: 10c0/7faca22584600a9dc5b9fca2cd5feb7135ac8c935449837b315676b4c90aa4f391ec4f42240178244b5a34e8bede1948627fda392ca3191522fc46b34e985ab2 + languageName: node + linkType: hard + +"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4": + version: 2.0.4 + resolution: "inherits@npm:2.0.4" + checksum: 10c0/4e531f648b29039fb7426fb94075e6545faa1eb9fe83c29f0b6d9e7263aceb4289d2d4557db0d428188eeb449cc7c5e77b0a0b2c4e248ff2a65933a0dee49ef2 + languageName: node + linkType: hard + +"ini@npm:~1.3.0": + version: 1.3.8 + resolution: "ini@npm:1.3.8" + checksum: 10c0/ec93838d2328b619532e4f1ff05df7909760b6f66d9c9e2ded11e5c1897d6f2f9980c54dd638f88654b00919ce31e827040631eab0a3969e4d1abefa0719516a + languageName: node + linkType: hard + +"ip@npm:^2.0.0": + version: 2.0.0 + resolution: "ip@npm:2.0.0" + checksum: 10c0/8d186cc5585f57372847ae29b6eba258c68862055e18a75cc4933327232cb5c107f89800ce29715d542eef2c254fbb68b382e780a7414f9ee7caf60b7a473958 + languageName: node + linkType: hard + +"irregular-plurals@npm:^3.3.0": + version: 3.5.0 + resolution: "irregular-plurals@npm:3.5.0" + checksum: 10c0/7c033bbe7325e5a6e0a26949cc6863b6ce273403d4cd5b93bd99b33fecb6605b0884097c4259c23ed0c52c2133bf7d1cdcdd7a0630e8c325161fe269b3447918 + languageName: node + linkType: hard + +"is-extglob@npm:^2.1.1": + version: 2.1.1 + resolution: "is-extglob@npm:2.1.1" + checksum: 10c0/5487da35691fbc339700bbb2730430b07777a3c21b9ebaecb3072512dfd7b4ba78ac2381a87e8d78d20ea08affb3f1971b4af629173a6bf435ff8a4c47747912 + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^3.0.0": + version: 3.0.0 + resolution: "is-fullwidth-code-point@npm:3.0.0" + checksum: 10c0/bb11d825e049f38e04c06373a8d72782eee0205bda9d908cc550ccb3c59b99d750ff9537982e01733c1c94a58e35400661f57042158ff5e8f3e90cf936daf0fc + languageName: node + linkType: hard + +"is-fullwidth-code-point@npm:^4.0.0": + version: 4.0.0 + resolution: "is-fullwidth-code-point@npm:4.0.0" + checksum: 10c0/df2a717e813567db0f659c306d61f2f804d480752526886954a2a3e2246c7745fd07a52b5fecf2b68caf0a6c79dcdace6166fdf29cc76ed9975cc334f0a018b8 + languageName: node + linkType: hard + +"is-glob@npm:^4.0.1": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: "npm:^2.1.1" + checksum: 10c0/17fb4014e22be3bbecea9b2e3a76e9e34ff645466be702f1693e8f1ee1adac84710d0be0bd9f967d6354036fd51ab7c2741d954d6e91dae6bb69714de92c197a + languageName: node + linkType: hard + +"is-lambda@npm:^1.0.1": + version: 1.0.1 + resolution: "is-lambda@npm:1.0.1" + checksum: 10c0/85fee098ae62ba6f1e24cf22678805473c7afd0fb3978a3aa260e354cb7bcb3a5806cf0a98403188465efedec41ab4348e8e4e79305d409601323855b3839d4d + languageName: node + linkType: hard + +"is-number@npm:^7.0.0": + version: 7.0.0 + resolution: "is-number@npm:7.0.0" + checksum: 10c0/b4686d0d3053146095ccd45346461bc8e53b80aeb7671cc52a4de02dbbf7dc0d1d2a986e2fe4ae206984b4d34ef37e8b795ebc4f4295c978373e6575e295d811 + languageName: node + linkType: hard + +"is-plain-object@npm:^5.0.0": + version: 5.0.0 + resolution: "is-plain-object@npm:5.0.0" + checksum: 10c0/893e42bad832aae3511c71fd61c0bf61aa3a6d853061c62a307261842727d0d25f761ce9379f7ba7226d6179db2a3157efa918e7fe26360f3bf0842d9f28942c + languageName: node + linkType: hard + +"is-promise@npm:^4.0.0": + version: 4.0.0 + resolution: "is-promise@npm:4.0.0" + checksum: 10c0/ebd5c672d73db781ab33ccb155fb9969d6028e37414d609b115cc534654c91ccd061821d5b987eefaa97cf4c62f0b909bb2f04db88306de26e91bfe8ddc01503 + languageName: node + linkType: hard + +"is-stream@npm:^3.0.0": + version: 3.0.0 + resolution: "is-stream@npm:3.0.0" + checksum: 10c0/eb2f7127af02ee9aa2a0237b730e47ac2de0d4e76a4a905a50a11557f2339df5765eaea4ceb8029f1efa978586abe776908720bfcb1900c20c6ec5145f6f29d8 + languageName: node + linkType: hard + +"is-unicode-supported@npm:^2.0.0": + version: 2.0.0 + resolution: "is-unicode-supported@npm:2.0.0" + checksum: 10c0/3013dfb8265fe9f9a0d1e9433fc4e766595631a8d85d60876c457b4bedc066768dab1477c553d02e2f626d88a4e019162706e04263c94d74994ef636a33b5f94 + languageName: node + linkType: hard + +"isexe@npm:^2.0.0": + version: 2.0.0 + resolution: "isexe@npm:2.0.0" + checksum: 10c0/228cfa503fadc2c31596ab06ed6aa82c9976eec2bfd83397e7eaf06d0ccf42cd1dfd6743bf9aeb01aebd4156d009994c5f76ea898d2832c1fe342da923ca457d + languageName: node + linkType: hard + +"isexe@npm:^3.1.1": + version: 3.1.1 + resolution: "isexe@npm:3.1.1" + checksum: 10c0/9ec257654093443eb0a528a9c8cbba9c0ca7616ccb40abd6dde7202734d96bb86e4ac0d764f0f8cd965856aacbff2f4ce23e730dc19dfb41e3b0d865ca6fdcc7 + languageName: node + linkType: hard + +"jackspeak@npm:^2.3.5": + version: 2.3.6 + resolution: "jackspeak@npm:2.3.6" + dependencies: + "@isaacs/cliui": "npm:^8.0.2" + "@pkgjs/parseargs": "npm:^0.11.0" + dependenciesMeta: + "@pkgjs/parseargs": + optional: true + checksum: 10c0/f01d8f972d894cd7638bc338e9ef5ddb86f7b208ce177a36d718eac96ec86638a6efa17d0221b10073e64b45edc2ce15340db9380b1f5d5c5d000cbc517dc111 + languageName: node + linkType: hard + +"js-string-escape@npm:^1.0.1": + version: 1.0.1 + resolution: "js-string-escape@npm:1.0.1" + checksum: 10c0/2c33b9ff1ba6b84681c51ca0997e7d5a1639813c95d5b61cb7ad47e55cc28fa4a0b1935c3d218710d8e6bcee5d0cd8c44755231e3a4e45fc604534d9595a3628 + languageName: node + linkType: hard + +"js-yaml@npm:^3.14.1": + version: 3.14.1 + resolution: "js-yaml@npm:3.14.1" + dependencies: + argparse: "npm:^1.0.7" + esprima: "npm:^4.0.0" + bin: + js-yaml: bin/js-yaml.js + checksum: 10c0/6746baaaeac312c4db8e75fa22331d9a04cccb7792d126ed8ce6a0bbcfef0cedaddd0c5098fade53db067c09fe00aa1c957674b4765610a8b06a5a189e46433b + languageName: node + linkType: hard + +"load-json-file@npm:^7.0.1": + version: 7.0.1 + resolution: "load-json-file@npm:7.0.1" + checksum: 10c0/7117459608a0b6329c7f78e6e1f541b3162dd901c29dd5af721fec8b270177d2e3d7999c971f344fff04daac368d052732e2c7146014bc84d15e0b636975e19a + languageName: node + linkType: hard + +"lodash@npm:^4.17.15": + version: 4.17.21 + resolution: "lodash@npm:4.17.21" + checksum: 10c0/d8cbea072bb08655bb4c989da418994b073a608dffa608b09ac04b43a791b12aeae7cd7ad919aa4c925f33b48490b5cfe6c1f71d827956071dae2e7bb3a6b74c + languageName: node + linkType: hard + +"lru-cache@npm:^10.0.1, lru-cache@npm:^9.1.1 || ^10.0.0": + version: 10.1.0 + resolution: "lru-cache@npm:10.1.0" + checksum: 10c0/778bc8b2626daccd75f24c4b4d10632496e21ba064b126f526c626fbdbc5b28c472013fccd45d7646b9e1ef052444824854aed617b59cd570d01a8b7d651fc1e + languageName: node + linkType: hard + +"lru-cache@npm:^6.0.0": + version: 6.0.0 + resolution: "lru-cache@npm:6.0.0" + dependencies: + yallist: "npm:^4.0.0" + checksum: 10c0/cb53e582785c48187d7a188d3379c181b5ca2a9c78d2bce3e7dee36f32761d1c42983da3fe12b55cb74e1779fa94cdc2e5367c028a9b35317184ede0c07a30a9 + languageName: node + linkType: hard + +"make-dir@npm:^3.1.0": + version: 3.1.0 + resolution: "make-dir@npm:3.1.0" + dependencies: + semver: "npm:^6.0.0" + checksum: 10c0/56aaafefc49c2dfef02c5c95f9b196c4eb6988040cf2c712185c7fe5c99b4091591a7fc4d4eafaaefa70ff763a26f6ab8c3ff60b9e75ea19876f49b18667ecaa + languageName: node + linkType: hard + +"make-fetch-happen@npm:^13.0.0": + version: 13.0.0 + resolution: "make-fetch-happen@npm:13.0.0" + dependencies: + "@npmcli/agent": "npm:^2.0.0" + cacache: "npm:^18.0.0" + http-cache-semantics: "npm:^4.1.1" + is-lambda: "npm:^1.0.1" + minipass: "npm:^7.0.2" + minipass-fetch: "npm:^3.0.0" + minipass-flush: "npm:^1.0.5" + minipass-pipeline: "npm:^1.2.4" + negotiator: "npm:^0.6.3" + promise-retry: "npm:^2.0.1" + ssri: "npm:^10.0.0" + checksum: 10c0/43b9f6dcbc6fe8b8604cb6396957c3698857a15ba4dbc38284f7f0e61f248300585ef1eb8cc62df54e9c724af977e45b5cdfd88320ef7f53e45070ed3488da55 + languageName: node + linkType: hard + +"matcher@npm:^5.0.0": + version: 5.0.0 + resolution: "matcher@npm:5.0.0" + dependencies: + escape-string-regexp: "npm:^5.0.0" + checksum: 10c0/eda5471fc9d5b7264d63c81727824adc3585ddb5cfdc5fce5a9b7c86f946ff181610735d330b1c37a84811df872d1290bf4e9401d2be2a414204343701144b18 + languageName: node + linkType: hard + +"md5-hex@npm:^3.0.1": + version: 3.0.1 + resolution: "md5-hex@npm:3.0.1" + dependencies: + blueimp-md5: "npm:^2.10.0" + checksum: 10c0/ee2b4d8da16b527b3a3fe4d7a96720f43afd07b46a82d49421208b5a126235fb75cfb30b80d4029514772c8844273f940bddfbf4155c787f968f3be4060d01e4 + languageName: node + linkType: hard + +"memoize@npm:^10.0.0": + version: 10.0.0 + resolution: "memoize@npm:10.0.0" + dependencies: + mimic-function: "npm:^5.0.0" + checksum: 10c0/1584351834564be66b21d47b7afe495851f622669ad49e2f4fa4f35d5633471b93176cf602130a95f71fa0aee65a20179817ffac2dd11fa354aa19a8109a14e8 + languageName: node + linkType: hard + +"merge-stream@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-stream@npm:2.0.0" + checksum: 10c0/867fdbb30a6d58b011449b8885601ec1690c3e41c759ecd5a9d609094f7aed0096c37823ff4a7190ef0b8f22cc86beb7049196ff68c016e3b3c671d0dac91ce5 + languageName: node + linkType: hard + +"merge2@npm:^1.3.0": + version: 1.4.1 + resolution: "merge2@npm:1.4.1" + checksum: 10c0/254a8a4605b58f450308fc474c82ac9a094848081bf4c06778200207820e5193726dc563a0d2c16468810516a5c97d9d3ea0ca6585d23c58ccfff2403e8dbbeb + languageName: node + linkType: hard + +"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4": + version: 4.0.5 + resolution: "micromatch@npm:4.0.5" + dependencies: + braces: "npm:^3.0.2" + picomatch: "npm:^2.3.1" + checksum: 10c0/3d6505b20f9fa804af5d8c596cb1c5e475b9b0cd05f652c5b56141cf941bd72adaeb7a436fda344235cef93a7f29b7472efc779fcdb83b478eab0867b95cdeff + languageName: node + linkType: hard + +"mimic-fn@npm:^4.0.0": + version: 4.0.0 + resolution: "mimic-fn@npm:4.0.0" + checksum: 10c0/de9cc32be9996fd941e512248338e43407f63f6d497abe8441fa33447d922e927de54d4cc3c1a3c6d652857acd770389d5a3823f311a744132760ce2be15ccbf + languageName: node + linkType: hard + +"mimic-function@npm:^5.0.0": + version: 5.0.1 + resolution: "mimic-function@npm:5.0.1" + checksum: 10c0/f3d9464dd1816ecf6bdf2aec6ba32c0728022039d992f178237d8e289b48764fee4131319e72eedd4f7f094e22ded0af836c3187a7edc4595d28dd74368fd81d + languageName: node + linkType: hard + +"mimic-response@npm:^3.1.0": + version: 3.1.0 + resolution: "mimic-response@npm:3.1.0" + checksum: 10c0/0d6f07ce6e03e9e4445bee655202153bdb8a98d67ee8dc965ac140900d7a2688343e6b4c9a72cfc9ef2f7944dfd76eef4ab2482eb7b293a68b84916bac735362 + languageName: node + linkType: hard + +"minimatch@npm:^3.1.1": + version: 3.1.2 + resolution: "minimatch@npm:3.1.2" + dependencies: + brace-expansion: "npm:^1.1.7" + checksum: 10c0/0262810a8fc2e72cca45d6fd86bd349eee435eb95ac6aa45c9ea2180e7ee875ef44c32b55b5973ceabe95ea12682f6e3725cbb63d7a2d1da3ae1163c8b210311 + languageName: node + linkType: hard + +"minimatch@npm:^9.0.1": + version: 9.0.3 + resolution: "minimatch@npm:9.0.3" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 10c0/85f407dcd38ac3e180f425e86553911d101455ca3ad5544d6a7cec16286657e4f8a9aa6695803025c55e31e35a91a2252b5dc8e7d527211278b8b65b4dbd5eac + languageName: node + linkType: hard + +"minimist@npm:^1.2.0, minimist@npm:^1.2.3": + version: 1.2.8 + resolution: "minimist@npm:1.2.8" + checksum: 10c0/19d3fcdca050087b84c2029841a093691a91259a47def2f18222f41e7645a0b7c44ef4b40e88a1e58a40c84d2ef0ee6047c55594d298146d0eb3f6b737c20ce6 + languageName: node + linkType: hard + +"minipass-collect@npm:^2.0.1": + version: 2.0.1 + resolution: "minipass-collect@npm:2.0.1" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10c0/5167e73f62bb74cc5019594709c77e6a742051a647fe9499abf03c71dca75515b7959d67a764bdc4f8b361cf897fbf25e2d9869ee039203ed45240f48b9aa06e + languageName: node + linkType: hard + +"minipass-fetch@npm:^3.0.0": + version: 3.0.4 + resolution: "minipass-fetch@npm:3.0.4" + dependencies: + encoding: "npm:^0.1.13" + minipass: "npm:^7.0.3" + minipass-sized: "npm:^1.0.3" + minizlib: "npm:^2.1.2" + dependenciesMeta: + encoding: + optional: true + checksum: 10c0/1b63c1f3313e88eeac4689f1b71c9f086598db9a189400e3ee960c32ed89e06737fa23976c9305c2d57464fb3fcdc12749d3378805c9d6176f5569b0d0ee8a75 + languageName: node + linkType: hard + +"minipass-flush@npm:^1.0.5": + version: 1.0.5 + resolution: "minipass-flush@npm:1.0.5" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10c0/2a51b63feb799d2bb34669205eee7c0eaf9dce01883261a5b77410c9408aa447e478efd191b4de6fc1101e796ff5892f8443ef20d9544385819093dbb32d36bd + languageName: node + linkType: hard + +"minipass-pipeline@npm:^1.2.4": + version: 1.2.4 + resolution: "minipass-pipeline@npm:1.2.4" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10c0/cbda57cea20b140b797505dc2cac71581a70b3247b84480c1fed5ca5ba46c25ecc25f68bfc9e6dcb1a6e9017dab5c7ada5eab73ad4f0a49d84e35093e0c643f2 + languageName: node + linkType: hard + +"minipass-sized@npm:^1.0.3": + version: 1.0.3 + resolution: "minipass-sized@npm:1.0.3" + dependencies: + minipass: "npm:^3.0.0" + checksum: 10c0/298f124753efdc745cfe0f2bdfdd81ba25b9f4e753ca4a2066eb17c821f25d48acea607dfc997633ee5bf7b6dfffb4eee4f2051eb168663f0b99fad2fa4829cb + languageName: node + linkType: hard + +"minipass@npm:^3.0.0": + version: 3.3.6 + resolution: "minipass@npm:3.3.6" + dependencies: + yallist: "npm:^4.0.0" + checksum: 10c0/a114746943afa1dbbca8249e706d1d38b85ed1298b530f5808ce51f8e9e941962e2a5ad2e00eae7dd21d8a4aae6586a66d4216d1a259385e9d0358f0c1eba16c + languageName: node + linkType: hard + +"minipass@npm:^5.0.0": + version: 5.0.0 + resolution: "minipass@npm:5.0.0" + checksum: 10c0/a91d8043f691796a8ac88df039da19933ef0f633e3d7f0d35dcd5373af49131cf2399bfc355f41515dc495e3990369c3858cd319e5c2722b4753c90bf3152462 + languageName: node + linkType: hard + +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3": + version: 7.0.4 + resolution: "minipass@npm:7.0.4" + checksum: 10c0/6c7370a6dfd257bf18222da581ba89a5eaedca10e158781232a8b5542a90547540b4b9b7e7f490e4cda43acfbd12e086f0453728ecf8c19e0ef6921bc5958ac5 + languageName: node + linkType: hard + +"minizlib@npm:^2.1.1, minizlib@npm:^2.1.2": + version: 2.1.2 + resolution: "minizlib@npm:2.1.2" + dependencies: + minipass: "npm:^3.0.0" + yallist: "npm:^4.0.0" + checksum: 10c0/64fae024e1a7d0346a1102bb670085b17b7f95bf6cfdf5b128772ec8faf9ea211464ea4add406a3a6384a7d87a0cd1a96263692134323477b4fb43659a6cab78 + languageName: node + linkType: hard + +"mkdirp-classic@npm:^0.5.2, mkdirp-classic@npm:^0.5.3": + version: 0.5.3 + resolution: "mkdirp-classic@npm:0.5.3" + checksum: 10c0/95371d831d196960ddc3833cc6907e6b8f67ac5501a6582f47dfae5eb0f092e9f8ce88e0d83afcae95d6e2b61a01741ba03714eeafb6f7a6e9dcc158ac85b168 + languageName: node + linkType: hard + +"mkdirp@npm:^1.0.3": + version: 1.0.4 + resolution: "mkdirp@npm:1.0.4" + bin: + mkdirp: bin/cmd.js + checksum: 10c0/46ea0f3ffa8bc6a5bc0c7081ffc3907777f0ed6516888d40a518c5111f8366d97d2678911ad1a6882bf592fa9de6c784fea32e1687bb94e1f4944170af48a5cf + languageName: node + linkType: hard + +"ms@npm:2.1.2": + version: 2.1.2 + resolution: "ms@npm:2.1.2" + checksum: 10c0/a437714e2f90dbf881b5191d35a6db792efbca5badf112f87b9e1c712aace4b4b9b742dd6537f3edf90fd6f684de897cec230abde57e87883766712ddda297cc + languageName: node + linkType: hard + +"ms@npm:^2.1.3": + version: 2.1.3 + resolution: "ms@npm:2.1.3" + checksum: 10c0/d924b57e7312b3b63ad21fc5b3dc0af5e78d61a1fc7cfb5457edaf26326bf62be5307cc87ffb6862ef1c2b33b0233cdb5d4f01c4c958cc0d660948b65a287a48 + languageName: node + linkType: hard + +"napi-build-utils@npm:^1.0.1": + version: 1.0.2 + resolution: "napi-build-utils@npm:1.0.2" + checksum: 10c0/37fd2cd0ff2ad20073ce78d83fd718a740d568b225924e753ae51cb69d68f330c80544d487e5e5bd18e28702ed2ca469c2424ad948becd1862c1b0209542b2e9 + languageName: node + linkType: hard + +"negotiator@npm:^0.6.3": + version: 0.6.3 + resolution: "negotiator@npm:0.6.3" + checksum: 10c0/3ec9fd413e7bf071c937ae60d572bc67155262068ed522cf4b3be5edbe6ddf67d095ec03a3a14ebf8fc8e95f8e1d61be4869db0dbb0de696f6b837358bd43fc2 + languageName: node + linkType: hard + +"node-abi@npm:^3.3.0": + version: 3.54.0 + resolution: "node-abi@npm:3.54.0" + dependencies: + semver: "npm:^7.3.5" + checksum: 10c0/9ebbb21e6951aa51e831549ed62b68dc56bcc10f6b21ffd04195a16a6abf5ddfc48b6ae5e3334720fe4459cafde5ec8103025902efff5599d0539f8656fc694e + languageName: node + linkType: hard + +"node-fetch@npm:^2.6.7": + version: 2.7.0 + resolution: "node-fetch@npm:2.7.0" + dependencies: + whatwg-url: "npm:^5.0.0" + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + checksum: 10c0/b55786b6028208e6fbe594ccccc213cab67a72899c9234eb59dba51062a299ea853210fcf526998eaa2867b0963ad72338824450905679ff0fa304b8c5093ae8 + languageName: node + linkType: hard + +"node-gyp-build@npm:^4.2.2": + version: 4.8.0 + resolution: "node-gyp-build@npm:4.8.0" + bin: + node-gyp-build: bin.js + node-gyp-build-optional: optional.js + node-gyp-build-test: build-test.js + checksum: 10c0/85324be16f81f0235cbbc42e3eceaeb1b5ab94c8d8f5236755e1435b4908338c65a4e75f66ee343cbcb44ddf9b52a428755bec16dcd983295be4458d95c8e1ad + languageName: node + linkType: hard + +"node-gyp@npm:latest": + version: 10.0.1 + resolution: "node-gyp@npm:10.0.1" + dependencies: + env-paths: "npm:^2.2.0" + exponential-backoff: "npm:^3.1.1" + glob: "npm:^10.3.10" + graceful-fs: "npm:^4.2.6" + make-fetch-happen: "npm:^13.0.0" + nopt: "npm:^7.0.0" + proc-log: "npm:^3.0.0" + semver: "npm:^7.3.5" + tar: "npm:^6.1.2" + which: "npm:^4.0.0" + bin: + node-gyp: bin/node-gyp.js + checksum: 10c0/abddfff7d873312e4ed4a5fb75ce893a5c4fb69e7fcb1dfa71c28a6b92a7f1ef6b62790dffb39181b5a82728ba8f2f32d229cf8cbe66769fe02cea7db4a555aa + languageName: node + linkType: hard + +"nofilter@npm:^3.1.0": + version: 3.1.0 + resolution: "nofilter@npm:3.1.0" + checksum: 10c0/92459f3864a067b347032263f0b536223cbfc98153913b5dce350cb39c8470bc1813366e41993f22c33cc6400c0f392aa324a4b51e24c22040635c1cdb046499 + languageName: node + linkType: hard + +"nopt@npm:^5.0.0": + version: 5.0.0 + resolution: "nopt@npm:5.0.0" + dependencies: + abbrev: "npm:1" + bin: + nopt: bin/nopt.js + checksum: 10c0/fc5c4f07155cb455bf5fc3dd149fac421c1a40fd83c6bfe83aa82b52f02c17c5e88301321318adaa27611c8a6811423d51d29deaceab5fa158b585a61a551061 + languageName: node + linkType: hard + +"nopt@npm:^7.0.0": + version: 7.2.0 + resolution: "nopt@npm:7.2.0" + dependencies: + abbrev: "npm:^2.0.0" + bin: + nopt: bin/nopt.js + checksum: 10c0/9bd7198df6f16eb29ff16892c77bcf7f0cc41f9fb5c26280ac0def2cf8cf319f3b821b3af83eba0e74c85807cc430a16efe0db58fe6ae1f41e69519f585b6aff + languageName: node + linkType: hard + +"npm-run-path@npm:^5.1.0": + version: 5.1.0 + resolution: "npm-run-path@npm:5.1.0" + dependencies: + path-key: "npm:^4.0.0" + checksum: 10c0/ff6d77514489f47fa1c3b1311d09cd4b6d09a874cc1866260f9dea12cbaabda0436ed7f8c2ee44d147bf99a3af29307c6f63b0f83d242b0b6b0ab25dff2629e3 + languageName: node + linkType: hard + +"npmlog@npm:^5.0.1": + version: 5.0.1 + resolution: "npmlog@npm:5.0.1" + dependencies: + are-we-there-yet: "npm:^2.0.0" + console-control-strings: "npm:^1.1.0" + gauge: "npm:^3.0.0" + set-blocking: "npm:^2.0.0" + checksum: 10c0/489ba519031013001135c463406f55491a17fc7da295c18a04937fe3a4d523fd65e88dd418a28b967ab743d913fdeba1e29838ce0ad8c75557057c481f7d49fa + languageName: node + linkType: hard + +"object-assign@npm:^4.1.1": + version: 4.1.1 + resolution: "object-assign@npm:4.1.1" + checksum: 10c0/1f4df9945120325d041ccf7b86f31e8bcc14e73d29171e37a7903050e96b81323784ec59f93f102ec635bcf6fa8034ba3ea0a8c7e69fa202b87ae3b6cec5a414 + languageName: node + linkType: hard + +"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0": + version: 1.4.0 + resolution: "once@npm:1.4.0" + dependencies: + wrappy: "npm:1" + checksum: 10c0/5d48aca287dfefabd756621c5dfce5c91a549a93e9fdb7b8246bc4c4790aa2ec17b34a260530474635147aeb631a2dcc8b32c613df0675f96041cbb8244517d0 + languageName: node + linkType: hard + +"onetime@npm:^6.0.0": + version: 6.0.0 + resolution: "onetime@npm:6.0.0" + dependencies: + mimic-fn: "npm:^4.0.0" + checksum: 10c0/4eef7c6abfef697dd4479345a4100c382d73c149d2d56170a54a07418c50816937ad09500e1ed1e79d235989d073a9bade8557122aee24f0576ecde0f392bb6c + languageName: node + linkType: hard + +"p-map@npm:^4.0.0": + version: 4.0.0 + resolution: "p-map@npm:4.0.0" + dependencies: + aggregate-error: "npm:^3.0.0" + checksum: 10c0/592c05bd6262c466ce269ff172bb8de7c6975afca9b50c975135b974e9bdaafbfe80e61aaaf5be6d1200ba08b30ead04b88cfa7e25ff1e3b93ab28c9f62a2c75 + languageName: node + linkType: hard + +"p-map@npm:^7.0.1": + version: 7.0.2 + resolution: "p-map@npm:7.0.2" + checksum: 10c0/e10548036648d1c043153f9997112fe5a7de54a319210238628f8ea22ee36587fd6ee740811f88b60bbf29d932e23ae35df7fced40df477116c84c18e797047e + languageName: node + linkType: hard + +"package-config@npm:^5.0.0": + version: 5.0.0 + resolution: "package-config@npm:5.0.0" + dependencies: + find-up-simple: "npm:^1.0.0" + load-json-file: "npm:^7.0.1" + checksum: 10c0/f6c48930700b73a41d839bf2898b628d23665827488a4f34aed2d05e4a99d7a70a70ada115c3546765947fbc8accff94c0779da21ea084b25df47cb774531eeb + languageName: node + linkType: hard + +"parse-ms@npm:^4.0.0": + version: 4.0.0 + resolution: "parse-ms@npm:4.0.0" + checksum: 10c0/a7900f4f1ebac24cbf5e9708c16fb2fd482517fad353aecd7aefb8c2ba2f85ce017913ccb8925d231770404780df46244ea6fec598b3bde6490882358b4d2d16 + languageName: node + linkType: hard + +"path-is-absolute@npm:^1.0.0": + version: 1.0.1 + resolution: "path-is-absolute@npm:1.0.1" + checksum: 10c0/127da03c82172a2a50099cddbf02510c1791fc2cc5f7713ddb613a56838db1e8168b121a920079d052e0936c23005562059756d653b7c544c53185efe53be078 + languageName: node + linkType: hard + +"path-key@npm:^3.1.0": + version: 3.1.1 + resolution: "path-key@npm:3.1.1" + checksum: 10c0/748c43efd5a569c039d7a00a03b58eecd1d75f3999f5a28303d75f521288df4823bc057d8784eb72358b2895a05f29a070bc9f1f17d28226cc4e62494cc58c4c + languageName: node + linkType: hard + +"path-key@npm:^4.0.0": + version: 4.0.0 + resolution: "path-key@npm:4.0.0" + checksum: 10c0/794efeef32863a65ac312f3c0b0a99f921f3e827ff63afa5cb09a377e202c262b671f7b3832a4e64731003fa94af0263713962d317b9887bd1e0c48a342efba3 + languageName: node + linkType: hard + +"path-scurry@npm:^1.10.1": + version: 1.10.1 + resolution: "path-scurry@npm:1.10.1" + dependencies: + lru-cache: "npm:^9.1.1 || ^10.0.0" + minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" + checksum: 10c0/e5dc78a7348d25eec61ab166317e9e9c7b46818aa2c2b9006c507a6ff48c672d011292d9662527213e558f5652ce0afcc788663a061d8b59ab495681840c0c1e + languageName: node + linkType: hard + +"path-type@npm:^5.0.0": + version: 5.0.0 + resolution: "path-type@npm:5.0.0" + checksum: 10c0/e8f4b15111bf483900c75609e5e74e3fcb79f2ddb73e41470028fcd3e4b5162ec65da9907be077ee5012c18801ff7fffb35f9f37a077f3f81d85a0b7d6578efd + languageName: node + linkType: hard + +"picomatch@npm:^2.2.2, picomatch@npm:^2.3.1": + version: 2.3.1 + resolution: "picomatch@npm:2.3.1" + checksum: 10c0/26c02b8d06f03206fc2ab8d16f19960f2ff9e81a658f831ecb656d8f17d9edc799e8364b1f4a7873e89d9702dff96204be0fa26fe4181f6843f040f819dac4be + languageName: node + linkType: hard + +"picomatch@npm:^3.0.1": + version: 3.0.1 + resolution: "picomatch@npm:3.0.1" + checksum: 10c0/70ec738569f1864658378b7abdab8939d15dae0718c1df994eae3346fd33daf6a3c1ff4e0c1a0cd1e2c0319130985b63a2cff34d192f2f2acbb78aca76111736 + languageName: node + linkType: hard + +"plur@npm:^5.1.0": + version: 5.1.0 + resolution: "plur@npm:5.1.0" + dependencies: + irregular-plurals: "npm:^3.3.0" + checksum: 10c0/26bb622b8545fcfd47bbf56fbcca66c08693708a232e403fa3589e00003c56c14231ac57c7588ca5db83ef4be1f61383402c4ea954000768f779f8aef6eb6da8 + languageName: node + linkType: hard + +"prebuild-install@npm:^7.1.1": + version: 7.1.1 + resolution: "prebuild-install@npm:7.1.1" + dependencies: + detect-libc: "npm:^2.0.0" + expand-template: "npm:^2.0.3" + github-from-package: "npm:0.0.0" + minimist: "npm:^1.2.3" + mkdirp-classic: "npm:^0.5.3" + napi-build-utils: "npm:^1.0.1" + node-abi: "npm:^3.3.0" + pump: "npm:^3.0.0" + rc: "npm:^1.2.7" + simple-get: "npm:^4.0.0" + tar-fs: "npm:^2.0.0" + tunnel-agent: "npm:^0.6.0" + bin: + prebuild-install: bin.js + checksum: 10c0/6dc70f36b0f4adcb2fe0ed38d874ab28b571fb1a9725d769e8ba3f64a15831e58462de09f3e6e64569bcc4a3e03b9328b56faa0d45fe10ae1574478814536c76 + languageName: node + linkType: hard + +"pretty-ms@npm:^9.0.0": + version: 9.0.0 + resolution: "pretty-ms@npm:9.0.0" + dependencies: + parse-ms: "npm:^4.0.0" + checksum: 10c0/ba4a2acd1fe92a1c629e5cdeb555d7fa344ae9920e20fa00e8ac1db61b8d3dff8638ffc70c7569f681e375df68c9f31291c2c1912cefd02ef1b1bdd0861a4aed + languageName: node + linkType: hard + +"proc-log@npm:^3.0.0": + version: 3.0.0 + resolution: "proc-log@npm:3.0.0" + checksum: 10c0/f66430e4ff947dbb996058f6fd22de2c66612ae1a89b097744e17fb18a4e8e7a86db99eda52ccf15e53f00b63f4ec0b0911581ff2aac0355b625c8eac509b0dc + languageName: node + linkType: hard + +"promise-retry@npm:^2.0.1": + version: 2.0.1 + resolution: "promise-retry@npm:2.0.1" + dependencies: + err-code: "npm:^2.0.2" + retry: "npm:^0.12.0" + checksum: 10c0/9c7045a1a2928094b5b9b15336dcd2a7b1c052f674550df63cc3f36cd44028e5080448175b6f6ca32b642de81150f5e7b1a98b728f15cb069f2dd60ac2616b96 + languageName: node + linkType: hard + +"pump@npm:^3.0.0": + version: 3.0.0 + resolution: "pump@npm:3.0.0" + dependencies: + end-of-stream: "npm:^1.1.0" + once: "npm:^1.3.1" + checksum: 10c0/bbdeda4f747cdf47db97428f3a135728669e56a0ae5f354a9ac5b74556556f5446a46f720a8f14ca2ece5be9b4d5d23c346db02b555f46739934cc6c093a5478 + languageName: node + linkType: hard + +"queue-microtask@npm:^1.2.2": + version: 1.2.3 + resolution: "queue-microtask@npm:1.2.3" + checksum: 10c0/900a93d3cdae3acd7d16f642c29a642aea32c2026446151f0778c62ac089d4b8e6c986811076e1ae180a694cedf077d453a11b58ff0a865629a4f82ab558e102 + languageName: node + linkType: hard + +"rc@npm:^1.2.7": + version: 1.2.8 + resolution: "rc@npm:1.2.8" + dependencies: + deep-extend: "npm:^0.6.0" + ini: "npm:~1.3.0" + minimist: "npm:^1.2.0" + strip-json-comments: "npm:~2.0.1" + bin: + rc: ./cli.js + checksum: 10c0/24a07653150f0d9ac7168e52943cc3cb4b7a22c0e43c7dff3219977c2fdca5a2760a304a029c20811a0e79d351f57d46c9bde216193a0f73978496afc2b85b15 + languageName: node + linkType: hard + +"readable-stream@npm:^3.1.1, readable-stream@npm:^3.4.0, readable-stream@npm:^3.6.0": + version: 3.6.2 + resolution: "readable-stream@npm:3.6.2" + dependencies: + inherits: "npm:^2.0.3" + string_decoder: "npm:^1.1.1" + util-deprecate: "npm:^1.0.1" + checksum: 10c0/e37be5c79c376fdd088a45fa31ea2e423e5d48854be7a22a58869b4e84d25047b193f6acb54f1012331e1bcd667ffb569c01b99d36b0bd59658fb33f513511b7 + languageName: node + linkType: hard + +"require-directory@npm:^2.1.1": + version: 2.1.1 + resolution: "require-directory@npm:2.1.1" + checksum: 10c0/83aa76a7bc1531f68d92c75a2ca2f54f1b01463cb566cf3fbc787d0de8be30c9dbc211d1d46be3497dac5785fe296f2dd11d531945ac29730643357978966e99 + languageName: node + linkType: hard + +"resolve-cwd@npm:^3.0.0": + version: 3.0.0 + resolution: "resolve-cwd@npm:3.0.0" + dependencies: + resolve-from: "npm:^5.0.0" + checksum: 10c0/e608a3ebd15356264653c32d7ecbc8fd702f94c6703ea4ac2fb81d9c359180cba0ae2e6b71faa446631ed6145454d5a56b227efc33a2d40638ac13f8beb20ee4 + languageName: node + linkType: hard + +"resolve-from@npm:^5.0.0": + version: 5.0.0 + resolution: "resolve-from@npm:5.0.0" + checksum: 10c0/b21cb7f1fb746de8107b9febab60095187781137fd803e6a59a76d421444b1531b641bba5857f5dc011974d8a5c635d61cec49e6bd3b7fc20e01f0fafc4efbf2 + languageName: node + linkType: hard + +"retry@npm:^0.12.0": + version: 0.12.0 + resolution: "retry@npm:0.12.0" + checksum: 10c0/59933e8501727ba13ad73ef4a04d5280b3717fd650408460c987392efe9d7be2040778ed8ebe933c5cbd63da3dcc37919c141ef8af0a54a6e4fca5a2af177bfe + languageName: node + linkType: hard + +"reusify@npm:^1.0.4": + version: 1.0.4 + resolution: "reusify@npm:1.0.4" + checksum: 10c0/c19ef26e4e188f408922c46f7ff480d38e8dfc55d448310dfb518736b23ed2c4f547fb64a6ed5bdba92cd7e7ddc889d36ff78f794816d5e71498d645ef476107 + languageName: node + linkType: hard + +"rimraf@npm:^3.0.2": + version: 3.0.2 + resolution: "rimraf@npm:3.0.2" + dependencies: + glob: "npm:^7.1.3" + bin: + rimraf: bin.js + checksum: 10c0/9cb7757acb489bd83757ba1a274ab545eafd75598a9d817e0c3f8b164238dd90eba50d6b848bd4dcc5f3040912e882dc7ba71653e35af660d77b25c381d402e8 + languageName: node + linkType: hard + +"root-workspace-0b6124@workspace:.": + version: 0.0.0-use.local + resolution: "root-workspace-0b6124@workspace:." + dependencies: + "@agoric/synthetic-chain": "npm:^0.0.10" + ava: "npm:^6.1.2" + languageName: unknown + linkType: soft + +"run-parallel@npm:^1.1.9": + version: 1.2.0 + resolution: "run-parallel@npm:1.2.0" + dependencies: + queue-microtask: "npm:^1.2.2" + checksum: 10c0/200b5ab25b5b8b7113f9901bfe3afc347e19bb7475b267d55ad0eb86a62a46d77510cb0f232507c9e5d497ebda569a08a9867d0d14f57a82ad5564d991588b39 + languageName: node + linkType: hard + +"safe-buffer@npm:^5.0.1, safe-buffer@npm:~5.2.0": + version: 5.2.1 + resolution: "safe-buffer@npm:5.2.1" + checksum: 10c0/6501914237c0a86e9675d4e51d89ca3c21ffd6a31642efeba25ad65720bce6921c9e7e974e5be91a786b25aa058b5303285d3c15dbabf983a919f5f630d349f3 + languageName: node + linkType: hard + +"safer-buffer@npm:>= 2.1.2 < 3.0.0": + version: 2.1.2 + resolution: "safer-buffer@npm:2.1.2" + checksum: 10c0/7e3c8b2e88a1841c9671094bbaeebd94448111dd90a81a1f606f3f67708a6ec57763b3b47f06da09fc6054193e0e6709e77325415dc8422b04497a8070fa02d4 + languageName: node + linkType: hard + +"semver@npm:^6.0.0": + version: 6.3.1 + resolution: "semver@npm:6.3.1" + bin: + semver: bin/semver.js + checksum: 10c0/e3d79b609071caa78bcb6ce2ad81c7966a46a7431d9d58b8800cfa9cb6a63699b3899a0e4bcce36167a284578212d9ae6942b6929ba4aa5015c079a67751d42d + languageName: node + linkType: hard + +"semver@npm:^7.3.2, semver@npm:^7.3.5": + version: 7.5.4 + resolution: "semver@npm:7.5.4" + dependencies: + lru-cache: "npm:^6.0.0" + bin: + semver: bin/semver.js + checksum: 10c0/5160b06975a38b11c1ab55950cb5b8a23db78df88275d3d8a42ccf1f29e55112ac995b3a26a522c36e3b5f76b0445f1eef70d696b8c7862a2b4303d7b0e7609e + languageName: node + linkType: hard + +"serialize-error@npm:^7.0.1": + version: 7.0.1 + resolution: "serialize-error@npm:7.0.1" + dependencies: + type-fest: "npm:^0.13.1" + checksum: 10c0/7982937d578cd901276c8ab3e2c6ed8a4c174137730f1fb0402d005af209a0e84d04acc874e317c936724c7b5b26c7a96ff7e4b8d11a469f4924a4b0ea814c05 + languageName: node + linkType: hard + +"set-blocking@npm:^2.0.0": + version: 2.0.0 + resolution: "set-blocking@npm:2.0.0" + checksum: 10c0/9f8c1b2d800800d0b589de1477c753492de5c1548d4ade52f57f1d1f5e04af5481554d75ce5e5c43d4004b80a3eb714398d6907027dc0534177b7539119f4454 + languageName: node + linkType: hard + +"shebang-command@npm:^2.0.0": + version: 2.0.0 + resolution: "shebang-command@npm:2.0.0" + dependencies: + shebang-regex: "npm:^3.0.0" + checksum: 10c0/a41692e7d89a553ef21d324a5cceb5f686d1f3c040759c50aab69688634688c5c327f26f3ecf7001ebfd78c01f3c7c0a11a7c8bfd0a8bc9f6240d4f40b224e4e + languageName: node + linkType: hard + +"shebang-regex@npm:^3.0.0": + version: 3.0.0 + resolution: "shebang-regex@npm:3.0.0" + checksum: 10c0/1dbed0726dd0e1152a92696c76c7f06084eb32a90f0528d11acd764043aacf76994b2fb30aa1291a21bd019d6699164d048286309a278855ee7bec06cf6fb690 + languageName: node + linkType: hard + +"signal-exit@npm:^3.0.0": + version: 3.0.7 + resolution: "signal-exit@npm:3.0.7" + checksum: 10c0/25d272fa73e146048565e08f3309d5b942c1979a6f4a58a8c59d5fa299728e9c2fcd1a759ec870863b1fd38653670240cd420dad2ad9330c71f36608a6a1c912 + languageName: node + linkType: hard + +"signal-exit@npm:^4.0.1, signal-exit@npm:^4.1.0": + version: 4.1.0 + resolution: "signal-exit@npm:4.1.0" + checksum: 10c0/41602dce540e46d599edba9d9860193398d135f7ff72cab629db5171516cfae628d21e7bfccde1bbfdf11c48726bc2a6d1a8fb8701125852fbfda7cf19c6aa83 + languageName: node + linkType: hard + +"simple-concat@npm:^1.0.0": + version: 1.0.1 + resolution: "simple-concat@npm:1.0.1" + checksum: 10c0/62f7508e674414008910b5397c1811941d457dfa0db4fd5aa7fa0409eb02c3609608dfcd7508cace75b3a0bf67a2a77990711e32cd213d2c76f4fd12ee86d776 + languageName: node + linkType: hard + +"simple-get@npm:^4.0.0": + version: 4.0.1 + resolution: "simple-get@npm:4.0.1" + dependencies: + decompress-response: "npm:^6.0.0" + once: "npm:^1.3.1" + simple-concat: "npm:^1.0.0" + checksum: 10c0/b0649a581dbca741babb960423248899203165769747142033479a7dc5e77d7b0fced0253c731cd57cf21e31e4d77c9157c3069f4448d558ebc96cf9e1eebcf0 + languageName: node + linkType: hard + +"slash@npm:^5.1.0": + version: 5.1.0 + resolution: "slash@npm:5.1.0" + checksum: 10c0/eb48b815caf0bdc390d0519d41b9e0556a14380f6799c72ba35caf03544d501d18befdeeef074bc9c052acf69654bc9e0d79d7f1de0866284137a40805299eb3 + languageName: node + linkType: hard + +"slice-ansi@npm:^5.0.0": + version: 5.0.0 + resolution: "slice-ansi@npm:5.0.0" + dependencies: + ansi-styles: "npm:^6.0.0" + is-fullwidth-code-point: "npm:^4.0.0" + checksum: 10c0/2d4d40b2a9d5cf4e8caae3f698fe24ae31a4d778701724f578e984dcb485ec8c49f0c04dab59c401821e80fcdfe89cace9c66693b0244e40ec485d72e543914f + languageName: node + linkType: hard + +"smart-buffer@npm:^4.2.0": + version: 4.2.0 + resolution: "smart-buffer@npm:4.2.0" + checksum: 10c0/a16775323e1404dd43fabafe7460be13a471e021637bc7889468eb45ce6a6b207261f454e4e530a19500cc962c4cc5348583520843b363f4193cee5c00e1e539 + languageName: node + linkType: hard + +"socks-proxy-agent@npm:^8.0.1": + version: 8.0.2 + resolution: "socks-proxy-agent@npm:8.0.2" + dependencies: + agent-base: "npm:^7.0.2" + debug: "npm:^4.3.4" + socks: "npm:^2.7.1" + checksum: 10c0/a842402fc9b8848a31367f2811ca3cd14c4106588b39a0901cd7a69029998adfc6456b0203617c18ed090542ad0c24ee4e9d4c75a0c4b75071e214227c177eb7 + languageName: node + linkType: hard + +"socks@npm:^2.7.1": + version: 2.7.1 + resolution: "socks@npm:2.7.1" + dependencies: + ip: "npm:^2.0.0" + smart-buffer: "npm:^4.2.0" + checksum: 10c0/43f69dbc9f34fc8220bc51c6eea1c39715ab3cfdb115d6e3285f6c7d1a603c5c75655668a5bbc11e3c7e2c99d60321fb8d7ab6f38cda6a215fadd0d6d0b52130 + languageName: node + linkType: hard + +"sprintf-js@npm:~1.0.2": + version: 1.0.3 + resolution: "sprintf-js@npm:1.0.3" + checksum: 10c0/ecadcfe4c771890140da5023d43e190b7566d9cf8b2d238600f31bec0fc653f328da4450eb04bd59a431771a8e9cc0e118f0aa3974b683a4981b4e07abc2a5bb + languageName: node + linkType: hard + +"ssri@npm:^10.0.0": + version: 10.0.5 + resolution: "ssri@npm:10.0.5" + dependencies: + minipass: "npm:^7.0.3" + checksum: 10c0/b091f2ae92474183c7ac5ed3f9811457e1df23df7a7e70c9476eaa9a0c4a0c8fc190fb45acefbf023ca9ee864dd6754237a697dc52a0fb182afe65d8e77443d8 + languageName: node + linkType: hard + +"stack-utils@npm:^2.0.6": + version: 2.0.6 + resolution: "stack-utils@npm:2.0.6" + dependencies: + escape-string-regexp: "npm:^2.0.0" + checksum: 10c0/651c9f87667e077584bbe848acaecc6049bc71979f1e9a46c7b920cad4431c388df0f51b8ad7cfd6eed3db97a2878d0fc8b3122979439ea8bac29c61c95eec8a + languageName: node + linkType: hard + +"string-width-cjs@npm:string-width@^4.2.0, string-width@npm:^1.0.2 || 2 || 3 || 4, string-width@npm:^4.1.0, string-width@npm:^4.2.0, string-width@npm:^4.2.3": + version: 4.2.3 + resolution: "string-width@npm:4.2.3" + dependencies: + emoji-regex: "npm:^8.0.0" + is-fullwidth-code-point: "npm:^3.0.0" + strip-ansi: "npm:^6.0.1" + checksum: 10c0/1e525e92e5eae0afd7454086eed9c818ee84374bb80328fc41217ae72ff5f065ef1c9d7f72da41de40c75fa8bb3dee63d92373fd492c84260a552c636392a47b + languageName: node + linkType: hard + +"string-width@npm:^5.0.1, string-width@npm:^5.1.2": + version: 5.1.2 + resolution: "string-width@npm:5.1.2" + dependencies: + eastasianwidth: "npm:^0.2.0" + emoji-regex: "npm:^9.2.2" + strip-ansi: "npm:^7.0.1" + checksum: 10c0/ab9c4264443d35b8b923cbdd513a089a60de339216d3b0ed3be3ba57d6880e1a192b70ae17225f764d7adbf5994e9bb8df253a944736c15a0240eff553c678ca + languageName: node + linkType: hard + +"string-width@npm:^7.0.0": + version: 7.1.0 + resolution: "string-width@npm:7.1.0" + dependencies: + emoji-regex: "npm:^10.3.0" + get-east-asian-width: "npm:^1.0.0" + strip-ansi: "npm:^7.1.0" + checksum: 10c0/68a99fbc3bd3d8eb42886ff38dce819767dee55f606f74dfa4687a07dfd21262745d9683df0aa53bf81a5dd47c13da921a501925b974bec66a7ddd634fef0634 + languageName: node + linkType: hard + +"string_decoder@npm:^1.1.1": + version: 1.3.0 + resolution: "string_decoder@npm:1.3.0" + dependencies: + safe-buffer: "npm:~5.2.0" + checksum: 10c0/810614ddb030e271cd591935dcd5956b2410dd079d64ff92a1844d6b7588bf992b3e1b69b0f4d34a3e06e0bd73046ac646b5264c1987b20d0601f81ef35d731d + languageName: node + linkType: hard + +"strip-ansi-cjs@npm:strip-ansi@^6.0.1, strip-ansi@npm:^6.0.0, strip-ansi@npm:^6.0.1": + version: 6.0.1 + resolution: "strip-ansi@npm:6.0.1" + dependencies: + ansi-regex: "npm:^5.0.1" + checksum: 10c0/1ae5f212a126fe5b167707f716942490e3933085a5ff6c008ab97ab2f272c8025d3aa218b7bd6ab25729ca20cc81cddb252102f8751e13482a5199e873680952 + languageName: node + linkType: hard + +"strip-ansi@npm:^7.0.1, strip-ansi@npm:^7.1.0": + version: 7.1.0 + resolution: "strip-ansi@npm:7.1.0" + dependencies: + ansi-regex: "npm:^6.0.1" + checksum: 10c0/a198c3762e8832505328cbf9e8c8381de14a4fa50a4f9b2160138158ea88c0f5549fb50cb13c651c3088f47e63a108b34622ec18c0499b6c8c3a5ddf6b305ac4 + languageName: node + linkType: hard + +"strip-final-newline@npm:^3.0.0": + version: 3.0.0 + resolution: "strip-final-newline@npm:3.0.0" + checksum: 10c0/a771a17901427bac6293fd416db7577e2bc1c34a19d38351e9d5478c3c415f523f391003b42ed475f27e33a78233035df183525395f731d3bfb8cdcbd4da08ce + languageName: node + linkType: hard + +"strip-json-comments@npm:~2.0.1": + version: 2.0.1 + resolution: "strip-json-comments@npm:2.0.1" + checksum: 10c0/b509231cbdee45064ff4f9fd73609e2bcc4e84a4d508e9dd0f31f70356473fde18abfb5838c17d56fb236f5a06b102ef115438de0600b749e818a35fbbc48c43 + languageName: node + linkType: hard + +"supertap@npm:^3.0.1": + version: 3.0.1 + resolution: "supertap@npm:3.0.1" + dependencies: + indent-string: "npm:^5.0.0" + js-yaml: "npm:^3.14.1" + serialize-error: "npm:^7.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 10c0/8164674f2e280cab875f0fef5bb36c15553c13e29697ff92f4e0d6bc62149f0303a89eee47535413ed145ea72e14a24d065bab233059d48a499ec5ebb4566b0f + languageName: node + linkType: hard + +"tar-fs@npm:^2.0.0": + version: 2.1.1 + resolution: "tar-fs@npm:2.1.1" + dependencies: + chownr: "npm:^1.1.1" + mkdirp-classic: "npm:^0.5.2" + pump: "npm:^3.0.0" + tar-stream: "npm:^2.1.4" + checksum: 10c0/871d26a934bfb7beeae4c4d8a09689f530b565f79bd0cf489823ff0efa3705da01278160da10bb006d1a793fa0425cf316cec029b32a9159eacbeaff4965fb6d + languageName: node + linkType: hard + +"tar-stream@npm:^2.1.4": + version: 2.2.0 + resolution: "tar-stream@npm:2.2.0" + dependencies: + bl: "npm:^4.0.3" + end-of-stream: "npm:^1.4.1" + fs-constants: "npm:^1.0.0" + inherits: "npm:^2.0.3" + readable-stream: "npm:^3.1.1" + checksum: 10c0/2f4c910b3ee7196502e1ff015a7ba321ec6ea837667220d7bcb8d0852d51cb04b87f7ae471008a6fb8f5b1a1b5078f62f3a82d30c706f20ada1238ac797e7692 + languageName: node + linkType: hard + +"tar@npm:^6.1.11, tar@npm:^6.1.2": + version: 6.2.0 + resolution: "tar@npm:6.2.0" + dependencies: + chownr: "npm:^2.0.0" + fs-minipass: "npm:^2.0.0" + minipass: "npm:^5.0.0" + minizlib: "npm:^2.1.1" + mkdirp: "npm:^1.0.3" + yallist: "npm:^4.0.0" + checksum: 10c0/02ca064a1a6b4521fef88c07d389ac0936730091f8c02d30ea60d472e0378768e870769ab9e986d87807bfee5654359cf29ff4372746cc65e30cbddc352660d8 + languageName: node + linkType: hard + +"temp-dir@npm:^3.0.0": + version: 3.0.0 + resolution: "temp-dir@npm:3.0.0" + checksum: 10c0/a86978a400984cd5f315b77ebf3fe53bb58c61f192278cafcb1f3fb32d584a21dc8e08b93171d7874b7cc972234d3455c467306cc1bfc4524b622e5ad3bfd671 + languageName: node + linkType: hard + +"time-zone@npm:^1.0.0": + version: 1.0.0 + resolution: "time-zone@npm:1.0.0" + checksum: 10c0/d00ebd885039109011b6e2423ebbf225160927333c2ade6d833e9cc4676db20759f1f3855fafde00d1bd668c243a6aa68938ce71fe58aab0d514e820d59c1d81 + languageName: node + linkType: hard + +"to-regex-range@npm:^5.0.1": + version: 5.0.1 + resolution: "to-regex-range@npm:5.0.1" + dependencies: + is-number: "npm:^7.0.0" + checksum: 10c0/487988b0a19c654ff3e1961b87f471702e708fa8a8dd02a298ef16da7206692e8552a0250e8b3e8759270f62e9d8314616f6da274734d3b558b1fc7b7724e892 + languageName: node + linkType: hard + +"tr46@npm:~0.0.3": + version: 0.0.3 + resolution: "tr46@npm:0.0.3" + checksum: 10c0/047cb209a6b60c742f05c9d3ace8fa510bff609995c129a37ace03476a9b12db4dbf975e74600830ef0796e18882b2381fb5fb1f6b4f96b832c374de3ab91a11 + languageName: node + linkType: hard + +"tunnel-agent@npm:^0.6.0": + version: 0.6.0 + resolution: "tunnel-agent@npm:0.6.0" + dependencies: + safe-buffer: "npm:^5.0.1" + checksum: 10c0/4c7a1b813e7beae66fdbf567a65ec6d46313643753d0beefb3c7973d66fcec3a1e7f39759f0a0b4465883499c6dc8b0750ab8b287399af2e583823e40410a17a + languageName: node + linkType: hard + +"type-fest@npm:^0.13.1": + version: 0.13.1 + resolution: "type-fest@npm:0.13.1" + checksum: 10c0/0c0fa07ae53d4e776cf4dac30d25ad799443e9eef9226f9fddbb69242db86b08584084a99885cfa5a9dfe4c063ebdc9aa7b69da348e735baede8d43f1aeae93b + languageName: node + linkType: hard + +"unicorn-magic@npm:^0.1.0": + version: 0.1.0 + resolution: "unicorn-magic@npm:0.1.0" + checksum: 10c0/e4ed0de05b0a05e735c7d8a2930881e5efcfc3ec897204d5d33e7e6247f4c31eac92e383a15d9a6bccb7319b4271ee4bea946e211bf14951fec6ff2cbbb66a92 + languageName: node + linkType: hard + +"unique-filename@npm:^3.0.0": + version: 3.0.0 + resolution: "unique-filename@npm:3.0.0" + dependencies: + unique-slug: "npm:^4.0.0" + checksum: 10c0/6363e40b2fa758eb5ec5e21b3c7fb83e5da8dcfbd866cc0c199d5534c42f03b9ea9ab069769cc388e1d7ab93b4eeef28ef506ab5f18d910ef29617715101884f + languageName: node + linkType: hard + +"unique-slug@npm:^4.0.0": + version: 4.0.0 + resolution: "unique-slug@npm:4.0.0" + dependencies: + imurmurhash: "npm:^0.1.4" + checksum: 10c0/cb811d9d54eb5821b81b18205750be84cb015c20a4a44280794e915f5a0a70223ce39066781a354e872df3572e8155c228f43ff0cce94c7cbf4da2cc7cbdd635 + languageName: node + linkType: hard + +"util-deprecate@npm:^1.0.1": + version: 1.0.2 + resolution: "util-deprecate@npm:1.0.2" + checksum: 10c0/41a5bdd214df2f6c3ecf8622745e4a366c4adced864bc3c833739791aeeeb1838119af7daed4ba36428114b5c67dcda034a79c882e97e43c03e66a4dd7389942 + languageName: node + linkType: hard + +"webidl-conversions@npm:^3.0.0": + version: 3.0.1 + resolution: "webidl-conversions@npm:3.0.1" + checksum: 10c0/5612d5f3e54760a797052eb4927f0ddc01383550f542ccd33d5238cfd65aeed392a45ad38364970d0a0f4fea32e1f4d231b3d8dac4a3bdd385e5cf802ae097db + languageName: node + linkType: hard + +"well-known-symbols@npm:^2.0.0": + version: 2.0.0 + resolution: "well-known-symbols@npm:2.0.0" + checksum: 10c0/cb6c12e98877e8952ec28d13ae6f4fdb54ae1cb49b16a728720276dadd76c930e6cb0e174af3a4620054dd2752546f842540122920c6e31410208abd4958ee6b + languageName: node + linkType: hard + +"whatwg-url@npm:^5.0.0": + version: 5.0.0 + resolution: "whatwg-url@npm:5.0.0" + dependencies: + tr46: "npm:~0.0.3" + webidl-conversions: "npm:^3.0.0" + checksum: 10c0/1588bed84d10b72d5eec1d0faa0722ba1962f1821e7539c535558fb5398d223b0c50d8acab950b8c488b4ba69043fd833cc2697056b167d8ad46fac3995a55d5 + languageName: node + linkType: hard + +"which@npm:^2.0.1": + version: 2.0.2 + resolution: "which@npm:2.0.2" + dependencies: + isexe: "npm:^2.0.0" + bin: + node-which: ./bin/node-which + checksum: 10c0/66522872a768b60c2a65a57e8ad184e5372f5b6a9ca6d5f033d4b0dc98aff63995655a7503b9c0a2598936f532120e81dd8cc155e2e92ed662a2b9377cc4374f + languageName: node + linkType: hard + +"which@npm:^4.0.0": + version: 4.0.0 + resolution: "which@npm:4.0.0" + dependencies: + isexe: "npm:^3.1.1" + bin: + node-which: bin/which.js + checksum: 10c0/449fa5c44ed120ccecfe18c433296a4978a7583bf2391c50abce13f76878d2476defde04d0f79db8165bdf432853c1f8389d0485ca6e8ebce3bbcded513d5e6a + languageName: node + linkType: hard + +"wide-align@npm:^1.1.2": + version: 1.1.5 + resolution: "wide-align@npm:1.1.5" + dependencies: + string-width: "npm:^1.0.2 || 2 || 3 || 4" + checksum: 10c0/1d9c2a3e36dfb09832f38e2e699c367ef190f96b82c71f809bc0822c306f5379df87bab47bed27ea99106d86447e50eb972d3c516c2f95782807a9d082fbea95 + languageName: node + linkType: hard + +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0, wrap-ansi@npm:^7.0.0": + version: 7.0.0 + resolution: "wrap-ansi@npm:7.0.0" + dependencies: + ansi-styles: "npm:^4.0.0" + string-width: "npm:^4.1.0" + strip-ansi: "npm:^6.0.0" + checksum: 10c0/d15fc12c11e4cbc4044a552129ebc75ee3f57aa9c1958373a4db0292d72282f54373b536103987a4a7594db1ef6a4f10acf92978f79b98c49306a4b58c77d4da + languageName: node + linkType: hard + +"wrap-ansi@npm:^8.1.0": + version: 8.1.0 + resolution: "wrap-ansi@npm:8.1.0" + dependencies: + ansi-styles: "npm:^6.1.0" + string-width: "npm:^5.0.1" + strip-ansi: "npm:^7.0.1" + checksum: 10c0/138ff58a41d2f877eae87e3282c0630fc2789012fc1af4d6bd626eeb9a2f9a65ca92005e6e69a75c7b85a68479fe7443c7dbe1eb8fbaa681a4491364b7c55c60 + languageName: node + linkType: hard + +"wrappy@npm:1": + version: 1.0.2 + resolution: "wrappy@npm:1.0.2" + checksum: 10c0/56fece1a4018c6a6c8e28fbc88c87e0fbf4ea8fd64fc6c63b18f4acc4bd13e0ad2515189786dd2c30d3eec9663d70f4ecf699330002f8ccb547e4a18231fc9f0 + languageName: node + linkType: hard + +"write-file-atomic@npm:^5.0.1": + version: 5.0.1 + resolution: "write-file-atomic@npm:5.0.1" + dependencies: + imurmurhash: "npm:^0.1.4" + signal-exit: "npm:^4.0.1" + checksum: 10c0/e8c850a8e3e74eeadadb8ad23c9d9d63e4e792bd10f4836ed74189ef6e996763959f1249c5650e232f3c77c11169d239cbfc8342fc70f3fe401407d23810505d + languageName: node + linkType: hard + +"y18n@npm:^5.0.5": + version: 5.0.8 + resolution: "y18n@npm:5.0.8" + checksum: 10c0/4df2842c36e468590c3691c894bc9cdbac41f520566e76e24f59401ba7d8b4811eb1e34524d57e54bc6d864bcb66baab7ffd9ca42bf1eda596618f9162b91249 + languageName: node + linkType: hard + +"yallist@npm:^4.0.0": + version: 4.0.0 + resolution: "yallist@npm:4.0.0" + checksum: 10c0/2286b5e8dbfe22204ab66e2ef5cc9bbb1e55dfc873bbe0d568aa943eb255d131890dfd5bf243637273d31119b870f49c18fcde2c6ffbb7a7a092b870dc90625a + languageName: node + linkType: hard + +"yargs-parser@npm:^21.1.1": + version: 21.1.1 + resolution: "yargs-parser@npm:21.1.1" + checksum: 10c0/f84b5e48169479d2f402239c59f084cfd1c3acc197a05c59b98bab067452e6b3ea46d4dd8ba2985ba7b3d32a343d77df0debd6b343e5dae3da2aab2cdf5886b2 + languageName: node + linkType: hard + +"yargs@npm:^17.7.2": + version: 17.7.2 + resolution: "yargs@npm:17.7.2" + dependencies: + cliui: "npm:^8.0.1" + escalade: "npm:^3.1.1" + get-caller-file: "npm:^2.0.5" + require-directory: "npm:^2.1.1" + string-width: "npm:^4.2.3" + y18n: "npm:^5.0.5" + yargs-parser: "npm:^21.1.1" + checksum: 10c0/ccd7e723e61ad5965fffbb791366db689572b80cca80e0f96aad968dfff4156cd7cd1ad18607afe1046d8241e6fb2d6c08bf7fa7bfb5eaec818735d8feac8f05 + languageName: node + linkType: hard diff --git a/a3p-integration/yarn.lock b/a3p-integration/yarn.lock index 3223e3fb0b5c..64be7d6a2ce8 100644 --- a/a3p-integration/yarn.lock +++ b/a3p-integration/yarn.lock @@ -5,9 +5,9 @@ __metadata: version: 8 cacheKey: 10c0 -"@agoric/synthetic-chain@npm:^0.0.7": - version: 0.0.7 - resolution: "@agoric/synthetic-chain@npm:0.0.7" +"@agoric/synthetic-chain@npm:^0.0.10": + version: 0.0.10 + resolution: "@agoric/synthetic-chain@npm:0.0.10" dependencies: "@endo/zip": "npm:^1.0.1" better-sqlite3: "npm:^9.4.0" @@ -15,7 +15,7 @@ __metadata: execa: "npm:^8.0.1" bin: synthetic-chain: dist/cli/cli.js - checksum: 10c0/ae53a9c4837eecc7db5020c8e0ac46f02a5a8ae6679adfe5e32365d6895f8ca8eb1da2dad3b3dc7a545ec801275b1a53d68bb0737db462ec9ea82bbcffe37374 + checksum: 10c0/c75308830cbe879ba865e285a20529ac82da1434c778046b27c790e426a8139369c3ef904939905ad73109202a336925733448109a85bc19aa2d350ebdb2a520 languageName: node linkType: hard @@ -972,7 +972,7 @@ __metadata: version: 0.0.0-use.local resolution: "root-workspace-0b6124@workspace:." dependencies: - "@agoric/synthetic-chain": "npm:^0.0.7" + "@agoric/synthetic-chain": "npm:^0.0.10" languageName: unknown linkType: soft diff --git a/docs/env.md b/docs/env.md index 4472af2ec28a..5b510c4ba3d5 100644 --- a/docs/env.md +++ b/docs/env.md @@ -80,6 +80,45 @@ console messages to enable, pass it to `makeConsole`. For example: - `DEBUG=SwingSet:vat` enable for user code, regardless of vat. - `DEBUG=SwingSet:vat,SwingSet:ls` enable for liveslots and user code, all vats +## ENDO_DELIVERY_BREAKPOINTS + +The value of this option should be a JSON string identifying for which +eventual-send message deliveries should a JS `debugger;` statement be executed. +The format of the JSON string is +```json +{ + : { + : , + : , + ... + }, + : { + : + ... + }, + ... +} +``` +Where +- `` is either `"*"` or an alleged string tag of the receiving + remotable (exo or far) object +- `` is either `"*"` or a method name. There is not yet a syntax for symbols to name symbol-named methods, but there may eventually be. +- `` is either `"*"` or a non-negative integer saying how many occurrences to ignore before breakpointing. + +When the program is run under a debugger, it will breakpoint when the JS +`debugger;` statement is executed. When run normally without a debugger, the +`debugger;` statement will have no effect. The `debugger;` statement +is executed *before* the method is entered. + +See https://github.com/endojs/endo/blob/master/packages/pass-style/test/prepare-breakpoints.js for an example. + +## ENDO_SEND_BREAKPOINTS + +The value of this option is a JSON string identifying for which eventual sends +should a JS `debugger;` statement be executed. The format is the same as +shown for `ENDO_DELIVERY_BREAKPOINTS` above, but the breakpoint happens +when and where the message is sent, rather than when and where it is delivered. + ## END_BLOCK_SPIN_MS Affects: cosmic-swingset @@ -106,6 +145,14 @@ Lifetime: until chain is mature enough not to need any pretend tokens For the environment variables beginning with `LOCKDOWN_` , see [`lockdown` Options](https://github.com/endojs/endo/blob/master/packages/ses/docs/lockdown.md). +## ONLY_WELL_FORMED_STRINGS_PASSABLE + +As part of the OCapN standards process, we have agreed that only so-called +"well formed" unicode strings should be considered `Passable`. However, we are +not yet confident about the performance impact of enforcing this ban, so it +is `"disabled"` by default for now. To turn it on, set this option to `"enabled"`. +See https://github.com/endojs/endo/blob/master/packages/pass-style/NEWS.md#v130-2024-03-19 for more explanation. + ## OTEL_EXPORTER_PROMETHEUS_PORT Affects: cosmic-swingset diff --git a/golang/cosmos/app/app.go b/golang/cosmos/app/app.go index 03cfecb4bf95..5f0c0cb70dd3 100644 --- a/golang/cosmos/app/app.go +++ b/golang/cosmos/app/app.go @@ -895,11 +895,12 @@ func unreleasedUpgradeHandler(app *GaiaApp, targetUpgrade string) func(sdk.Conte // Each CoreProposalStep runs sequentially, and can be constructed from // one or more modules executing in parallel within the step. CoreProposalSteps = []vm.CoreProposalStep{ - // First, upgrade wallet factory + /* upgrade-15 evals */ + // Upgrade ZCF only + vm.CoreProposalStepForModules("@agoric/builders/scripts/vats/upgrade-zcf.js"), + // Upgrade walletFactory vm.CoreProposalStepForModules("@agoric/builders/scripts/smart-wallet/build-wallet-factory2-upgrade.js"), - // Then, upgrade Zoe and ZCF - vm.CoreProposalStepForModules("@agoric/builders/scripts/vats/replace-zoe.js"), - // Then, upgrade the provisioning vat + // upgrade the provisioning vat vm.CoreProposalStepForModules("@agoric/builders/scripts/vats/replace-provisioning.js"), // Enable low-level Orchestration. vm.CoreProposalStepForModules( diff --git a/golang/cosmos/go.mod b/golang/cosmos/go.mod index 8976d2e56eb5..5886cfc01a2c 100644 --- a/golang/cosmos/go.mod +++ b/golang/cosmos/go.mod @@ -187,7 +187,10 @@ replace ( // Agoric-specific replacements: replace ( // We need a fork of cosmos-sdk until all of the differences are merged. - github.com/cosmos/cosmos-sdk => github.com/agoric-labs/cosmos-sdk v0.46.16-alpha.agoric.2.1 + github.com/cosmos/cosmos-sdk => github.com/agoric-labs/cosmos-sdk v0.46.16-alpha.agoric.2.4 + + // Pick up an IAVL race fix. + github.com/cosmos/iavl => github.com/cosmos/iavl v0.19.7 // Async version negotiation github.com/cosmos/ibc-go/v6 => github.com/agoric-labs/ibc-go/v6 v6.2.1-alpha.agoric.3 diff --git a/golang/cosmos/go.sum b/golang/cosmos/go.sum index 2b1b00f2fccb..51dc4b7c7353 100644 --- a/golang/cosmos/go.sum +++ b/golang/cosmos/go.sum @@ -232,8 +232,8 @@ github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBA github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/agoric-labs/cometbft v0.34.30-alpha.agoric.1 h1:tqCNL72pQXdUmBzgv1md5SN2U3K/PaYQ4qZ5pFv8v6w= github.com/agoric-labs/cometbft v0.34.30-alpha.agoric.1/go.mod h1:myvkihZD8eg9jKE3WFaugkNoL5nvEqlP7Jbjg98pCek= -github.com/agoric-labs/cosmos-sdk v0.46.16-alpha.agoric.2.1 h1:VZFX9Mogwt4cVTnkdt9zA6UJue4XYXdBURNhlTWw71Q= -github.com/agoric-labs/cosmos-sdk v0.46.16-alpha.agoric.2.1/go.mod h1:zUe5lsg/X7SeSO1nGkzOh9EGKO295szfrxIxYmeLYic= +github.com/agoric-labs/cosmos-sdk v0.46.16-alpha.agoric.2.4 h1:i5IgChQjTyWulV/y5NpVBB5qBJETQ59hYglod6vhok0= +github.com/agoric-labs/cosmos-sdk v0.46.16-alpha.agoric.2.4/go.mod h1:d7e4h+w7FNBNmE6ysp6duBVuQg67pqMtvsLwpT9ca3E= github.com/agoric-labs/cosmos-sdk/ics23/go v0.8.0-alpha.agoric.1 h1:2jvHI/2d+psWAZy6FQ0vXJCHUtfU3ZbbW+pQFL04arQ= github.com/agoric-labs/cosmos-sdk/ics23/go v0.8.0-alpha.agoric.1/go.mod h1:E45NqnlpxGnpfTWL/xauN7MRwEE28T4Dd4uraToOaKg= github.com/agoric-labs/ibc-go/v6 v6.2.1-alpha.agoric.3 h1:YqvVwK+Lg/ZsuwyVm9UbPs8K55fg00R3Y9KnmaTBdgc= @@ -378,8 +378,8 @@ github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= -github.com/cosmos/iavl v0.19.6 h1:XY78yEeNPrEYyNCKlqr9chrwoeSDJ0bV2VjocTk//OU= -github.com/cosmos/iavl v0.19.6/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= +github.com/cosmos/iavl v0.19.7 h1:ij32FaEnwxfEurtK0QKDNhTWFnz6NUmrI5gky/WnoY0= +github.com/cosmos/iavl v0.19.7/go.mod h1:X9PKD3J0iFxdmgNLa7b2LYWdsGd90ToV5cAONApkEPw= github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v6 v6.1.2 h1:Hz4nkpStoXIHrC77CIEyu2mRiN2qysGEZPFRf0fpv7w= github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v6 v6.1.2/go.mod h1:Jo934o/sW7fNxuOa/TjCalSalz+1Fd649eLyANaJx8g= github.com/cosmos/keyring v1.2.0 h1:8C1lBP9xhImmIabyXW4c3vFjjLiBdGCmfLUfeZlV1Yo= diff --git a/packages/ERTP/package.json b/packages/ERTP/package.json index 0daece068db9..f29190a597f8 100644 --- a/packages/ERTP/package.json +++ b/packages/ERTP/package.json @@ -86,6 +86,6 @@ "access": "public" }, "typeCoverage": { - "atLeast": 90.61 + "atLeast": 90.62 } } diff --git a/packages/agoric-cli/package.json b/packages/agoric-cli/package.json index 3a7839702e3a..2bf0150b58d6 100644 --- a/packages/agoric-cli/package.json +++ b/packages/agoric-cli/package.json @@ -98,6 +98,6 @@ "workerThreads": false }, "typeCoverage": { - "atLeast": 77.12 + "atLeast": 76.98 } } diff --git a/packages/agoric-cli/src/commands/inter.js b/packages/agoric-cli/src/commands/inter.js index 56440d43bf65..f8353d41c8b4 100644 --- a/packages/agoric-cli/src/commands/inter.js +++ b/packages/agoric-cli/src/commands/inter.js @@ -33,8 +33,8 @@ const bidInvitationShape = harden({ callPipe: [['makeBidInvitation', M.any()]], }); -/** @typedef {import('@agoric/vats/tools/board-utils.js').VBankAssetDetail } AssetDescriptor */ -/** @typedef {import('@agoric/smart-wallet/src/smartWallet.js').TryExitOfferAction } TryExitOfferAction */ +/** @import {VBankAssetDetail} from '@agoric/vats/tools/board-utils.js'; */ +/** @import {TryExitOfferAction} from '@agoric/smart-wallet/src/smartWallet.js'; */ /** @import {OfferSpec as BidSpec} from '@agoric/inter-protocol/src/auction/auctionBook.js' */ /** @import {ScheduleNotification} from '@agoric/inter-protocol/src/auction/scheduler.js' */ /** @import {BookDataNotification} from '@agoric/inter-protocol/src/auction/auctionBook.js' */ @@ -42,7 +42,7 @@ const bidInvitationShape = harden({ /** * Format amounts, prices etc. based on brand board Ids, displayInfo * - * @param {AssetDescriptor[]} assets + * @param {VBankAssetDetail[]} assets */ const makeFormatters = assets => { const r4 = x => Math.round(x * 10_000) / 10_000; @@ -138,7 +138,7 @@ const coerceBid = (offerStatus, agoricNames, warn) => { * * @param {import('@agoric/smart-wallet/src/offers.js').OfferStatus & * { offerArgs: BidSpec}} bid - * @param {import('../lib/format.js').AssetDescriptor[]} assets + * @param {VBankAssetDetail[]} assets */ export const fmtBid = (bid, assets) => { const fmt = makeFormatters(assets); diff --git a/packages/agoric-cli/src/lib/format.js b/packages/agoric-cli/src/lib/format.js index 18259f316484..cad70a023dc2 100644 --- a/packages/agoric-cli/src/lib/format.js +++ b/packages/agoric-cli/src/lib/format.js @@ -3,6 +3,7 @@ import { makeBoardRemote } from '@agoric/vats/tools/board-utils.js'; /** @import {BoardRemote} from '@agoric/vats/tools/board-utils.js' */ +/** @import {VBankAssetDetail} from '@agoric/vats/tools/board-utils.js'; */ /** * Like @endo/nat but coerces @@ -26,7 +27,7 @@ export const Natural = str => { */ export const bigintReplacer = (k, v) => (typeof v === 'bigint' ? `${v}` : v); -/** @type {Partial} */ +/** @type {Partial} */ // eslint-disable-next-line no-unused-vars const exampleAsset = { brand: makeBoardRemote({ boardId: 'board0425', iface: 'Alleged: BLD brand' }), @@ -35,10 +36,8 @@ const exampleAsset = { proposedName: 'Agoric staking token', }; -/** @typedef {import('@agoric/vats/tools/board-utils.js').VBankAssetDetail } AssetDescriptor */ - /** - * @param {AssetDescriptor[]} assets + * @param {VBankAssetDetail[]} assets * @returns {(a: Amount & { brand: BoardRemote }) => [string | null, number | any[]]} */ export const makeAmountFormatter = assets => amt => { @@ -90,7 +89,7 @@ export const asBoardRemote = x => { * Summarize the balances array as user-facing informative tuples * * @param {import('@agoric/smart-wallet/src/smartWallet.js').CurrentWalletRecord['purses']} purses - * @param {AssetDescriptor[]} assets + * @param {VBankAssetDetail[]} assets */ export const purseBalanceTuples = (purses, assets) => { const fmt = makeAmountFormatter(assets); diff --git a/packages/agoric-cli/src/lib/rpc.js b/packages/agoric-cli/src/lib/rpc.js index fb6dc58d4f82..23da41fe7ff7 100644 --- a/packages/agoric-cli/src/lib/rpc.js +++ b/packages/agoric-cli/src/lib/rpc.js @@ -148,12 +148,13 @@ export const makeVStorage = (powers, config = networkConfig) => { // console.debug('readAt returned', { blockHeight }); } catch (err) { if ( - // CosmosSDK ErrNotFound; there is no data at the path - (err.codespace === 'sdk' && err.code === 38) || - // CosmosSDK ErrUnknownRequest; misrepresentation of the same until - // https://github.com/Agoric/agoric-sdk/commit/dafc7c1708977aaa55e245dc09a73859cf1df192 - // TODO remove after upgrade-12 - err.message.match(/unknown request/) + // CosmosSDK ErrInvalidRequest with particular message text; + // misrepresentation of pruned data + // TODO replace after incorporating a fix to + // https://github.com/cosmos/cosmos-sdk/issues/19992 + err.codespace === 'sdk' && + err.code === 18 && + err.message.match(/pruned/) ) { // console.error(err); break; diff --git a/packages/agoric-cli/test/test-inter-cli.js b/packages/agoric-cli/test/test-inter-cli.js index af3a901d1059..3a80a27c26d4 100644 --- a/packages/agoric-cli/test/test-inter-cli.js +++ b/packages/agoric-cli/test/test-inter-cli.js @@ -14,7 +14,7 @@ const { entries } = Object; /** * @import { Command } from 'commander'; - * @import { BoardRemote } from '@agoric/vats/tools/board-utils.js'; + * @import { BoardRemote, VBankAssetDetail } from '@agoric/vats/tools/board-utils.js'; */ /** @@ -39,7 +39,7 @@ const agoricNames = harden({ auctioneer: makeBoardRemote({ boardId: 'board434', iface: 'Instance' }), }, - /** @type {Record} */ + /** @type {Record} */ vbankAsset: { ubld: { denom: 'ubld', diff --git a/packages/boot/package.json b/packages/boot/package.json index 8c603233ecaa..91b5823f1d74 100644 --- a/packages/boot/package.json +++ b/packages/boot/package.json @@ -90,6 +90,6 @@ "workerThreads": false }, "typeCoverage": { - "atLeast": 86 + "atLeast": 85.88 } } diff --git a/packages/builders/package.json b/packages/builders/package.json index cf95477b318c..b34c6f357c3d 100644 --- a/packages/builders/package.json +++ b/packages/builders/package.json @@ -78,6 +78,6 @@ "workerThreads": false }, "typeCoverage": { - "atLeast": 74.42 + "atLeast": 74.28 } } diff --git a/packages/builders/scripts/vats/upgrade-zcf.js b/packages/builders/scripts/vats/upgrade-zcf.js new file mode 100644 index 000000000000..73afe7e1a641 --- /dev/null +++ b/packages/builders/scripts/vats/upgrade-zcf.js @@ -0,0 +1,18 @@ +import { makeHelpers } from '@agoric/deploy-script-support'; + +/** @type {import('@agoric/deploy-script-support/src/externalTypes.js').ProposalBuilder} */ +export const defaultProposalBuilder = async ({ publishRef, install }) => + harden({ + sourceSpec: '@agoric/vats/src/proposals/zcf-only-proposal.js', + getManifestCall: [ + 'getManifestForUpgradingZcf', + { + zcfRef: publishRef(install('@agoric/zoe/src/contractFacet/vatRoot.js')), + }, + ], + }); + +export default async (homeP, endowments) => { + const { writeCoreProposal } = await makeHelpers(homeP, endowments); + await writeCoreProposal('upgrade-zcf', defaultProposalBuilder); +}; diff --git a/packages/casting/package.json b/packages/casting/package.json index 899be4e52d07..cae5060cf4f4 100644 --- a/packages/casting/package.json +++ b/packages/casting/package.json @@ -60,6 +60,6 @@ "workerThreads": false }, "typeCoverage": { - "atLeast": 89.6 + "atLeast": 88.94 } } diff --git a/packages/cosmic-swingset/src/launch-chain.js b/packages/cosmic-swingset/src/launch-chain.js index 558651273634..c521e79bdbfb 100644 --- a/packages/cosmic-swingset/src/launch-chain.js +++ b/packages/cosmic-swingset/src/launch-chain.js @@ -10,6 +10,8 @@ import anylogger from 'anylogger'; import { E } from '@endo/far'; import bundleSource from '@endo/bundle-source'; +/** @import {RunPolicy} from '@agoric/swingset-vat' */ + import { buildMailbox, buildMailboxStateMap, @@ -242,7 +244,7 @@ export async function buildSwingset( } /** - * @typedef {import('@agoric/swingset-vat').RunPolicy & { + * @typedef {RunPolicy & { * shouldRun(): boolean; * remainingBeans(): bigint | undefined; * totalBeans(): bigint; diff --git a/packages/deploy-script-support/README.md b/packages/deploy-script-support/README.md index 9ed2b83dd6d4..35fc33991e68 100644 --- a/packages/deploy-script-support/README.md +++ b/packages/deploy-script-support/README.md @@ -1,4 +1,87 @@ # Deploy Script Support -Import this code in your dapp deploy scripts to more easily install and -interact with Zoe contracts. \ No newline at end of file +To install code on chain or in the a3p-integration environment, you'll have to +generate a proposal, and write a script to build the core proposal. The +proposals have limited access to bootstrap powers, described by their manifests. + + +### Proposal + +The proposal is called with `(powers, options)` available. The manifest +detailing the powers that will be used is usually in the same file, and +conventionally provided by a function named `getManifestForFoo`. The manifest +needs to have a unique name, since it will be referenced by name from the script. +The usual format is +```js +export const foo = async ( + { + consume: { + ... + }, + brands: { + ... + } + }, + options, +) => { + // do the things using powers and options +}; + +export const getManifestForFoo = (powers, options) => { + manifest: { + [foo.name]: { + consume: { + ... + }, + options, +)}; +``` + +`manifest` contains descriptions of powers to be provided to the proposals. + +**TODO** what happens with the `installations` in [`startPsm.js`](https://github.com/Agoric/agoric-sdk/blob/b13743a2cccf0cb63a412b54384435596d4e81ea/packages/inter-protocol/src/proposals/startPSM.js#L496)? + +`options` allows the proposal to be provided with arbitray other powerful +objects. + +### Script + +The script describes how to build the core proposal. For +`agoric-3-proposals` and uploading to the chain, the script must be named in the +`CoreProposalSteps` section in +[`app.go`](https://github.com/Agoric/agoric-sdk/blob/b13743a2cccf0cb63a412b54384435596d4e81ea/golang/cosmos/app/app.go#L881), +and its `defaultProposalBuilder` will be invoked +directly. + +Script files should export `defaultProposalBuilder` and a `default` function +that invokes `writeCoreProposal` one or more times to generate sets of files +describing the proposal. + +```js +export const defaultProposalBuilder = ({ publishRef, install }) => { + return harden({ + sourceSpec: '@agoric/vats/src/proposals/foo.js', + getManifestCall: [ + 'getManifestForFoo', + { + fooRef: publishRef(install('@agoric/...')), + ...otherParams, + }, + ], + }); +}; +` +export default async (homeP, endowments) => { + const { writeCoreProposal } = await makeHelpers(homeP, endowments); + await writeCoreProposal('proposalName', defaultProposalBuilder); +}; +``` + +The first element of `getManifestCall` is interpreted as the name of a proposal. +The second element of `getManifestCall` produces the `options` argument passed +to the proposal. (`foo` in the example above). A common thing to want to pass in +options is a reference to code to be installed on-chain. The `fooRef` example +above shows how. `publishRef(install())` is built from sources in the +sdk, and passed as a `bundleRef`, which contains a `bundleID` suitable for +passing to Zoe (for contracts) or `vatAdminService` (for non-contract vat code). + diff --git a/packages/deployment/Dockerfile.sdk b/packages/deployment/Dockerfile.sdk index 0430e2b160e8..9c72f4002055 100644 --- a/packages/deployment/Dockerfile.sdk +++ b/packages/deployment/Dockerfile.sdk @@ -1,3 +1,5 @@ +# syntax=docker/dockerfile:1.4 + ########################### # The golang build container FROM golang:1.20-bullseye as cosmos-go diff --git a/packages/governance/package.json b/packages/governance/package.json index 3eec1f2e63eb..5c9dd06f2a82 100644 --- a/packages/governance/package.json +++ b/packages/governance/package.json @@ -77,6 +77,6 @@ "access": "public" }, "typeCoverage": { - "atLeast": 89.27 + "atLeast": 89.25 } } diff --git a/packages/governance/src/types.js b/packages/governance/src/types.js index 23a80c4c5c5e..23c8e3ddec7c 100644 --- a/packages/governance/src/types.js +++ b/packages/governance/src/types.js @@ -1,5 +1,7 @@ export {}; +/** @import {ContractStartFunction} from '@agoric/zoe/src/zoeService/utils.js' */ + /** * @typedef { 'unranked' | 'order' | 'plurality' } ChoiceMethod * * UNRANKED: "unranked voting" means that the voter specifies some number of @@ -696,7 +698,7 @@ export {}; */ /** - * @typedef {import('@agoric/zoe/src/zoeService/utils.js').ContractStartFunction + * @typedef {ContractStartFunction * & ((zcf?: any, pa?: any, baggage?: any) => ERef<{creatorFacet: GovernedCreatorFacet<{}>, publicFacet: GovernedPublicFacet<{}>}>)} GovernableStartFn */ diff --git a/packages/inter-protocol/package.json b/packages/inter-protocol/package.json index 6c82720f91f8..ed07d754e132 100644 --- a/packages/inter-protocol/package.json +++ b/packages/inter-protocol/package.json @@ -83,6 +83,6 @@ "access": "public" }, "typeCoverage": { - "atLeast": 95.9 + "atLeast": 95.89 } } diff --git a/packages/inter-protocol/src/proposals/econ-behaviors.js b/packages/inter-protocol/src/proposals/econ-behaviors.js index fdb1bb8a74cc..5b669fd31a40 100644 --- a/packages/inter-protocol/src/proposals/econ-behaviors.js +++ b/packages/inter-protocol/src/proposals/econ-behaviors.js @@ -13,6 +13,8 @@ import { makeGovernedTerms as makeGovernedATerms } from '../auction/params.js'; import { makeReserveTerms } from '../reserve/params.js'; import { makeGovernedTerms as makeGovernedVFTerms } from '../vaultFactory/params.js'; +/** @import {StartedInstanceKit} from '@agoric/zoe/src/zoeService/utils.js' */ + const trace = makeTracer('RunEconBehaviors', true); export const SECONDS_PER_MINUTE = 60n; @@ -67,12 +69,12 @@ export const SECONDS_PER_WEEK = 7n * SECONDS_PER_DAY; */ /** - * @typedef {import('@agoric/zoe/src/zoeService/utils.js').StartedInstanceKit< + * @typedef {StartedInstanceKit< * import('../econCommitteeCharter.js')['start'] * >} EconCharterStartResult */ /** - * @typedef {import('@agoric/zoe/src/zoeService/utils.js').StartedInstanceKit< + * @typedef {StartedInstanceKit< * import('@agoric/governance/src/committee.js')['start'] * >} CommitteeStartResult */ diff --git a/packages/inter-protocol/test/auction/test-scheduler.js b/packages/inter-protocol/test/auction/test-scheduler.js index 80eecdfec677..90e3e59e7155 100644 --- a/packages/inter-protocol/test/auction/test-scheduler.js +++ b/packages/inter-protocol/test/auction/test-scheduler.js @@ -22,7 +22,10 @@ import { setUpInstallations, } from './tools.js'; -/** @import {TimerService} from '@agoric/time' */ +/** + * @import {TimerService} from '@agoric/time'; + * @import {AuctionParams} from '../../src/auction/params.js'; + */ test('schedule start to finish', async t => { const { zcf, zoe } = await setupZCFTest(); @@ -50,7 +53,7 @@ test('schedule start to finish', async t => { StartFrequency: 10n, PriceLockPeriod: 5n, }; - /** @type {import('../../src/auction/params.js').AuctionParams} */ + /** @type {AuctionParams} */ // @ts-expect-error ignore missing values for test const paramValues = objectMap( makeAuctioneerParams(defaultParams), @@ -273,7 +276,7 @@ test('lowest >= starting', async t => { LowestRate: 110n, StartingRate: 105n, }; - /** @type {import('../../src/auction/params.js').AuctionParams} */ + /** @type {AuctionParams} */ // @ts-expect-error ignore missing values for test const paramValues = objectMap( makeAuctioneerParams(defaultParams), @@ -324,7 +327,7 @@ test('zero time for auction', async t => { AuctionStartDelay: 1n, PriceLockPeriod: 1n, }; - /** @type {import('../../src/auction/params.js').AuctionParams} */ + /** @type {AuctionParams} */ // @ts-expect-error ignore missing values for test const paramValues = objectMap( makeAuctioneerParams(defaultParams), @@ -370,7 +373,7 @@ test('discountStep 0', async t => { ...defaultParams, DiscountStep: 0n, }; - /** @type {import('../../src/auction/params.js').AuctionParams} */ + /** @type {AuctionParams} */ // @ts-expect-error ignore missing values for test const paramValues = objectMap( makeAuctioneerParams(defaultParams), @@ -417,7 +420,7 @@ test('discountStep larger than starting rate', async t => { StartingRate: 10100n, DiscountStep: 10500n, }; - /** @type {import('../../src/auction/params.js').AuctionParams} */ + /** @type {AuctionParams} */ // @ts-expect-error ignore missing values for test const paramValues = objectMap( makeAuctioneerParams(defaultParams), @@ -463,7 +466,7 @@ test('start Freq 0', async t => { ...defaultParams, StartFrequency: 0n, }; - /** @type {import('../../src/auction/params.js').AuctionParams} */ + /** @type {AuctionParams} */ // @ts-expect-error ignore missing values for test const paramValues = objectMap( makeAuctioneerParams(defaultParams), @@ -510,7 +513,7 @@ test('delay > freq', async t => { AuctionStartDelay: 40n, StartFrequency: 20n, }; - /** @type {import('../../src/auction/params.js').AuctionParams} */ + /** @type {AuctionParams} */ // @ts-expect-error ignore missing values for test const paramValues = objectMap( makeAuctioneerParams(defaultParams), @@ -558,7 +561,7 @@ test('lockPeriod > freq', async t => { StartFrequency: 3600n, AuctionStartDelay: 500n, }; - /** @type {import('../../src/auction/params.js').AuctionParams} */ + /** @type {AuctionParams} */ // @ts-expect-error ignore missing values for test const paramValues = objectMap( makeAuctioneerParams(defaultParams), @@ -613,7 +616,7 @@ test('duration = freq', async t => { LowestRate: 40n, DiscountStep: 10n, }; - /** @type {import('../../src/auction/params.js').AuctionParams} */ + /** @type {AuctionParams} */ // @ts-expect-error ignore missing values for test const paramValues = objectMap( makeAuctioneerParams(defaultParams), @@ -692,7 +695,7 @@ test('change Schedule', async t => { // start hourly, request 6 steps down every 10 minutes, so duration would be // 1 hour. Instead, cut the auction short. - /** @type {import('../../src/auction/params.js').AuctionParams} */ + /** @type {AuctionParams} */ defaultParams = { ...defaultParams, PriceLockPeriod: lockPeriodT, @@ -704,7 +707,7 @@ test('change Schedule', async t => { DiscountStep: 10n, }; - /** @type {import('../../src/auction/params.js').AuctionParams} */ + /** @type {AuctionParams} */ // @ts-expect-error ignore missing values for test const paramValues = objectMap( makeAuctioneerParams(defaultParams), @@ -885,7 +888,7 @@ test('change Schedule late', async t => { // start hourly, request 6 steps down every 10 minutes, so duration would be // 1 hour. Instead, cut the auction short. - /** @type {import('../../src/auction/params.js').AuctionParams} */ + /** @type {AuctionParams} */ defaultParams = { ...defaultParams, PriceLockPeriod: lockPeriodT, @@ -897,7 +900,7 @@ test('change Schedule late', async t => { DiscountStep: 10n, }; - /** @type {import('../../src/auction/params.js').AuctionParams} */ + /** @type {AuctionParams} */ // @ts-expect-error ignore missing values for test const paramValues = objectMap( makeAuctioneerParams(defaultParams), @@ -1116,7 +1119,7 @@ test('schedule anomalies', async t => { AuctionStartDelay: delay, PriceLockPeriod: lock, }; - /** @type {import('../../src/auction/params.js').AuctionParams} */ + /** @type {AuctionParams} */ // @ts-expect-error ignore missing values for test const paramValues = objectMap( makeAuctioneerParams(defaultParams), diff --git a/packages/internal/src/callback.js b/packages/internal/src/callback.js index cce95b9846d5..2f932cf995c2 100644 --- a/packages/internal/src/callback.js +++ b/packages/internal/src/callback.js @@ -4,6 +4,7 @@ import { isObject, isPassableSymbol } from '@endo/marshal'; import { getInterfaceMethodKeys } from '@endo/patterns'; /** @import { ERef } from '@endo/far' */ +/** @import { Callback, SyncCallback } from './types.js' */ const { Fail, quote: q } = assert; @@ -20,16 +21,6 @@ const ownKeys = * @typedef {(...args: Parameters>) => import('@endo/exo').Farable} MakeAttenuator */ -/** - * @template {(...args: unknown[]) => any} I - * @typedef {import('./types.js').Callback} Callback - */ - -/** - * @template {(...args: unknown[]) => any} I - * @typedef {import('./types.js').SyncCallback} SyncCallback - */ - /** * @param {unknown} key * @returns {key is PropertyKey} FIXME: should be just `PropertyKey` but TS diff --git a/packages/internal/src/lib-chainStorage.js b/packages/internal/src/lib-chainStorage.js index dcf3c421a4a8..2591b1370c07 100644 --- a/packages/internal/src/lib-chainStorage.js +++ b/packages/internal/src/lib-chainStorage.js @@ -132,7 +132,7 @@ export const prepareChainStorageNode = zone => { /** * Create a storage node for a given backing storage interface and path. * - * @param {import('./callback.js').Callback<(message: StorageMessage) => any>} messenger a callback + * @param {import('./types.js').Callback<(message: StorageMessage) => any>} messenger a callback * for sending a storageMessage object to the storage implementation * (cf. golang/cosmos/x/vstorage/vstorage.go) * @param {string} path @@ -147,7 +147,7 @@ export const prepareChainStorageNode = zone => { 'ChainStorageNode', ChainStorageNodeI, /** - * @param {import('./callback.js').Callback<(message: StorageMessage) => any>} messenger + * @param {import('./types.js').Callback<(message: StorageMessage) => any>} messenger * @param {string} path * @param {object} [options] * @param {boolean} [options.sequence] diff --git a/packages/internal/test/test-callback.js b/packages/internal/test/test-callback.js index ca23cec186cf..bc9fd7095e85 100644 --- a/packages/internal/test/test-callback.js +++ b/packages/internal/test/test-callback.js @@ -5,6 +5,8 @@ import { Far } from '@endo/far'; import { makeHeapZone } from '@agoric/base-zone/heap.js'; import * as cb from '../src/callback.js'; +/** @import { Callback, SyncCallback } from '../src/types.js' */ + test('near function callbacks', t => { /** * @param {number} a @@ -14,15 +16,15 @@ test('near function callbacks', t => { */ const f = (a, b, c) => `${a + b}${c}`; - /** @type {import('../src/callback.js').SyncCallback} */ + /** @type {SyncCallback} */ const cb0 = cb.makeSyncFunctionCallback(f); t.deepEqual(cb0, { target: f, bound: [], isSync: true }); - /** @type {import('../src/callback.js').SyncCallback<(b: number, c: string) => string>} */ + /** @type {SyncCallback<(b: number, c: string) => string>} */ const cb1 = cb.makeSyncFunctionCallback(f, 9); t.deepEqual(cb1, { target: f, bound: [9], isSync: true }); - /** @type {import('../src/callback.js').SyncCallback<(c: string) => string>} */ + /** @type {SyncCallback<(c: string) => string>} */ const cb2 = cb.makeSyncFunctionCallback(f, 9, 10); t.deepEqual(cb2, { target: f, bound: [9, 10], isSync: true }); @@ -39,12 +41,11 @@ test('near function callbacks', t => { t.is(cb.callSync(cb1, 10, 'go'), '19go'); t.is(cb.callSync(cb2, 'go'), '19go'); - const cbp2 = - /** @type {import('../src/callback.js').SyncCallback<(...args: unknown[]) => any>} */ ({ - target: Promise.resolve(f), - methodName: undefined, - bound: [9, 10], - }); + const cbp2 = /** @type {SyncCallback<(...args: unknown[]) => any>} */ ({ + target: Promise.resolve(f), + methodName: undefined, + bound: [9, 10], + }); t.throws(() => cb.callSync(cbp2, 'go'), { message: /not a function/ }); }); @@ -72,15 +73,15 @@ test('near method callbacks', t => { }, }; - /** @type {import('../src/callback.js').SyncCallback} */ + /** @type {SyncCallback} */ const cb0 = cb.makeSyncMethodCallback(o, 'm1'); t.deepEqual(cb0, { target: o, methodName: 'm1', bound: [], isSync: true }); - /** @type {import('../src/callback.js').SyncCallback<(b: number, c: string) => string>} */ + /** @type {SyncCallback<(b: number, c: string) => string>} */ const cb1 = cb.makeSyncMethodCallback(o, 'm1', 9); t.deepEqual(cb1, { target: o, methodName: 'm1', bound: [9], isSync: true }); - /** @type {import('../src/callback.js').SyncCallback<(c: string) => string>} */ + /** @type {SyncCallback<(c: string) => string>} */ const cb2 = cb.makeSyncMethodCallback(o, 'm1', 9, 10); t.deepEqual(cb2, { target: o, @@ -98,7 +99,7 @@ test('near method callbacks', t => { isSync: true, }); - /** @type {import('../src/callback.js').SyncCallback<(c: string) => string>} */ + /** @type {SyncCallback<(c: string) => string>} */ const cb4 = cb.makeSyncMethodCallback(o, m2, 9, 10); t.deepEqual(cb4, { target: o, methodName: m2, bound: [9, 10], isSync: true }); @@ -145,7 +146,7 @@ test('far method callbacks', async t => { }, }); - /** @type {import('../src/callback.js').Callback<(c: string) => Promise>} */ + /** @type {Callback<(c: string) => Promise>} */ const cbp2 = cb.makeMethodCallback(Promise.resolve(o), 'm1', 9, 10); t.like(cbp2, { methodName: 'm1', bound: [9, 10] }); t.assert(cbp2.target instanceof Promise); @@ -153,7 +154,7 @@ test('far method callbacks', async t => { t.assert(p2r instanceof Promise); t.is(await p2r, '19go'); - /** @type {import('../src/callback.js').Callback<(c: string) => Promise>} */ + /** @type {Callback<(c: string) => Promise>} */ const cbp3 = cb.makeMethodCallback(Promise.resolve(o), m2, 9, 10); t.like(cbp3, { methodName: m2, bound: [9, 10] }); t.assert(cbp3.target instanceof Promise); @@ -175,7 +176,7 @@ test('far function callbacks', async t => { */ const f = async (a, b, c) => `${a + b}${c}`; - /** @type {import('../src/callback.js').Callback<(c: string) => Promise>} */ + /** @type {Callback<(c: string) => Promise>} */ const cbp2 = cb.makeFunctionCallback(Promise.resolve(f), 9, 10); t.like(cbp2, { bound: [9, 10] }); t.assert(cbp2.target instanceof Promise); diff --git a/packages/network/package.json b/packages/network/package.json index 1381a53719f8..5a773a6f521c 100644 --- a/packages/network/package.json +++ b/packages/network/package.json @@ -68,6 +68,6 @@ "workerThreads": false }, "typeCoverage": { - "atLeast": 89.74 + "atLeast": 89.73 } } diff --git a/packages/network/src/types.js b/packages/network/src/types.js index 82ce4d1672e3..04206a67d5fc 100644 --- a/packages/network/src/types.js +++ b/packages/network/src/types.js @@ -1,14 +1,6 @@ // @ts-check -/** - * @template T - * @typedef {import('@agoric/vow').PromiseVow} PromiseVow - */ - -/** - * @template T - * @typedef {import('@agoric/vow').Remote} Remote - */ +/** @import {PromiseVow, Remote} from '@agoric/vow' */ /** * @template {import('@endo/exo').Methods} M diff --git a/packages/orchestration/package.json b/packages/orchestration/package.json index b54f1b8105c6..f8183833395b 100644 --- a/packages/orchestration/package.json +++ b/packages/orchestration/package.json @@ -80,6 +80,6 @@ "access": "public" }, "typeCoverage": { - "atLeast": 96.96 + "atLeast": 96.39 } } diff --git a/packages/smart-wallet/package.json b/packages/smart-wallet/package.json index 1c968855f6f2..4548fbcdb9bc 100644 --- a/packages/smart-wallet/package.json +++ b/packages/smart-wallet/package.json @@ -18,6 +18,7 @@ "devDependencies": { "@agoric/cosmic-proto": "^0.4.0", "@agoric/swingset-vat": "^0.32.2", + "@agoric/zone": "^0.2.2", "@endo/bundle-source": "^3.2.2", "@endo/captp": "^4.1.1", "@endo/init": "^1.1.1", diff --git a/packages/smart-wallet/src/offerWatcher.js b/packages/smart-wallet/src/offerWatcher.js index 1604c8e47866..2771484abcbb 100644 --- a/packages/smart-wallet/src/offerWatcher.js +++ b/packages/smart-wallet/src/offerWatcher.js @@ -12,18 +12,12 @@ import { deeplyFulfilledObject, objectMap } from '@agoric/internal'; import { UNPUBLISHED_RESULT } from './offers.js'; -/** - * @typedef {import('./offers.js').OfferSpec & { - * error?: string, - * numWantsSatisfied?: number - * result?: unknown | typeof import('./offers.js').UNPUBLISHED_RESULT, - * payouts?: AmountKeywordRecord, - * }} OfferStatus - */ +/** @import {OfferSpec} from "./offers.js" */ +/** @import {PromiseWatcher} from '@agoric/swingset-liveslots' */ /** * @template {any} T - * @typedef {import('@agoric/swingset-liveslots').PromiseWatcher} OfferPromiseWatcher} OfferPromiseWatcher { * * @param {*} walletHelper * @param {*} deposit - * @param {import('./offers.js').OfferSpec} offerSpec + * @param {OfferSpec} offerSpec * @param {string} address * @param {Amount<'set'>} invitationAmount * @param {UserSeat} seatRef diff --git a/packages/smart-wallet/src/offers.js b/packages/smart-wallet/src/offers.js index e892bf2b03ef..6c78021ff9c7 100644 --- a/packages/smart-wallet/src/offers.js +++ b/packages/smart-wallet/src/offers.js @@ -15,7 +15,7 @@ export const UNPUBLISHED_RESULT = 'UNPUBLISHED'; /** - * @typedef {import('./offers.js').OfferSpec & { + * @typedef {OfferSpec & { * error?: string, * numWantsSatisfied?: number * result?: unknown | typeof UNPUBLISHED_RESULT, diff --git a/packages/smart-wallet/src/smartWallet.js b/packages/smart-wallet/src/smartWallet.js index 7a1f73343351..270edb892e0d 100644 --- a/packages/smart-wallet/src/smartWallet.js +++ b/packages/smart-wallet/src/smartWallet.js @@ -906,7 +906,7 @@ export const prepareSmartWallet = (baggage, shared) => { * Find the live payments for the offer and deposit them back in the appropriate purses. * * @param {OfferId} offerId - * @returns {Promise} + * @returns {Promise} */ async tryReclaimingWithdrawnPayments(offerId) { const { facets } = this; @@ -917,8 +917,9 @@ export const prepareSmartWallet = (baggage, shared) => { if (liveOfferPayments.has(offerId)) { const brandPaymentRecord = liveOfferPayments.get(offerId); if (!brandPaymentRecord) { - return; + return []; } + const out = []; // Use allSettled to ensure we attempt all the deposits, regardless of // individual rejections. await Promise.allSettled( @@ -928,10 +929,16 @@ export const prepareSmartWallet = (baggage, shared) => { const purseP = facets.helper.purseForBrand(b); // Now send it back to the purse. - return E(purseP).deposit(p); + return E(purseP) + .deposit(p) + .then(amt => { + out.push(amt); + }); }), ); + return harden(out); } + return []; }, }, @@ -972,22 +979,23 @@ export const prepareSmartWallet = (baggage, shared) => { const invitation = invitationFromSpec(offerSpec.invitationSpec); - const [paymentKeywordRecord, invitationAmount] = await Promise.all([ - proposal?.give && - deeplyFulfilledObject( - facets.payments.withdrawGive(proposal.give, offerSpec.id), - ), - E(invitationIssuer).getAmountOf(invitation), - ]); + const invitationAmount = + await E(invitationIssuer).getAmountOf(invitation); // 2. Begin executing offer // No explicit signal to user that we reached here but if anything above // failed they'd get an 'error' status update. + const withdrawnPayments = + proposal?.give && + (await deeplyFulfilledObject( + facets.payments.withdrawGive(proposal.give, offerSpec.id), + )); + seatRef = await E(zoe).offer( invitation, proposal, - paymentKeywordRecord, + withdrawnPayments, offerSpec.offerArgs, ); facets.helper.logWalletInfo(offerSpec.id, 'seated'); @@ -1051,6 +1059,19 @@ export const prepareSmartWallet = (baggage, shared) => { * @throws if the seat can't be found or E(seatRef).tryExit() fails. */ async tryExitOffer(offerId) { + const { facets } = this; + const amts = await facets.payments + .tryReclaimingWithdrawnPayments(offerId) + .catch(e => { + facets.helper.logWalletError( + 'recovery failed reclaiming payments', + e, + ); + return []; + }); + if (amts.length > 0) { + facets.helper.logWalletInfo('reclaimed', amts, 'from', offerId); + } const seatRef = this.state.liveOfferSeats.get(offerId); await E(seatRef).tryExit(); }, diff --git a/packages/smart-wallet/test/test-invitation1.js b/packages/smart-wallet/test/test-invitation1.js new file mode 100644 index 000000000000..93808a1154a5 --- /dev/null +++ b/packages/smart-wallet/test/test-invitation1.js @@ -0,0 +1,251 @@ +// @ts-check +/* global setTimeout */ +import { test as anyTest } from '@agoric/zoe/tools/prepare-test-env-ava.js'; +import { createRequire } from 'module'; +import { E, Far } from '@endo/far'; +import { makeScalarMapStore } from '@agoric/store'; +import { makeDurableZone } from '@agoric/zone/durable.js'; +import { makeNameHubKit, makePromiseSpace } from '@agoric/vats'; +import { makeFakeVatAdmin } from '@agoric/zoe/tools/fakeVatAdmin.js'; +import { makeZoeKitForTest } from '@agoric/zoe/tools/setup-zoe.js'; +import { makeWellKnownSpaces } from '@agoric/vats/src/core/utils.js'; +import { makeMockChainStorageRoot } from '@agoric/internal/src/storage-test-utils.js'; +import { makeFakeBoard } from '@agoric/vats/tools/board-utils.js'; +import { allValues } from '@agoric/internal'; +import { AmountMath, makeIssuerKit } from '@agoric/ertp'; +import { makeNodeBundleCache } from '@endo/bundle-source/cache.js'; +import { eventLoopIteration } from '@agoric/internal/src/testing-utils.js'; +import { prepareSmartWallet } from '../src/smartWallet.js'; + +/** @type {import('ava').TestFn>>} */ +const test = anyTest; + +const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); + +const nodeRequire = createRequire(import.meta.url); +const asset = { + anyContract: nodeRequire.resolve( + '@agoric/zoe/src/contracts/automaticRefund.js', + ), +}; + +const mockBootstrapPowers = async ( + log, + spaceNames = ['installation', 'instance', 'issuer', 'brand'], +) => { + /** @type {import('@agoric/vat-data').Baggage} */ + const baggage = makeScalarMapStore('bootstrap'); + const zone = makeDurableZone(baggage); + const { produce, consume } = makePromiseSpace(); + + const { admin, vatAdminState } = makeFakeVatAdmin(); + const { zoeService: zoe } = makeZoeKitForTest(admin); + produce.zoe.resolve(zoe); + + const { nameHub: agoricNames, nameAdmin: agoricNamesAdmin } = + makeNameHubKit(); + produce.agoricNames.resolve(agoricNames); + + const spaces = await makeWellKnownSpaces(agoricNamesAdmin, log, spaceNames); + + const invitationIssuer = await E(zoe).getInvitationIssuer(); + const invitationBrand = await E(invitationIssuer).getBrand(); + spaces.brand.produce.Invitation.resolve(invitationBrand); + spaces.issuer.produce.Invitation.resolve(invitationIssuer); + + const chainStorage = makeMockChainStorageRoot(); + produce.chainStorage.resolve(chainStorage); + + const board = makeFakeBoard(); + produce.board.resolve(board); + + /** @type {BootstrapPowers} */ + // @ts-expect-error mock + const powers = { produce, consume, ...spaces, zone }; + const shared = {}; + + return { powers, vatAdminState, chainStorage, shared }; +}; + +const makeTestContext = async t => { + const bootKit = await mockBootstrapPowers(t.log); + const bundleCache = await makeNodeBundleCache('bundles/', {}, s => import(s)); + + const { agoricNames, board, zoe } = bootKit.powers.consume; + const startAnyContract = async () => { + const bundle = await bundleCache.load(asset.anyContract, 'automaticRefund'); + /** @type {Promise>} */ + const installation = E(zoe).install(bundle); + return E(zoe).startInstance(installation); + }; + const { instance: anyInstance } = await startAnyContract(); + + const makeSpendableAsset = () => { + const tok1 = makeIssuerKit('Tok1'); + const { issuer, brand } = bootKit.powers; + // @ts-expect-error new symbol + issuer.produce.Token1.resolve(tok1.issuer); + // @ts-expect-error new symbol + brand.produce.Token1.resolve(tok1.brand); + return tok1; + }; + const spendable = makeSpendableAsset(); + + const makeRegistry = async () => { + /** @type {[string, Brand][]} */ + const be = await E(E(agoricNames).lookup('brand')).entries(); + /** @type {[string, Issuer][]} */ + const ie = await E(E(agoricNames).lookup('issuer')).entries(); + const byName = Object.fromEntries(ie); + const descriptors = await Promise.all( + be.map(([name, b]) => { + /** @type {Promise} */ + const d = allValues({ + brand: b, + displayInfo: E(b).getDisplayInfo(), + issuer: byName[name], + petname: name, + }); + return d; + }), + ); + /** @type {MapStore} */ + const store = makeScalarMapStore('registry'); + store.addAll(harden(descriptors.map(d => [d.brand, d]))); + return store; + }; + /** @type {import('../src/smartWallet.js').BrandDescriptorRegistry} */ + const registry = await makeRegistry(); + + /** @type {import('@agoric/vat-data').Baggage} */ + const swBaggage = makeScalarMapStore('smart-wallet'); + + const secretWalletFactoryKey = Far('Key', {}); + + const { brand: brandSpace, issuer: issuerSpace } = bootKit.powers; + /** @type {Issuer<'set'>} */ + // @ts-expect-error cast + const invitationIssuer = await issuerSpace.consume.Invitation; + /** @type {Brand<'set'>} */ + // @ts-expect-error cast + const invitationBrand = await brandSpace.consume.Invitation; + const invitationDisplayInfo = await E(invitationBrand).getDisplayInfo(); + const publicMarshaller = await E(board).getPublishingMarshaller(); + const makeSmartWallet = prepareSmartWallet(swBaggage, { + agoricNames, + invitationBrand, + invitationDisplayInfo, + invitationIssuer, + publicMarshaller, + zoe, + secretWalletFactoryKey, + registry, + }); + + return { ...bootKit, makeSmartWallet, anyInstance, spendable }; +}; + +test.before(async t => (t.context = await makeTestContext(t))); + +test.serial('handle failure to create invitation', async t => { + const { powers, makeSmartWallet, spendable, shared } = t.context; + const { chainStorage, board } = powers.consume; + /** @type {Issuer<'set'>} */ + // @ts-expect-error cast + const invitationIssuer = powers.issuer.consume.Invitation; + const address = 'agoric1234'; + + // @ts-expect-error Test setup ensures that chainStorage resolution is not undefined. (see #8247) + const walletsStorage = E(chainStorage).makeChildNode('wallet'); + const walletStorageNode = await E(walletsStorage).makeChildNode(address); + + const invitationPurse = await E(invitationIssuer).makeEmptyPurse(); + + /** @type {() => import('@agoric/vats/src/vat-bank.js').Bank} */ + const makeBank = () => + Far('Bank', { + getPurse: async brand => { + assert(brand === spendable.brand); + if (shared.thePurse) return shared.thePurse; + + const purse = await E(spendable.issuer).makeEmptyPurse(); + const amt = AmountMath.make(spendable.brand, 100n); + const pmt = await E(spendable.mint).mintPayment(amt); + await E(purse).deposit(pmt); + const slowWithdrawPurse = { + ...purse, + withdraw: async a => { + await delay(100); + console.log('@@slow withdraw', a); + return E(purse).withdraw(a); + }, + getCurrentAmount: () => purse.getCurrentAmount(), + }; + return slowWithdrawPurse; + }, + getAssetSubscription: () => { + throw new Error('TODO'); + }, + }); + + const theBank = makeBank(); + shared.thePurse = await theBank.getPurse(spendable.brand); + + const smartWallet = await makeSmartWallet({ + address, + walletStorageNode, + bank: theBank, + invitationPurse, + }); + shared.theWallet = smartWallet; + + const { anyInstance } = t.context; + const In = AmountMath.make(spendable.brand, 5n); + + /** @type {import('../src/smartWallet.js').BridgeAction} */ + const spec1 = { + method: 'executeOffer', + offer: { + id: 1, + invitationSpec: { + source: 'contract', + instance: anyInstance, + publicInvitationMaker: 'noSuchMethod', + }, + proposal: { + give: { In }, + }, + }, + }; + + const publicMarshaller = await E(board).getPublishingMarshaller(); + const actionCapData = await E(publicMarshaller).toCapData(spec1); + await t.throwsAsync(E(smartWallet).handleBridgeAction(actionCapData, true)); + await delay(200); +}); + +test.serial('funds should be back in the purse', async t => { + t.like(t.context.shared.thePurse.getCurrentAmount(), { value: 100n }); +}); + +test.serial('recover withdrawn payments', async t => { + const { powers, shared } = t.context; + const { thePurse, theWallet } = shared; + + /** @type {import('../src/smartWallet.js').BridgeAction} */ + const spec1 = { + method: 'tryExitOffer', + offerId: 1, + }; + + const { board } = powers.consume; + const publicMarshaller = await E(board).getPublishingMarshaller(); + + const actionCapData = await E(publicMarshaller).toCapData(spec1); + await t.throwsAsync(E(theWallet).handleBridgeAction(actionCapData, true), { + message: /key 1 not found in collection "live offer seats"/, + }); + await eventLoopIteration(); + await delay(10); + t.like(thePurse.getCurrentAmount(), { value: 100n }); +}); diff --git a/packages/store/package.json b/packages/store/package.json index 2af60428d5fe..56f10b4e2ddf 100644 --- a/packages/store/package.json +++ b/packages/store/package.json @@ -58,6 +58,6 @@ "timeout": "2m" }, "typeCoverage": { - "atLeast": 86.12 + "atLeast": 86.34 } } diff --git a/packages/swingset-liveslots/package.json b/packages/swingset-liveslots/package.json index 9d5141ecb79d..655192ee75e5 100644 --- a/packages/swingset-liveslots/package.json +++ b/packages/swingset-liveslots/package.json @@ -67,6 +67,6 @@ "access": "public" }, "typeCoverage": { - "atLeast": 75.24 + "atLeast": 75.29 } } diff --git a/packages/swingset-liveslots/test/waitUntilQuiescent.js b/packages/swingset-liveslots/test/waitUntilQuiescent.js index 3144860f6831..1f36df969db0 100644 --- a/packages/swingset-liveslots/test/waitUntilQuiescent.js +++ b/packages/swingset-liveslots/test/waitUntilQuiescent.js @@ -1,6 +1,7 @@ /* global setImmediate */ import { makePromiseKit } from '@endo/promise-kit'; -/** @template T @typedef {import('@endo/promise-kit').PromiseKit} PromiseKit */ + +/** @import {PromiseKit} from '@endo/promise-kit' */ // This can only be imported from the Start Compartment, where 'setImmediate' // is available. diff --git a/packages/vat-data/src/index.js b/packages/vat-data/src/index.js index eed5c1270601..3bce4c80258d 100644 --- a/packages/vat-data/src/index.js +++ b/packages/vat-data/src/index.js @@ -42,8 +42,8 @@ export { prepareSingleton, } from './exo-utils.js'; +// TODO re-export these /** @template T @typedef {import('@agoric/swingset-liveslots').DefineKindOptions} DefineKindOptions */ - // Copy this type because aliasing it by `import('@agoric/swingset-liveslots').Baggage` // causes this error in typedoc: Expected a symbol for node with kind Identifier /** @typedef {MapStore} Baggage */ diff --git a/packages/vats/package.json b/packages/vats/package.json index a04ac9ccfee2..8e98264c021a 100644 --- a/packages/vats/package.json +++ b/packages/vats/package.json @@ -76,6 +76,6 @@ "workerThreads": false }, "typeCoverage": { - "atLeast": 89.58 + "atLeast": 91.5 } } diff --git a/packages/vats/src/ibc.js b/packages/vats/src/ibc.js index f9db428c58f0..a48718bc8cc2 100644 --- a/packages/vats/src/ibc.js +++ b/packages/vats/src/ibc.js @@ -7,6 +7,14 @@ import { dataToBase64, base64ToBytes } from '@agoric/network'; import '@agoric/store/exported.js'; import '@agoric/network/exported.js'; +import { + localAddrToPortID, + decodeRemoteIbcAddress, + encodeLocalIbcAddress, + encodeRemoteIbcAddress, +} from '../tools/ibc-utils.js'; + +/** @import {LocalIbcAddress, RemoteIbcAddress} from '../tools/ibc-utils.js' */ // CAVEAT: IBC acks cannot be empty, as the Cosmos IAVL tree cannot represent // empty acknowledgements as distinct from unacknowledged packets. @@ -16,14 +24,14 @@ const DEFAULT_ACKNOWLEDGEMENT = '\x00'; const DEFAULT_PACKET_TIMEOUT_NS = 60n * 60n * 1_000_000_000n; /** - * @import {BridgeHandler, ScopedBridgeManager, ConnectingInfo, IBCChannelID, IBCChannelOrdering, IBCEvent, IBCPacket, IBCPortID, IBCDowncall, IBCDowncallPacket, IBCDowncallMethod} from './types.js'; + * @import {BridgeHandler, ScopedBridgeManager, ConnectingInfo, IBCChannelID, IBCChannelOrdering, IBCEvent, IBCPacket, IBCPortID, IBCDowncallPacket, IBCDowncallMethod, IBCDowncall, IBCBridgeEvent} from './types.js'; * @import {Zone} from '@agoric/base-zone'; * @import {Remote, VowKit, VowResolver, VowTools} from '@agoric/vow'; */ +/** @typedef {VowKit} OnConnectP */ + /** - * @typedef {VowKit} OnConnectP - * * @typedef {Omit< * ConnectingInfo, * 'counterparty' | 'channelID' | 'counterpartyVersion' @@ -47,6 +55,26 @@ export const prepareIBCConnectionHandler = zone => { const makeIBCConnectionHandler = zone.exoClass( 'IBCConnectionHandler', undefined, + /** + * @param {{ + * protocolUtils: any; + * channelKeyToConnP: MapStore< + * string, + * import('@agoric/vow').Remote + * >; + * channelKeyToSeqAck: MapStore< + * string, + * MapStore> + * >; + * }} param0 + * @param {{ + * channelID: IBCChannelID; + * portID: string; + * rChannelID: IBCChannelID; + * rPortID: string; + * order: 'ORDERED' | 'UNORDERED'; + * }} param1 + */ ( { protocolUtils, channelKeyToConnP, channelKeyToSeqAck }, { channelID, portID, rChannelID, rPortID, order }, @@ -67,6 +95,7 @@ export const prepareIBCConnectionHandler = zone => { }; }, { + /** @type {Required['onOpen']} */ async onOpen(conn, localAddr, remoteAddr, _handler) { const { channelID, portID, channelKeyToConnP } = this.state; @@ -81,14 +110,7 @@ export const prepareIBCConnectionHandler = zone => { channelKeyToConnP.init(channelKey, conn); }, - /** - * @param {Connection} _conn - * @param {Bytes} packetBytes - * @param {ConnectionHandler} _handler - * @param {object} root0 - * @param {bigint} [root0.relativeTimeoutNs] - * @returns {PromiseVow} Acknowledgement data - */ + /** @type {Required['onReceive']} */ async onReceive( _conn, packetBytes, @@ -108,7 +130,8 @@ export const prepareIBCConnectionHandler = zone => { }; return protocolUtils.ibcSendPacket(packet, relativeTimeoutNs); }, - async onClose(_conn, _reason, _handler) { + /** @type {Required['onClose']} */ + async onClose() { const { portID, channelID } = this.state; const { protocolUtils, channelKeyToSeqAck } = this.state; @@ -166,12 +189,11 @@ export const prepareIBCProtocol = (zone, powers) => { /** * Create a handler for the IBC protocol, both from the network and from the * bridge. - * - * @param {IBCDevice} ibcdev */ const makeIBCProtocolKit = zone.exoClassKit( 'IBCProtocolHandler', undefined, + /** @param {IBCDevice} ibcdev */ ibcdev => { /** @type {MapStore>} */ const channelKeyToConnP = detached.mapStore('channelKeyToConnP'); @@ -206,73 +228,46 @@ export const prepareIBCProtocol = (zone, powers) => { }, { protocolHandler: { - async onCreate(impl, _protocolHandler) { + /** @type {Required['onCreate']} */ + async onCreate(impl) { console.debug('IBC onCreate'); this.state.protocolImpl = impl; }, + /** @type {Required['onInstantiate']} */ async onInstantiate() { // The IBC channel is not known until after handshake. return ''; }, - async generatePortID(_localAddr, _protocolHandler) { + /** @type {Required['generatePortID']} */ + async generatePortID() { this.state.lastPortID += 1n; return `port-${this.state.lastPortID}`; }, - async onBind(port, localAddr, _protocolHandler) { + /** @type {Required['onBind']} */ + async onBind(_port, localAddr) { const { util } = this.facets; const { portToPendingConns } = this.state; - const portID = util.localAddrToPortID(localAddr); + // @ts-expect-error may not be LocalIbcAddress + const portID = localAddrToPortID(localAddr); portToPendingConns.init(portID, detached.setStore('pendingConns')); const packet = { source_port: portID, }; return util.downcall('bindPort', { packet }); }, - async onConnect( - port, - localAddr, - remoteAddr, - _chandler, - _protocolHandler, - ) { + /** @type {Required['onConnect']} */ + async onConnect(_port, localAddr, remoteAddr) { const { util } = this.facets; const { portToPendingConns, srcPortToOutbounds } = this.state; console.debug('IBC onConnect', localAddr, remoteAddr); - const portID = util.localAddrToPortID(localAddr); + // @ts-expect-error may not be LocalIbcAddress + const portID = localAddrToPortID(localAddr); const pendingConns = portToPendingConns.get(portID); - const match = remoteAddr.match( - /^(\/ibc-hop\/[^/]+)*\/ibc-port\/([^/]+)\/(ordered|unordered)\/([^/]+)$/s, - ); - if (!match) { - throw TypeError( - `Remote address ${remoteAddr} must be '(/ibc-hop/CONNECTION)*/ibc-port/PORT/(ordered|unordered)/VERSION'`, - ); - } - - const hops = []; - let h = match[1]; - while (h) { - const m = h.match(/^\/ibc-hop\/([^/]+)/); - if (!m) { - throw Error( - `internal: ${JSON.stringify( - h, - )} did not begin with "/ibc-hop/XXX"`, - ); - } - h = h.substr(m[0].length); - hops.push(m[1]); - } - - // Generate a circuit. - /** @type {IBCPortID} */ - const rPortID = match[2]; - /** @type {IBCChannelOrdering} */ - const order = match[3] === 'ordered' ? 'ORDERED' : 'UNORDERED'; - const version = match[4]; + const { rPortID, hops, order, version } = + decodeRemoteIbcAddress(remoteAddr); const kit = makeVowKit(); @@ -310,18 +305,20 @@ export const prepareIBCProtocol = (zone, powers) => { return kit.vow; }, - async onListen(_port, localAddr, _listenHandler) { + /** @type {Required['onListen']} */ + async onListen(_port, localAddr) { console.debug('IBC onListen', localAddr); }, - async onListenRemove(_port, localAddr, _listenHandler) { + /** @type {Required['onListenRemove']} */ + async onListenRemove(_port, localAddr) { console.debug('IBC onListenRemove', localAddr); }, - async onRevoke(_port, localAddr, _protocolHandler) { - const { util } = this.facets; + /** @type {Required['onRevoke']} */ + async onRevoke(_port, localAddr) { const { portToPendingConns } = this.state; - console.debug('IBC onRevoke', localAddr); - const portID = util.localAddrToPortID(localAddr); + // @ts-expect-error may not be LocalIbcAddress + const portID = localAddrToPortID(localAddr); const pendingConns = portToPendingConns.get(portID); portToPendingConns.delete(portID); @@ -332,6 +329,7 @@ export const prepareIBCProtocol = (zone, powers) => { }, }, bridgeHandler: { + /** @param {IBCEvent} obj */ async fromBridge(obj) { const { protocolImpl, @@ -348,7 +346,6 @@ export const prepareIBCProtocol = (zone, powers) => { await null; switch (obj.event) { case 'channelOpenInit': { - /** @type {IBCEvent<'channelOpenInit'>} */ const { channelID, portID, @@ -357,7 +354,7 @@ export const prepareIBCProtocol = (zone, powers) => { order, version, asyncVersions, - } = obj; + } = /** @type {IBCEvent<'channelOpenInit'>} */ (obj); if (!asyncVersions) { // Synchronous versions have already been negotiated. break; @@ -381,7 +378,6 @@ export const prepareIBCProtocol = (zone, powers) => { } case 'channelOpenTry': { // They're (more or less politely) asking if we are listening, so make an attempt. - /** @type {IBCEvent<'channelOpenTry'>} */ const { portID, counterparty: { port_id: rPortID, channel_id: rChannelID }, @@ -389,11 +385,16 @@ export const prepareIBCProtocol = (zone, powers) => { order, version, counterpartyVersion: rVersion, - } = obj; + } = /** @type {IBCEvent<'channelOpenTry'>} */ (obj); - const localAddr = `/ibc-port/${portID}/${order.toLowerCase()}/${version}`; - const ibcHops = hops.map(hop => `/ibc-hop/${hop}`).join('/'); - const remoteAddr = `${ibcHops}/ibc-port/${rPortID}/${order.toLowerCase()}/${rVersion}/ibc-channel/${rChannelID}`; + const localAddr = encodeLocalIbcAddress(portID, order, version); + const remoteAddr = encodeRemoteIbcAddress( + hops, + rPortID, + order, + rVersion, + rChannelID, + ); // See if we allow an inbound attempt for this address pair (without // rejecting). @@ -420,14 +421,14 @@ export const prepareIBCProtocol = (zone, powers) => { case 'channelOpenAck': { // Complete the pending outbound connection. - /** @type {IBCEvent<'channelOpenAck'>} */ const { portID, channelID, counterparty: { port_id: rPortID, channel_id: rChannelID }, counterpartyVersion: rVersion, connectionHops: rHops, - } = obj; + } = /** @type {IBCEvent<'channelOpenAck'>} */ (obj); + const outbounds = this.state.srcPortToOutbounds.has(portID) ? [...this.state.srcPortToOutbounds.get(portID)] : []; @@ -460,8 +461,13 @@ export const prepareIBCProtocol = (zone, powers) => { } // Finish the outbound connection. - const ibcHops = rHops.map(hop => `/ibc-hop/${hop}`).join('/'); - const remoteAddress = `${ibcHops}/ibc-port/${rPortID}/${chanInfo.order.toLowerCase()}/${rVersion}/ibc-channel/${rChannelID}`; + const remoteAddress = encodeRemoteIbcAddress( + rHops, + rPortID, + chanInfo.order, + rVersion, + rChannelID, + ); const localAddress = `${localAddr}/${chanInfo.order.toLowerCase()}/${rVersion}/ibc-channel/${channelID}`; const rchandler = makeIBCConnectionHandler( { @@ -486,8 +492,9 @@ export const prepareIBCProtocol = (zone, powers) => { } case 'channelOpenConfirm': { - /** @type {IBCEvent<'channelOpenConfirm'>} */ - const { portID, channelID } = obj; + const { portID, channelID } = + /** @type {IBCEvent<'channelOpenConfirm'>} */ (obj); + const channelKey = `${channelID}:${portID}`; channelKeyToAttempt.has(channelKey) || Fail`${channelKey}: did not expect channelOpenConfirm`; @@ -525,8 +532,7 @@ export const prepareIBCProtocol = (zone, powers) => { } case 'receivePacket': { - /** @type {IBCEvent<'receivePacket'>} */ - const { packet } = obj; + const { packet } = /** @type {IBCEvent<'receivePacket'>} */ (obj); const { data: data64, destination_port: portID, @@ -542,26 +548,30 @@ export const prepareIBCProtocol = (zone, powers) => { } case 'acknowledgementPacket': { - /** @type {IBCEvent<'acknowledgementPacket'>} */ - const { packet, acknowledgement } = obj; + const { packet, acknowledgement } = + /** @type {IBCEvent<'acknowledgementPacket'>} */ (obj); const { sequence, source_channel: channelID, source_port: portID, } = packet; + if (sequence === undefined) + throw TypeError('acknowledgementPacket without sequence'); const ackKit = util.findAckKit(channelID, portID, sequence); ackKit.resolver.resolve(base64ToBytes(acknowledgement)); break; } case 'timeoutPacket': { - /** @type {IBCEvent<'timeoutPacket'>} */ - const { packet } = obj; + const { packet } = /** @type {IBCEvent<'timeoutPacket'>} */ (obj); const { sequence, source_channel: channelID, source_port: portID, } = packet; + if (sequence === undefined) + throw TypeError('timeoutPacket without sequence'); + const ackKit = util.findAckKit(channelID, portID, sequence); ackKit.resolver.reject(Error(`Packet timed out`)); break; @@ -569,7 +579,9 @@ export const prepareIBCProtocol = (zone, powers) => { case 'channelCloseInit': case 'channelCloseConfirm': { - const { portID, channelID } = obj; + const { portID, channelID } = + // could be either but that complicates line wrapping + /** @type {IBCEvent<'channelCloseInit'>} */ (obj); const channelKey = `${channelID}:${portID}`; if (channelKeyToConnP.has(channelKey)) { const conn = channelKeyToConnP.get(channelKey); @@ -580,8 +592,8 @@ export const prepareIBCProtocol = (zone, powers) => { } case 'sendPacket': { - /** @type {IBCEvent<'sendPacket'>} */ - const { packet, relativeTimeoutNs } = obj; + const { packet, relativeTimeoutNs } = + /** @type {IBCEvent<'sendPacket'>} */ (obj); util.ibcSendPacket(packet, relativeTimeoutNs).then( ack => console.info('Manual packet', packet, 'acked:', ack), e => console.warn('Manual packet', packet, 'failed:', e), @@ -633,17 +645,12 @@ export const prepareIBCProtocol = (zone, powers) => { const { vow } = util.findAckKit(channelID, portID, sequence); return vow; }, - /** @param {string} localAddr */ - localAddrToPortID(localAddr) { - const m = localAddr.match(/^\/ibc-port\/([-a-zA-Z0-9._+#[\]<>]+)$/); - if (!m) { - throw TypeError( - `Invalid port specification ${localAddr}; expected "/ibc-port/PORT"`, - ); - } - return m[1]; - }, + /** + * @param {IBCChannelID} channelID + * @param {IBCPortID} portID + * @param {number} sequence + */ findAckKit(channelID, portID, sequence) { const { channelKeyToSeqAck } = this.state; const channelKey = `${channelID}:${portID}`; @@ -657,6 +664,10 @@ export const prepareIBCProtocol = (zone, powers) => { }, }, ackWatcher: { + /** + * @param {string} ack + * @param {{ packet: any }} watcherContext + */ onFulfilled(ack, watcherContext) { const { packet } = watcherContext; @@ -674,6 +685,21 @@ export const prepareIBCProtocol = (zone, powers) => { }, }, protocolImplAttemptWatcher: { + /** + * @param {string} attemptedLocal + * @param {{ + * channelID: IBCChannelID; + * portID: string; + * attempt: any; + * obj: any; + * asyncVersions: any; + * rPortID: string; + * rChannelID: IBCChannelID; + * order: IBCChannelOrdering; + * hops: any; + * version: string; + * }} watcherContext + */ onFulfilled(attemptedLocal, watcherContext) { const { channelID, @@ -736,6 +762,10 @@ export const prepareIBCProtocol = (zone, powers) => { }, }, protocolImplInboundWatcher: { + /** + * @param {any} attempt + * @param {Record} watchContext + */ onFulfilled(attempt, watchContext) { const { obj } = watchContext; @@ -754,11 +784,13 @@ export const prepareIBCProtocol = (zone, powers) => { }, ); + /** @param {IBCDevice} ibcdev */ const makeIBCProtocolHandlerKit = ibcdev => { const { protocolHandler, bridgeHandler } = makeIBCProtocolKit(ibcdev); return harden({ protocolHandler, bridgeHandler }); }; + /** @param {IBCDevice} ibcdev */ const provideIBCProtocolHandlerKit = ibcdev => { if (ibcdevToKit.has(ibcdev)) { return ibcdevToKit.get(ibcdev); @@ -769,7 +801,6 @@ export const prepareIBCProtocol = (zone, powers) => { }; return provideIBCProtocolHandlerKit; }; - harden(prepareIBCProtocol); /** @param {Zone} zone */ @@ -780,6 +811,10 @@ export const prepareCallbacks = zone => { /** @param {ScopedBridgeManager} dibcBridgeManager */ dibcBridgeManager => ({ dibcBridgeManager }), { + /** + * @param {string} method + * @param {any} obj + */ downcall(method, obj) { const { dibcBridgeManager } = this.state; return E(dibcBridgeManager).toBridge({ diff --git a/packages/vats/src/proposals/probeZcfBundle.js b/packages/vats/src/proposals/probeZcfBundle.js index ee44affb2c67..e2a853b4516a 100644 --- a/packages/vats/src/proposals/probeZcfBundle.js +++ b/packages/vats/src/proposals/probeZcfBundle.js @@ -48,7 +48,9 @@ export const probeZcfBundleCap = async ( await E(adminNode).upgrade(zoeBundleCap, {}); // STEP 4: restart WF //////////////////////// - await E(walletAdminFacet).restartContract(privateArgs); + // Need to use `upgradeContract` instead of `restartContract` + // See https://github.com/Agoric/agoric-sdk/issues/9249 + await E(walletAdminFacet).upgradeContract(walletRef.bundleID, privateArgs); // ////// See which zcf bundle was used ////////// }; diff --git a/packages/vats/src/proposals/zcf-only-proposal.js b/packages/vats/src/proposals/zcf-only-proposal.js new file mode 100644 index 000000000000..85d3fd1a569b --- /dev/null +++ b/packages/vats/src/proposals/zcf-only-proposal.js @@ -0,0 +1,36 @@ +// @ts-check +import { E } from '@endo/far'; + +/** + * @param {BootstrapPowers} powers + * @param {object} options + * @param {{ zcfRef: VatSourceRef }} options.options + */ +export const upgradeZcfOnly = async ({ consume: { vatStore } }, options) => { + const { zcfRef } = options.options; + + const { root: zoeRoot } = await E(vatStore).get('zoe'); + + const zoeConfigFacet = await E(zoeRoot).getZoeConfigFacet(); + await E(zoeConfigFacet).updateZcfBundleId(zcfRef.bundleID); + console.log(`ZCF BUNDLE ID: `, zcfRef.bundleID); +}; +harden(upgradeZcfOnly); + +// main and permit are for use with rollup-plugin-core-eval.js +export const main = upgradeZcfOnly; + +export const permit = { + consume: { + vatStore: true, + }, +}; + +export const manifest = { + [upgradeZcfOnly.name]: permit, +}; + +export const getManifestForUpgradingZcf = (_powers, options) => ({ + manifest, + options, +}); diff --git a/packages/vats/src/types.d.ts b/packages/vats/src/types.d.ts index c036ce8f1181..1f33d7c65c22 100644 --- a/packages/vats/src/types.d.ts +++ b/packages/vats/src/types.d.ts @@ -167,8 +167,8 @@ type IBCPacketEvents = { timeoutPacket: { packet: IBCPacket; }; - channelCloseInit: {}; // TODO update - channelCloseConfirm: {}; // TODO update + channelCloseInit: ConnectingInfo; // TODO update + channelCloseConfirm: ConnectingInfo; // TODO update sendPacket: { relativeTimeoutNs: bigint; packet: IBCPacket }; }; diff --git a/packages/vats/src/virtual-purse.js b/packages/vats/src/virtual-purse.js index b2876a7e02bf..8f7e1c97fd41 100644 --- a/packages/vats/src/virtual-purse.js +++ b/packages/vats/src/virtual-purse.js @@ -81,10 +81,7 @@ export const makeVirtualPurseKitIKit = ( return { VirtualPurseIKit, VirtualPurseControllerI }; }; -/** - * @template T - * @typedef {import('@endo/far').EOnly} EOnly - */ +/** @import {EOnly} from '@endo/far'; */ /** @typedef {(pmt: Payment, optAmountShape?: Pattern) => Promise} Retain */ /** @typedef {(amt: Amount) => Promise} Redeem */ diff --git a/packages/vats/test/test-ibc-utils.js b/packages/vats/test/test-ibc-utils.js new file mode 100644 index 000000000000..cfd0b538c3cd --- /dev/null +++ b/packages/vats/test/test-ibc-utils.js @@ -0,0 +1,48 @@ +import test from 'ava'; +import { + decodeRemoteIbcAddress, + localAddrToPortID, +} from '../tools/ibc-utils.js'; + +test('decodeRemoteIbcAddress', t => { + /** @type {[string, any][]} */ + const cases = [ + [ + '/ibc-hop/connection-0/ibc-port/icahost/ordered/{"version":"ics27-1","controllerConnectionId":"connection-0","hostConnectionId":"connection-1","address":"","encoding":"proto3","txType":"sdk_multi_msg"}', + { + hops: ['connection-0'], + order: 'ORDERED', + rPortID: 'icahost', + version: + '{"version":"ics27-1","controllerConnectionId":"connection-0","hostConnectionId":"connection-1","address":"","encoding":"proto3","txType":"sdk_multi_msg"}', + }, + ], + ]; + for (const [raw, parsed] of cases) { + t.deepEqual(decodeRemoteIbcAddress(raw), parsed); + } +}); + +test('localAddrToPortID', t => { + /** @type {[import('../tools/ibc-utils.js').LocalIbcAddress, string][]} */ + const good = [['/ibc-port/my-cool-port-name', 'my-cool-port-name']]; + for (const [raw, parsed] of good) { + t.deepEqual(localAddrToPortID(raw), parsed); + } + + /** @type {[import('../tools/ibc-utils.js').LocalIbcAddress, string][]} */ + const bad = [ + [ + '/ibc-port/', + 'Invalid port specification /ibc-port/; expected "/ibc-port/PORT"', + ], + [ + // @ts-expect-error invalid port spec + 'ibc-port', + 'Invalid port specification ibc-port; expected "/ibc-port/PORT"', + ], + ]; + for (const [raw, message] of bad) { + t.throws(() => localAddrToPortID(raw), { message }); + } +}); diff --git a/packages/vats/tools/ibc-utils.js b/packages/vats/tools/ibc-utils.js new file mode 100644 index 000000000000..e925087490c0 --- /dev/null +++ b/packages/vats/tools/ibc-utils.js @@ -0,0 +1,89 @@ +export const REMOTE_ADDR_RE = + /^(?\/ibc-hop\/[^/]+)*\/ibc-port\/(?[^/]+)\/(?ordered|unordered)\/(?[^/]+)$/s; +harden(REMOTE_ADDR_RE); +/** @typedef {`/${string}ibc-port/${string}/${'ordered' | 'unordered'}/${string}`} RemoteIbcAddress */ + +export const LOCAL_ADDR_RE = /^\/ibc-port\/(?[-a-zA-Z0-9._+#[\]<>]+)$/; +/** @typedef {`/ibc-port/${string}`} LocalIbcAddress */ + +/** @param {string} remoteAddr */ +export const decodeRemoteIbcAddress = remoteAddr => { + const match = remoteAddr.match(REMOTE_ADDR_RE); + // .groups is to inform TS https://github.com/microsoft/TypeScript/issues/32098 + if (!(match && match.groups)) { + throw TypeError( + `Remote address ${remoteAddr} must be '(/ibc-hop/CONNECTION)*/ibc-port/PORT/(ordered|unordered)/VERSION'`, + ); + } + + /** @type {import('../src/types.js').IBCConnectionID[]} */ + const hops = []; + + let h = match.groups.hops; + while (h) { + const m = h.match(/^\/ibc-hop\/(?[^/]+)/); + if (!m) { + throw Error( + `internal: ${JSON.stringify(h)} did not begin with "/ibc-hop/XXX"`, + ); + } + h = h.substr(m[0].length); + // @ts-expect-error unchecked cast + hops.push(m.groups.hop); + } + // Generate a circuit. + const { portID: rPortID, version } = match.groups; + /** @type {import('../src/types.js').IBCChannelOrdering} */ + const order = match.groups.order === 'ordered' ? 'ORDERED' : 'UNORDERED'; + return { rPortID, hops, order, version }; +}; +harden(decodeRemoteIbcAddress); + +/** + * @param {LocalIbcAddress} localAddr + * @returns {string} + */ +export const localAddrToPortID = localAddr => { + const m = localAddr.match(LOCAL_ADDR_RE); + // .groups is to inform TS https://github.com/microsoft/TypeScript/issues/32098 + if (!(m && m.groups)) { + throw TypeError( + `Invalid port specification ${localAddr}; expected "/ibc-port/PORT"`, + ); + } + return m.groups.portID; +}; +harden(localAddrToPortID); + +/** + * @param {string[]} hops + * @param {string} rPortID + * @param {'ordered' | 'unordered' | 'ORDERED' | 'UNORDERED'} order + * @param {string} rVersion + * @param {string} rChannelID + * @returns {RemoteIbcAddress} + */ +export const encodeRemoteIbcAddress = ( + hops, + rPortID, + order, + rVersion, + rChannelID, +) => { + const ibcHops = hops.map(hop => `/ibc-hop/${hop}`).join('/'); + return /** @type {RemoteIbcAddress} */ ( + `${ibcHops}/ibc-port/${rPortID}/${order.toLowerCase()}/${rVersion}/ibc-channel/${rChannelID}` + ); +}; +harden(encodeRemoteIbcAddress); + +/** + * @param {string} portID + * @param {'ordered' | 'unordered' | 'ORDERED' | 'UNORDERED'} order + * @param {string} version + */ +export const encodeLocalIbcAddress = (portID, order, version) => { + return `/ibc-port/${portID}/${order.toLowerCase()}/${version}`; +}; + +harden(encodeLocalIbcAddress); diff --git a/packages/vow/src/types.js b/packages/vow/src/types.js index 183d563df015..ad582399cb58 100644 --- a/packages/vow/src/types.js +++ b/packages/vow/src/types.js @@ -113,8 +113,9 @@ export {}; * @template [T=any] * @template [TResult1=T] * @template [TResult2=T] + * @template [C=any] watcher context * @typedef {object} Watcher - * @property {(value: T) => Vow | PromiseVow | TResult1} [onFulfilled] + * @property {(value: T, context?: C) => Vow | PromiseVow | TResult1} [onFulfilled] * @property {(reason: any) => Vow | PromiseVow | TResult2} [onRejected] */ diff --git a/packages/vow/src/watch.js b/packages/vow/src/watch.js index 026fc6884bfa..b28e3c3a005e 100644 --- a/packages/vow/src/watch.js +++ b/packages/vow/src/watch.js @@ -129,12 +129,13 @@ export const prepareWatch = ( ); /** - * @template [T=any] + * @template [T=unknown] * @template [TResult1=T] * @template [TResult2=T] + * @template [C=unknown] watcher context * @param {import('./types.js').ERef>} specimenP * @param {import('./types.js').Watcher} [watcher] - * @param {unknown} [watcherContext] + * @param {C} [watcherContext] */ const watch = (specimenP, watcher, watcherContext) => { /** @type {import('./types.js').VowKit} */ diff --git a/packages/zoe/tools/internal-types.js b/packages/zoe/tools/internal-types.js index ff654d601d60..c2e1e266e06a 100644 --- a/packages/zoe/tools/internal-types.js +++ b/packages/zoe/tools/internal-types.js @@ -1,5 +1,7 @@ // @jessie-check +/** @import {TimerService} from '@agoric/time' */ + /** * @typedef {object} ManualTimerAdmin * @property {(msg?: string) => void | Promise} tick Advance the timer by one tick. @@ -10,5 +12,5 @@ */ /** - * @typedef {import('@agoric/time').TimerService & ManualTimerAdmin} ManualTimer + * @typedef {TimerService & ManualTimerAdmin} ManualTimer */ diff --git a/packages/zone/package.json b/packages/zone/package.json index 9d35a4f28f46..c2b3389c518f 100644 --- a/packages/zone/package.json +++ b/packages/zone/package.json @@ -54,6 +54,6 @@ "workerThreads": false }, "typeCoverage": { - "atLeast": 96.68 + "atLeast": 96.66 } }