diff --git a/a3p-integration/proposals/n:upgrade-next/.gitignore b/a3p-integration/proposals/n:upgrade-next/.gitignore deleted file mode 100644 index 2f3ed03b1691..000000000000 --- a/a3p-integration/proposals/n:upgrade-next/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -# Generated Artifacts to Ignore in CI -add-LEMONS/ -add-OLIVES/ -upgrade-bank/ -upgrade-provisionPool/ -upgrade-orch-core/ -replace-electorate/ -price-feeds/ diff --git a/a3p-integration/proposals/n:upgrade-next/eval.sh b/a3p-integration/proposals/n:upgrade-next/eval.sh deleted file mode 100755 index c44d11c5a351..000000000000 --- a/a3p-integration/proposals/n:upgrade-next/eval.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -# Exit when any command fails -set -uxeo pipefail - -# The upgrade-vaults proposal needs to know the existing vaultDirector -# parameters in order to cleanly upgrade the contract. The governance notifier -# it relies on doesn't give the most recent value if there were no updates to -# the parameters, so we'll do a governance action to reset them to their current -# values so the notifier will work. - -./resetChargingPeriod.js - -cp /usr/src/upgrade-test-scripts/eval_submission.js . -./eval_submission.js diff --git a/a3p-integration/proposals/n:upgrade-next/initial.test.js b/a3p-integration/proposals/n:upgrade-next/initial.test.js index 779b25ed1dd7..e86b4dd9993c 100644 --- a/a3p-integration/proposals/n:upgrade-next/initial.test.js +++ b/a3p-integration/proposals/n:upgrade-next/initial.test.js @@ -8,7 +8,7 @@ const vats = { localchain: { incarnation: 1 }, orchestration: { incarnation: 0 }, transfer: { incarnation: 1 }, - walletFactory: { incarnation: 4 }, + walletFactory: { incarnation: 5 }, zoe: { incarnation: 3 }, }; diff --git a/a3p-integration/proposals/n:upgrade-next/package.json b/a3p-integration/proposals/n:upgrade-next/package.json index e2914aa62535..af2361a9a58e 100644 --- a/a3p-integration/proposals/n:upgrade-next/package.json +++ b/a3p-integration/proposals/n:upgrade-next/package.json @@ -6,23 +6,6 @@ "upgradeInfo": { "coreProposals": [] }, - "sdk-generate": [ - "vats/test-localchain.js localchaintest-submission", - "vats/upgrade-bank.js upgrade-bank", - "vats/upgrade-provisionPool.js upgrade-provisionPool", - "testing/add-LEMONS.js add-LEMONS", - "testing/add-OLIVES.js add-OLIVES", - "inter-protocol/replace-electorate-core.js replace-electorate A3P_INTEGRATION", - "inter-protocol/updatePriceFeeds.js price-feeds A3P_INTEGRATION", - "vats/add-auction.js price-feeds", - "vats/upgradeVaults.js price-feeds", - "inter-protocol/updatePriceFeeds.js submission/main main", - "vats/add-auction.js submission/main", - "vats/upgradeVaults.js submission/main", - "inter-protocol/updatePriceFeeds.js submission/devnet devnet", - "vats/add-auction.js submission/devnet", - "vats/upgradeVaults.js submission/devnet" - ], "type": "Software Upgrade Proposal" }, "type": "module", diff --git a/a3p-integration/proposals/n:upgrade-next/priceFeedUpdate.test.js b/a3p-integration/proposals/n:upgrade-next/priceFeedUpdate.test.js index 5cbacd019add..d0bdaa1b055c 100644 --- a/a3p-integration/proposals/n:upgrade-next/priceFeedUpdate.test.js +++ b/a3p-integration/proposals/n:upgrade-next/priceFeedUpdate.test.js @@ -14,10 +14,12 @@ import { getVaultPrices, getVatDetails, openVault, - pushPrices, - registerOraclesForBrand, USER1ADDR, } from '@agoric/synthetic-chain'; +import { + getPriceFeedRoundId, + verifyPushedPrice, +} from './test-lib/price-feed.js'; import { BID_OFFER_ID } from './agd-tools.js'; @@ -37,12 +39,17 @@ const checkPriceFeedVatsUpdated = async t => { await checkForOracle(t, 'stATOM'); }; -console.log('adding oracle for each brand'); -const oraclesByBrand = generateOracleMap('f-priceFeeds', ['ATOM', 'stATOM']); -await registerOraclesForBrand('ATOM', oraclesByBrand); -await registerOraclesForBrand('stATOM', oraclesByBrand); +/* + * The Oracle for ATOM and stATOM brands are being registered in the offer made at file: + * a3p-integration/proposals/n:upgrade-next/verifyPushedPrice.js + * which is being executed during the use phase of upgrade-next proposal + */ +const oraclesByBrand = generateOracleMap('n-upgrade', ['ATOM', 'stATOM']); -let roundId = 1; +const latestAtomRoundId = await getPriceFeedRoundId('ATOM'); +const latestStAtomRoundId = await getPriceFeedRoundId('stATOM'); +let atomRoundId = latestAtomRoundId + 1; +let stAtomRoundId = latestStAtomRoundId + 1; const tryPushPrices = async t => { // There are no old prices for the other currencies. @@ -52,9 +59,10 @@ const tryPushPrices = async t => { // t.is(stAtomOutPre, '+12010000'); t.log('pushing new prices'); - await pushPrices(13.4, 'ATOM', oraclesByBrand, roundId); - await pushPrices(13.7, 'stATOM', oraclesByBrand, roundId); - roundId += 1; + await verifyPushedPrice(13.4, 'ATOM', oraclesByBrand, atomRoundId); + await verifyPushedPrice(13.7, 'stATOM', oraclesByBrand, stAtomRoundId); + atomRoundId += 1; + stAtomRoundId += 1; t.log('awaiting new quotes'); const atomOut = await getPriceQuote('ATOM'); @@ -89,7 +97,7 @@ const openMarginalVault = async t => { }; const triggerAuction = async t => { - await pushPrices(5.2, 'ATOM', oraclesByBrand, roundId); + await verifyPushedPrice(5.2, 'ATOM', oraclesByBrand, atomRoundId); const atomOut = await getPriceQuote('ATOM'); t.is(atomOut, '+5200000'); diff --git a/a3p-integration/proposals/n:upgrade-next/provisionPool.test.js b/a3p-integration/proposals/n:upgrade-next/provisionPool.test.js deleted file mode 100644 index 6e0bbcca1f1c..000000000000 --- a/a3p-integration/proposals/n:upgrade-next/provisionPool.test.js +++ /dev/null @@ -1,102 +0,0 @@ -// @ts-check - -import test from 'ava'; - -import { - evalBundles, - getIncarnation, - waitForBlock, -} from '@agoric/synthetic-chain'; - -import { bankSend, getProvisionPoolMetrics } from './agd-tools.js'; - -const NULL_UPGRADE_BANK_DIR = 'upgrade-bank'; -const UPGRADE_PP_DIR = 'upgrade-provisionPool'; -const ADD_LEMONS_DIR = 'add-LEMONS'; -const ADD_OLIVES_DIR = 'add-OLIVES'; - -const USDC_DENOM = - 'ibc/295548A78785A1007F232DE286149A6FF512F180AF5657780FC89C009E2C348F'; -const PROVISIONING_POOL_ADDR = 'agoric1megzytg65cyrgzs6fvzxgrcqvwwl7ugpt62346'; - -/** - * @file - * The problem to be addressed is that provisionPool won't correctly handle - * (#8722) deposit of assets after it (provisionPool) is upgraded or (#8724) - * new asset kinds after vat-bank is upgraded. - * - * To test this, we will - * - * 1. See that we can add USDC. - * - * 2. Null upgrade vat-bank, and see that we can add a new collateal. - * - * 2a. Not null upgrade provisionPool, since it would fail. If it had succeeded, - * we would have been able to observe the effect of #8724, which would have - * caused addition of new currencies to be ignored. - * - * 3. Do a full upgrade of provisionPool; then deposit USDC, and see IST - * incremented in totalMintedConverted. - * - * 4. Null upgrade vat-bank again, and then see (in logs) that adding a new - * asset type gives the ability to make deposits. We don't actually add it - * because it would be too much work to add a faucet or other ability to mint - * the new collateral. - */ - -const contributeToPool = async (t, asset, expectedToGrow) => { - const metricsBefore = await getProvisionPoolMetrics(); - console.log('PPT pre', metricsBefore); - - await bankSend(PROVISIONING_POOL_ADDR, asset); - - const metricsAfter = await getProvisionPoolMetrics(); - console.log('PPT post', metricsAfter); - t.is( - metricsAfter.totalMintedConverted.brand, - metricsBefore.totalMintedConverted.brand, - 'brands match', - ); - if (expectedToGrow) { - // I couldn't import AmountMath. dunno why. - t.true( - metricsAfter.totalMintedConverted.value > - metricsBefore.totalMintedConverted.value, - 'brands match', - ); - } else { - t.equal( - metricsAfter.totalMintedConverted.value, - metricsBefore.totalMintedConverted.value, - ); - } -}; - -test('upgrading provisionPool and vat-bank', async t => { - t.log('add assets before'); - await contributeToPool(t, `10000${USDC_DENOM}`, true); - - t.log(`upgrade Bank`); - await evalBundles(NULL_UPGRADE_BANK_DIR); - - const firstIncarnation = await getIncarnation('bank'); - t.is(firstIncarnation, 1); - - await evalBundles(ADD_LEMONS_DIR); - - t.log('full upgrade ProvisionPool'); - await evalBundles(UPGRADE_PP_DIR); - const ppIncarnation = await getIncarnation('db93f-provisionPool'); - t.is(ppIncarnation, 1); - - await contributeToPool(t, `30000${USDC_DENOM}`, true); - - t.log(`Add assets after bank upgrade`); - await evalBundles(NULL_UPGRADE_BANK_DIR); - await waitForBlock(2); - - const secondIncarnation = await getIncarnation('bank'); - t.is(secondIncarnation, 2); - - await evalBundles(ADD_OLIVES_DIR); -}); diff --git a/a3p-integration/proposals/n:upgrade-next/resetChargingPeriod.js b/a3p-integration/proposals/n:upgrade-next/resetChargingPeriod.js deleted file mode 100755 index c77494dddc66..000000000000 --- a/a3p-integration/proposals/n:upgrade-next/resetChargingPeriod.js +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env node - -/* global setTimeout */ - -import { - getQuoteBody, - GOV1ADDR, - GOV2ADDR, - GOV3ADDR, -} from '@agoric/synthetic-chain'; -import { - proposeVaultDirectorParamChange, - voteForNewParams, -} from './agoric-tools.js'; - -const GOV_ADDRESSES = [GOV1ADDR, GOV2ADDR, GOV3ADDR]; - -const readChargingPeriod = async () => { - const governanceBody = await getQuoteBody( - 'published.vaultFactory.governance', - ); - const period = - governanceBody.current.ChargingPeriod.value.match(/\+?(\d+)/)[1]; - return `+${period}`; -}; - -const setChargingPeriod = async period => { - const params = { - ChargingPeriod: period, - }; - - const path = { paramPath: { key: 'governedParams' } }; - - await proposeVaultDirectorParamChange(GOV1ADDR, params, path); - await voteForNewParams(GOV_ADDRESSES, 0); - - await new Promise(r => setTimeout(r, 65000)); -}; - -const period = await readChargingPeriod(); -await setChargingPeriod(period); diff --git a/a3p-integration/proposals/n:upgrade-next/test-lib/price-feed.js b/a3p-integration/proposals/n:upgrade-next/test-lib/price-feed.js new file mode 100644 index 000000000000..c0e2acd311d9 --- /dev/null +++ b/a3p-integration/proposals/n:upgrade-next/test-lib/price-feed.js @@ -0,0 +1,62 @@ +/* eslint-env node */ + +import { + agoric, + getContractInfo, + pushPrices, + getPriceQuote, +} from '@agoric/synthetic-chain'; +import { retryUntilCondition } from './sync-tools.js'; + +export const scale6 = x => BigInt(x * 1_000_000); + +/** + * + * @param {number} price + * @param {string} brand + * @param {Map} oraclesByBrand + * @param {number} roundId + * @returns {Promise} + */ +export const verifyPushedPrice = async ( + price, + brand, + oraclesByBrand, + roundId, +) => { + const pushPriceRetryOpts = { + maxRetries: 5, // arbitrary + retryIntervalMs: 5000, // in ms + }; + + await pushPrices(price, brand, oraclesByBrand, roundId); + console.log(`Pushing price ${price} for ${brand}`); + + await retryUntilCondition( + () => getPriceQuote(brand), + res => res === `+${scale6(price).toString()}`, + 'price not pushed yet', + { + log: console.log, + setTimeout: global.setTimeout, + ...pushPriceRetryOpts, + }, + ); + console.log(`Price ${price} pushed for ${brand}`); +}; + +/** + * + * @param {string} brand + * @returns {Promise} + */ +export const getPriceFeedRoundId = async brand => { + const latestRoundPath = `published.priceFeed.${brand}-USD_price_feed.latestRound`; + const latestRound = await getContractInfo(latestRoundPath, { + agoric, + prefix: '', + }); + + console.log('latestRound: ', latestRound); + return Number(latestRound.roundId); +}; diff --git a/a3p-integration/proposals/n:upgrade-next/test-lib/sync-tools.js b/a3p-integration/proposals/n:upgrade-next/test-lib/sync-tools.js new file mode 100644 index 000000000000..4a0e727c4653 --- /dev/null +++ b/a3p-integration/proposals/n:upgrade-next/test-lib/sync-tools.js @@ -0,0 +1,72 @@ +/* eslint-env node */ + +/** + * @file These tools mostly duplicate code that will be added in other PRs + * and eventually migrated to synthetic-chain. Sorry for the duplication. + */ + +/** + * @typedef {object} RetryOptions + * @property {number} [maxRetries] + * @property {number} [retryIntervalMs] + * @property {(...arg0: string[]) => void} log + * @property {(object) => void} [setTimeout] + * @property {string} [errorMessage=Error] + */ + +const ambientSetTimeout = global.setTimeout; + +/** + * From https://github.com/Agoric/agoric-sdk/blob/442f07c8f0af03281b52b90e90c27131eef6f331/multichain-testing/tools/sleep.ts#L10 + * + * @param {number} ms + * @param {*} sleepOptions + */ +const sleep = (ms, { log = () => {}, setTimeout = ambientSetTimeout }) => + new Promise(resolve => { + log(`Sleeping for ${ms}ms...`); + setTimeout(resolve, ms); + }); + +/** + * From https://github.com/Agoric/agoric-sdk/blob/442f07c8f0af03281b52b90e90c27131eef6f331/multichain-testing/tools/sleep.ts#L24 + * + * @param {() => Promise} operation + * @param {(result: any) => boolean} condition + * @param {string} message + * @param {RetryOptions} options + */ +export const retryUntilCondition = async ( + operation, + condition, + message, + { maxRetries = 6, retryIntervalMs = 3500, log, setTimeout }, +) => { + console.log({ maxRetries, retryIntervalMs, message }); + let retries = 0; + + await null; + while (retries < maxRetries) { + try { + const result = await operation(); + log('RESULT', result); + if (condition(result)) { + return result; + } + } catch (error) { + if (error instanceof Error) { + log(`Error: ${error.message}`); + } else { + log(`Unknown error: ${String(error)}`); + } + } + + retries += 1; + console.log( + `Retry ${retries}/${maxRetries} - Waiting for ${retryIntervalMs}ms for ${message}...`, + ); + await sleep(retryIntervalMs, { log, setTimeout }); + } + + throw Error(`${message} condition failed after ${maxRetries} retries.`); +}; diff --git a/a3p-integration/proposals/n:upgrade-next/test.sh b/a3p-integration/proposals/n:upgrade-next/test.sh index 07c0eb0d035a..a3bc4a2d8450 100755 --- a/a3p-integration/proposals/n:upgrade-next/test.sh +++ b/a3p-integration/proposals/n:upgrade-next/test.sh @@ -6,8 +6,6 @@ # suppress file names from glob that run earlier GLOBIGNORE=initial.test.js -yarn ava ./replaceElectorate.test.js - # test the state right after upgrade yarn ava initial.test.js diff --git a/a3p-integration/proposals/n:upgrade-next/use.sh b/a3p-integration/proposals/n:upgrade-next/use.sh index c68eaeafeccc..18740efb70e8 100644 --- a/a3p-integration/proposals/n:upgrade-next/use.sh +++ b/a3p-integration/proposals/n:upgrade-next/use.sh @@ -4,4 +4,10 @@ set -uxeo pipefail node ./addGov4 + +# Econ Committee accept invitations for Committee and Charter ./acceptInvites.js + +# "oracles" accept their invitations and provide prices to priceFeeds +./verifyPushedPrice.js 'ATOM' 12.01 +./verifyPushedPrice.js 'stATOM' 12.01 diff --git a/a3p-integration/proposals/n:upgrade-next/verifyPushedPrice.js b/a3p-integration/proposals/n:upgrade-next/verifyPushedPrice.js new file mode 100644 index 000000000000..98449c316a58 --- /dev/null +++ b/a3p-integration/proposals/n:upgrade-next/verifyPushedPrice.js @@ -0,0 +1,21 @@ +#!/usr/bin/env node + +import { + registerOraclesForBrand, + generateOracleMap, +} from '@agoric/synthetic-chain'; +import { argv } from 'node:process'; +import { verifyPushedPrice } from './test-lib/price-feed.js'; + +const brand = argv[2]; +const price = Number(argv[3]); + +const BASE_ID = 'n-upgrade'; +const ROUND_ID = 1; + +const oraclesByBrand = generateOracleMap(BASE_ID, [brand]); +await registerOraclesForBrand(brand, oraclesByBrand); +console.log(`Registering Oracle for ${brand}`); + +await verifyPushedPrice(price, brand, oraclesByBrand, ROUND_ID); +console.log(`Price pushed for ${brand}`); diff --git a/a3p-integration/proposals/z:acceptance/.gitignore b/a3p-integration/proposals/z:acceptance/.gitignore index 146ed010dc02..3d143254692d 100644 --- a/a3p-integration/proposals/z:acceptance/.gitignore +++ b/a3p-integration/proposals/z:acceptance/.gitignore @@ -1,3 +1,4 @@ !*submission/ restart-valueVow start-valueVow +localchaintest-submission diff --git a/a3p-integration/proposals/z:acceptance/create-kread-item-test.sh b/a3p-integration/proposals/z:acceptance/create-kread-item-test.sh deleted file mode 100755 index 89b175b73408..000000000000 --- a/a3p-integration/proposals/z:acceptance/create-kread-item-test.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash -set -euo pipefail - -source /usr/src/upgrade-test-scripts/env_setup.sh - -OFFER=$(mktemp -t agops.XXX) -agops vaults open --wantMinted 6.00 --giveCollateral 9.0 >| "$OFFER" -agoric wallet send --offer "$OFFER" --from $GOV1ADDR --keyring-backend="test" - -govamount="200000000ubld" -provisionSmartWallet $GOV1ADDR $govamount - -KREAD_ITEM_OFFER=$(mktemp -t kreadItem.XXX) -node ./generate-kread-item-request.mjs > $KREAD_ITEM_OFFER -agops perf satisfaction --from $GOV1ADDR --executeOffer $KREAD_ITEM_OFFER --keyring-backend=test - -agd query vstorage data published.wallet.$GOV1ADDR.current -o json >&gov1.out -name=$(jq '.value | fromjson | .values[2] | fromjson | .body[1:] | fromjson | .purses[1].balance.value.payload[0][0].name ' gov1.out) -test_val $name \"ephemeral_Ace\" "found KREAd character" diff --git a/a3p-integration/proposals/z:acceptance/generate-kread-item-request.mjs b/a3p-integration/proposals/z:acceptance/generate-kread-item-request.mjs deleted file mode 100644 index 55feaf5f0671..000000000000 --- a/a3p-integration/proposals/z:acceptance/generate-kread-item-request.mjs +++ /dev/null @@ -1,77 +0,0 @@ -/* global process */ -import assert from 'assert'; -import { execFile } from 'child_process'; - -const ISTunit = 1_000_000n; // aka displayInfo: { decimalPlaces: 6 } - -const id = `KREAd-test-${Date.now()}`; - -// poor-man's zx -const $ = cmd => { - const [file, ...args] = cmd.split(' '); - - return new Promise((resolve, reject) => { - execFile(file, args, { encoding: 'utf8' }, (err, out) => { - if (err) return reject(err); - resolve(out); - }); - }); -}; - -const zip = (xs, ys) => xs.map((x, i) => [x, ys[i]]); - -const fromSmallCapsEntries = txt => { - const { body, slots } = JSON.parse(txt); - const theEntries = zip(JSON.parse(body.slice(1)), slots).map( - ([[name, ref], boardID]) => { - const iface = ref.replace(/^\$\d+\./, ''); - return [name, { iface, boardID }]; - }, - ); - return Object.fromEntries(theEntries); -}; - -const brand = fromSmallCapsEntries( - await $('agoric follow -lF :published.agoricNames.brand -o text'), -); -assert(brand.IST); - -const slots = []; // XXX global mutable state - -const smallCaps = { - Nat: n => `+${n}`, - // XXX mutates obj - ref: obj => { - if (obj.ix) return obj.ix; - const ix = slots.length; - slots.push(obj.boardID); - obj.ix = `$${ix}.Alleged: ${obj.iface}`; - return obj.ix; - }, -}; - -const body = { - method: 'executeOffer', - offer: { - id, - invitationSpec: { - source: 'agoricContract', - instancePath: ['kread'], - callPipe: [['makeMintCharacterInvitation', []]], - }, - offerArgs: { name: 'ephemeral_Ace' }, - proposal: { - give: { - Price: { - brand: smallCaps.ref(brand.IST), - value: smallCaps.Nat(5n * ISTunit), - }, - }, - }, - }, -}; - -const capData = { body: `#${JSON.stringify(body)}`, slots }; -const action = JSON.stringify(capData); - -console.log(action); diff --git a/a3p-integration/proposals/z:acceptance/kread.test.js b/a3p-integration/proposals/z:acceptance/kread.test.js new file mode 100644 index 000000000000..b7ed9404f53b --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/kread.test.js @@ -0,0 +1,166 @@ +import test from 'ava'; +import { + provisionSmartWallet, + USER1ADDR as Alice, + GOV1ADDR as Bob, +} from '@agoric/synthetic-chain'; +import { + buyCharacter, + buyItem, + getCharacterInventory, + getMarketCharactersChildren, + getBalanceFromPurse, + getMarketItem, + getMarketItemsChildren, + mintCharacter, + sellCharacter, + sellItem, + unequipAllItems, +} from './test-lib/kread.js'; + +test.serial('Alice mints a new Character', async t => { + await provisionSmartWallet(Alice, '200000000ubld'); + const characterBalanceBefore = await getBalanceFromPurse(Alice, 'character'); + t.is(characterBalanceBefore, null, 'A Character should not exist in purse'); + + await mintCharacter(Alice); + + const characterBalanceAfter = await getBalanceFromPurse(Alice, 'character'); + t.is( + characterBalanceAfter.name, + 'ephemeral_Ace', + 'Minted Character name should be ephemeral_Ace', + ); +}); + +test.serial('Alice unequips all defaults Items', async t => { + const itemBalanceBefore = await getBalanceFromPurse(Alice, 'item'); + t.is(itemBalanceBefore, null, 'An Item should not exist in purse'); + + const characterId = 'ephemeral_Ace'; + const characterInventoryBefore = await getCharacterInventory(characterId); + t.is( + characterInventoryBefore.length, + 3, + 'Character should have 3 items in inventory', + ); + + await unequipAllItems(Alice); + + const characterInventoryAfter = await getCharacterInventory(characterId); + t.is( + characterInventoryAfter.length, + 0, + 'Character should have 0 items in inventory', + ); + + const itemBalanceAfter = await getBalanceFromPurse(Alice, 'item'); + t.is( + itemBalanceAfter.description, + characterInventoryBefore[0][0].description, + 'The unequipped Item should exist in purse', + ); +}); + +test.serial('Alice sells one unequipped Item', async t => { + const itemListBefore = await getMarketItemsChildren(); + const itemBefore = await getBalanceFromPurse(Alice, 'item'); + + await sellItem(Alice); + + const itemListAfter = await getMarketItemsChildren(); + t.is( + itemListAfter.length, + itemListBefore.length + 1, + 'Items market should have 1 more item', + ); + + const soldItemNode = itemListAfter.filter( + itemNode => !itemListBefore.includes(itemNode), + ); + const soldItem = await getMarketItem(soldItemNode); + + t.is( + itemBefore.description, + soldItem.asset.description, + 'Item on purse should have the same description as the one sold to market', + ); +}); + +test.serial('Bob buys an Item on marketplace', async t => { + const itemListBefore = await getMarketItemsChildren(); + const marketItemNode = itemListBefore[0]; + const marketItem = await getMarketItem(marketItemNode); + + await buyItem(Bob); + + const itemListAfter = await getMarketItemsChildren(); + t.is( + itemListAfter.length, + itemListBefore.length - 1, + 'Items market should have 1 less item', + ); + + const boughtItemNode = itemListBefore.filter( + itemNode => !itemListAfter.includes(itemNode), + ); + t.is( + marketItemNode, + boughtItemNode[0], + 'Item bought should have been removed from market', + ); + + const item = await getBalanceFromPurse(Bob, 'item'); + t.is( + item.description, + marketItem.asset.description, + 'Item on purse should have the same description as the one bought from market', + ); +}); + +test.serial('Alice sells a Character', async t => { + const characterListBefore = await getMarketCharactersChildren(); + t.false( + characterListBefore.includes('character-ephemeral_Ace'), + 'Character should not be on market before selling', + ); + + const characterBalanceBefore = await getBalanceFromPurse(Alice, 'character'); + t.is( + characterBalanceBefore.name, + 'ephemeral_Ace', + 'Character name should be ephemeral_Ace', + ); + + await sellCharacter(Alice); + + const characterListAfter = await getMarketCharactersChildren(); + t.true( + characterListAfter.includes('character-ephemeral_Ace'), + 'Character should be on market after selling', + ); + + const characterBalanceAfter = await getBalanceFromPurse(Alice, 'character'); + t.is( + characterBalanceAfter, + null, + 'Character should not be in purse after selling', + ); +}); + +test.serial('Bob buys a Character on marketplace', async t => { + await buyCharacter(Bob); + + const characterListBefore = await getMarketCharactersChildren(); + t.false( + characterListBefore.includes('character-ephemeral_Ace'), + 'Character should not be on market after buying', + ); + + const characterBalance = await getBalanceFromPurse(Bob, 'character'); + t.is( + characterBalance.name, + 'ephemeral_Ace', + 'Character name should be ephemeral_Ace', + ); +}); diff --git a/a3p-integration/proposals/n:upgrade-next/localchain.test.js b/a3p-integration/proposals/z:acceptance/localchain.test.js similarity index 100% rename from a3p-integration/proposals/n:upgrade-next/localchain.test.js rename to a3p-integration/proposals/z:acceptance/localchain.test.js diff --git a/a3p-integration/proposals/z:acceptance/package.json b/a3p-integration/proposals/z:acceptance/package.json index 9004540f415d..7410b3c84468 100644 --- a/a3p-integration/proposals/z:acceptance/package.json +++ b/a3p-integration/proposals/z:acceptance/package.json @@ -3,13 +3,16 @@ "type": "/agoric.swingset.CoreEvalProposal", "sdk-generate": [ "testing/start-valueVow.js start-valueVow", + "vats/test-localchain.js localchaintest-submission", "testing/restart-valueVow.js restart-valueVow" ] }, "type": "module", "license": "Apache-2.0", "dependencies": { - "@agoric/internal": "0.3.3-dev-5676146.0", + "@agoric/ertp": "dev", + "@agoric/internal": "dev", + "@agoric/store": "dev", "@agoric/synthetic-chain": "^0.3.0", "@endo/errors": "^1.2.2", "@endo/far": "^1.1.5", diff --git a/a3p-integration/proposals/z:acceptance/psm.test.js b/a3p-integration/proposals/z:acceptance/psm.test.js new file mode 100644 index 000000000000..bd64b3c5229a --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/psm.test.js @@ -0,0 +1,293 @@ +/* eslint-env node */ +/** + * @file The goal of this file is to implement a set of tests to make sure PSM works properly + * + * Here are the steps we want to take; + * 1 - Change swap fees and mint limit according to "psmTestSpecs" below + * 2 - Create a new user using agd.keys + * 3 - Fund new user with a stable coin from the VALIDATOR + * - Do not provision manually + * 4 - Make sure new user is able to mint IST from PSM (fees are applied) + * 5 - Make sure new user can pay their debt and get their anchor (fees are applied) + * 6 - Make sure mint limit is adhered + */ + +import test from 'ava'; +import { + agd, + agoric, + getUser, + GOV1ADDR, + GOV2ADDR, +} from '@agoric/synthetic-chain'; +import { + adjustBalancesIfNotProvisioned, + psmSwap, + bankSend, + checkGovParams, + checkSwapExceedMintLimit, + checkSwapSucceeded, + getPsmMetrics, + implementPsmGovParamChange, + initializeNewUser, + maxMintBelowLimit, +} from './test-lib/psm-lib.js'; +import { getBalances } from './test-lib/utils.js'; +import { NonNullish } from './test-lib/errors.js'; +import { waitUntilAccountFunded } from './test-lib/sync-tools.js'; + +// Export these from synthetic-chain? +const USDC_DENOM = NonNullish(process.env.USDC_DENOM); +const PSM_PAIR = NonNullish(process.env.PSM_PAIR); +const PSM_INSTANCE = `psm-${PSM_PAIR.replace('.', '-')}`; + +const psmSwapIo = { + now: Date.now, + follow: agoric.follow, + setTimeout, +}; + +const psmTestSpecs = { + govParams: { + giveMintedFeeVal: 10n, // in % + wantMintedFeeVal: 10n, // in % + mintLimit: 500n * 1_000_000n, // in IST + votingDuration: 1, // in minutes + }, + psmInstance: PSM_INSTANCE, + anchor: PSM_INSTANCE.split('-')[2], + newUser: { + name: 'new-psm-trader', + fund: { + denom: USDC_DENOM, + value: '300000000', // 300 USDC_axl + }, + }, + otherUser: { + name: 'gov1', + fund: { + denom: USDC_DENOM, + value: '1000000000', // 1000 USDC_axl + }, + toIst: { + value: 500, // in IST + }, + }, + toIst: { + value: 50, // in IST + }, + fromIst: { + value: 50, // in USDC_axl + }, +}; + +test.serial('change gov params', async t => { + await implementPsmGovParamChange( + { + address: GOV1ADDR, + instanceName: psmTestSpecs.psmInstance, + newParams: psmTestSpecs.govParams, + votingDuration: psmTestSpecs.govParams.votingDuration, + }, + { committeeAddrs: [GOV1ADDR, GOV2ADDR], position: 0 }, + { now: Date.now, follow: agoric.follow }, + ); + + await checkGovParams( + t, + { + GiveMintedFee: { + type: 'ratio', + value: { + numerator: { value: psmTestSpecs.govParams.giveMintedFeeVal * 100n }, // convert to bps + }, + }, + WantMintedFee: { + type: 'ratio', + value: { + numerator: { value: psmTestSpecs.govParams.wantMintedFeeVal * 100n }, // convert to bps + }, + }, + MintLimit: { + type: 'amount', + value: { + value: psmTestSpecs.govParams.mintLimit, + }, + }, + }, + psmTestSpecs.psmInstance.split('-')[2], + ); +}); + +test.serial('initialize new user', async t => { + const { + newUser: { name, fund }, + } = psmTestSpecs; + + await initializeNewUser(name, fund, { query: agd.query, setTimeout }); + t.pass(); +}); + +test.serial('swap into IST', async t => { + const { + newUser: { name }, + anchor, + toIst, + govParams: { wantMintedFeeVal }, + } = psmTestSpecs; + + const psmTrader = await getUser(name); + + const [metricsBefore, balances] = await Promise.all([ + getPsmMetrics(anchor), + getBalances([psmTrader]), + ]); + + const balancesBefore = await adjustBalancesIfNotProvisioned( + balances, + psmTrader, + ); + t.log('METRICS', metricsBefore); + t.log('BALANCES', balancesBefore); + + await psmSwap( + psmTrader, + [ + 'swap', + '--pair', + PSM_PAIR, + '--wantMinted', + toIst.value, + '--feePct', + wantMintedFeeVal, + ], + psmSwapIo, + ); + + await checkSwapSucceeded(t, metricsBefore, balancesBefore, { + wantMinted: toIst.value, + trader: psmTrader, + fee: Number(wantMintedFeeVal) / 100, // fee has to be between 0 and 1 + anchor, + }); +}); + +test.serial('swap out of IST', async t => { + const { + newUser: { name }, + anchor, + fromIst, + govParams: { giveMintedFeeVal }, + } = psmTestSpecs; + + const psmTrader = await getUser(name); + + const [metricsBefore, balancesBefore] = await Promise.all([ + getPsmMetrics(anchor), + getBalances([psmTrader]), + ]); + + t.log('METRICS', metricsBefore); + t.log('BALANCES', balancesBefore); + + await psmSwap( + psmTrader, + [ + 'swap', + '--pair', + PSM_PAIR, + '--giveMinted', + fromIst.value, + '--feePct', + giveMintedFeeVal, + ], + psmSwapIo, + ); + + await checkSwapSucceeded(t, metricsBefore, balancesBefore, { + giveMinted: fromIst.value, + trader: psmTrader, + fee: Number(giveMintedFeeVal) / 100, // fee has to be between 0 and 1 + anchor, + }); +}); + +test.serial('mint limit is adhered', async t => { + const { + otherUser: { + fund: { denom, value }, + name, + }, + govParams, + anchor, + } = psmTestSpecs; + + // Fund other user + const otherAddr = await getUser(name); + await bankSend(otherAddr, `${value}${denom}`); + await waitUntilAccountFunded( + otherAddr, + { query: agd.query, setTimeout }, + { denom, value: parseInt(value, 10) }, + { errorMessage: `${otherAddr} could not be funded with ${value}${denom}` }, + ); + + const [metricsBefore, balancesBefore] = await Promise.all([ + getPsmMetrics(anchor), + getBalances([otherAddr]), + ]); + + t.log('METRICS', metricsBefore); + t.log('BALANCES', balancesBefore); + + const { maxMintableValue, wantFeeValue } = await maxMintBelowLimit(anchor); + const maxMintFeesAccounted = Math.floor( + maxMintableValue * (1 - wantFeeValue), + ); + t.log({ maxMintableValue, wantFeeValue, maxMintFeesAccounted }); + + // Send a swap, should fail because mint limit is exceeded + await t.throwsAsync( + () => + psmSwap( + otherAddr, + [ + 'swap', + '--pair', + PSM_PAIR, + '--wantMinted', + maxMintFeesAccounted / 1000000 + 2, // Make sure we exceed the limit + '--feePct', + govParams.wantMintedFeeVal, + ], + psmSwapIo, + ), + { message: /not succeeded/ }, + ); + + // Now check if failed with correct error message + await checkSwapExceedMintLimit(t, otherAddr, metricsBefore); + + // Send another swap offer, this time should succeed + await psmSwap( + otherAddr, + [ + 'swap', + '--pair', + PSM_PAIR, + '--wantMinted', + maxMintFeesAccounted / 1000000, + '--feePct', + govParams.wantMintedFeeVal, + ], + psmSwapIo, + ); + + // Make sure swap succeeded + await checkSwapSucceeded(t, metricsBefore, balancesBefore, { + wantMinted: maxMintFeesAccounted / 1000000, + trader: otherAddr, + fee: Number(govParams.wantMintedFeeVal) / 100, // fee has to be between 0 and 1 + anchor, + }); +}); diff --git a/a3p-integration/proposals/z:acceptance/test-lib/errors.js b/a3p-integration/proposals/z:acceptance/test-lib/errors.js new file mode 100644 index 000000000000..57dc771e6a57 --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/test-lib/errors.js @@ -0,0 +1,20 @@ +/** + * @file Copied from "@agoric/internal" + */ + +import { q } from '@endo/errors'; + +/** + * @template T + * @param {T | null | undefined} val + * @param {string} [optDetails] + * @returns {T} + */ +export const NonNullish = (val, optDetails = `unexpected ${q(val)}`) => { + if (val != null) { + // This `!= null` idiom checks that `val` is neither `null` nor `undefined`. + return val; + } + assert.fail(optDetails); +}; +harden(NonNullish); diff --git a/a3p-integration/proposals/z:acceptance/test-lib/kread.js b/a3p-integration/proposals/z:acceptance/test-lib/kread.js new file mode 100644 index 000000000000..83ecc0c3f772 --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/test-lib/kread.js @@ -0,0 +1,358 @@ +import assert from 'assert'; +import '@endo/init'; +import { + agoric, + executeOffer, + getContractInfo, + makeAgd, +} from '@agoric/synthetic-chain'; +import { execFileSync } from 'child_process'; +import { makeCopyBag } from '@agoric/store'; +import { AmountMath } from '@agoric/ertp'; +import { makeFromBoard, boardSlottingMarshaller } from './rpc.js'; + +const ISTunit = 1_000_000n; + +const showAndExec = (file, args, opts) => { + console.log('$', file, ...args); + return execFileSync(file, args, opts); +}; + +// @ts-expect-error string is not assignable to Buffer +const agd = makeAgd({ execFileSync: showAndExec }).withOpts({ + keyringBackend: 'test', +}); + +const fromBoard = makeFromBoard(); +const marshaller = boardSlottingMarshaller(fromBoard.convertSlotToVal); + +const brandsRaw = await agoric.follow( + '-lF', + ':published.agoricNames.brand', + '-o', + 'text', +); +const brands = Object.fromEntries( + marshaller.fromCapData(JSON.parse(brandsRaw)), +); + +assert(brands.IST, 'Brand IST not found'); +assert(brands.timer, 'Brand timer not found'); +assert(brands.KREAdCHARACTER, 'Brand KREAdCHARACTER not found'); +assert(brands.KREAdITEM, 'Brand KREAdITEM not found'); + +export const getMarketCharactersChildren = async () => { + const { children } = await agd.query([ + 'vstorage', + 'children', + `published.kread.market-characters`, + ]); + + return children; +}; + +export const getMarketItemsChildren = async () => { + const { children } = await agd.query([ + 'vstorage', + 'children', + `published.kread.market-items`, + ]); + + return children; +}; + +export const getMarketItem = async itemNode => { + const itemMarketPath = `:published.kread.market-items.${itemNode}`; + const rawItemData = await agoric.follow('-lF', itemMarketPath, '-o', 'text'); + const item = marshaller.fromCapData(JSON.parse(rawItemData)); + + return item; +}; + +export const getCharacterInventory = async characterName => { + const inventoryPath = `kread.character.inventory-${characterName}`; + const characterInventory = await getContractInfo(inventoryPath, { + agoric, + prefix: 'published.', + }); + + return characterInventory; +}; + +export const getMarketCharacterFromVstorage = async () => { + const charactersMarket = await getMarketCharactersChildren(); + const path = `:published.kread.market-characters.${charactersMarket[0]}`; + const rawCharacterData = await agoric.follow('-lF', path, '-o', 'text'); + const marketCharacter = marshaller.fromCapData(JSON.parse(rawCharacterData)); + + return marketCharacter; +}; + +export const getBalanceFromPurse = async (address, type) => { + const walletRaw = await agoric.follow( + '-lF', + `:published.wallet.${address}.current`, + '-o', + 'text', + ); + const purses = marshaller.fromCapData(JSON.parse(walletRaw)).purses; + + const assetBrands = { + character: brands.KREAdCHARACTER, + item: brands.KREAdITEM, + }; + const assetBrand = assetBrands[type]; + if (!assetBrand) { + throw new Error('Invalid type provided. Must be "character" or "item".'); + } + + const assetPurse = purses.find( + ({ brand }) => brand.getBoardId() === assetBrand.getBoardId(), + ); + + return assetPurse?.balance.value.payload[0]?.[0] || null; +}; + +/** @import {Brand, CopyBagAmount} from '@agoric/ertp/src/types.js'; */ + +/** + * @param {Brand} brand + * @param {any} asset + * @returns {CopyBagAmount<'item'>} + */ +export const assetAsAmount = (brand, asset) => { + const assetValue = makeCopyBag([[asset, 1n]]); + const assetAmount = AmountMath.make(brand, assetValue); + return assetAmount; +}; + +export const totalAssetPriceAmount = asset => { + const fees = AmountMath.add(asset.platformFee, asset.royalty); + const price = AmountMath.add(asset.askingPrice, fees); + return price; +}; +const mintCharacterOffer = async () => { + const body = { + method: 'executeOffer', + offer: { + id: 'KREAd-mint-character-acceptance-test', + invitationSpec: { + source: 'agoricContract', + instancePath: ['kread'], + callPipe: [['makeMintCharacterInvitation', []]], + }, + offerArgs: { name: 'ephemeral_Ace' }, + proposal: { + give: { + Price: { + brand: brands.IST, + value: 5n * ISTunit, + }, + }, + }, + }, + }; + + return JSON.stringify(marshaller.toCapData(harden(body))); +}; + +const unequipAllItemsOffer = async address => { + const kreadCharacter = await getBalanceFromPurse(address, 'character'); + if (!kreadCharacter) { + throw new Error('Character not found on user purse'); + } + + // deal with KREAd's funky parallel character representation swap + const inventoryKeyId = kreadCharacter.keyId === 1 ? 2 : 1; + const kreadCharacter2 = { ...kreadCharacter, keyId: inventoryKeyId }; + + const kreadCharacterAmount = assetAsAmount( + brands.KREAdCHARACTER, + kreadCharacter, + ); + + const kreadCharacter2Amount = assetAsAmount( + brands.KREAdCHARACTER, + kreadCharacter2, + ); + + const body = { + method: 'executeOffer', + offer: { + id: 'KREAd-unequip-all-items-acceptance-test', + invitationSpec: { + source: 'agoricContract', + instancePath: ['kread'], + callPipe: [['makeUnequipAllInvitation', []]], + }, + proposal: { + give: { + CharacterKey1: kreadCharacterAmount, + }, + want: { + CharacterKey2: kreadCharacter2Amount, + }, + }, + }, + }; + + return JSON.stringify(marshaller.toCapData(harden(body))); +}; + +const buyItemOffer = async () => { + const children = await getMarketItemsChildren(); + const marketItem = await getMarketItem(children[0]); + + const itemAmount = assetAsAmount(brands.KREAdITEM, marketItem.asset); + const priceAmount = totalAssetPriceAmount(marketItem); + + const body = { + method: 'executeOffer', + offer: { + id: 'KREAd-buy-item-acceptance-test', + invitationSpec: { + source: 'agoricContract', + instancePath: ['kread'], + callPipe: [['makeBuyItemInvitation', []]], + }, + offerArgs: { entryId: marketItem.id }, + proposal: { + give: { + Price: priceAmount, + }, + want: { + Item: itemAmount, + }, + }, + }, + }; + + return JSON.stringify(marshaller.toCapData(harden(body))); +}; + +const sellItemOffer = async address => { + const kreadItem = await getBalanceFromPurse(address, 'item'); + if (!kreadItem) { + throw new Error('Item not found on user purse'); + } + + const itemAmount = assetAsAmount(brands.KREAdITEM, kreadItem); + + const body = { + method: 'executeOffer', + offer: { + id: 'KREAd-sell-item-acceptance-test', + invitationSpec: { + source: 'agoricContract', + instancePath: ['kread'], + callPipe: [['makeSellItemInvitation', []]], + }, + proposal: { + give: { + Item: itemAmount, + }, + want: { + Price: { + brand: brands.IST, + value: 5n * ISTunit, + }, + }, + }, + }, + }; + + return JSON.stringify(marshaller.toCapData(harden(body))); +}; + +const buyCharacterOffer = async () => { + const marketCharacter = await getMarketCharacterFromVstorage(); + + const kreadCharacterAmount = assetAsAmount( + brands.KREAdCHARACTER, + marketCharacter.asset, + ); + const priceAmount = totalAssetPriceAmount(marketCharacter); + + const body = { + method: 'executeOffer', + offer: { + id: 'KREAd-buy-character-acceptance-test', + invitationSpec: { + source: 'agoricContract', + instancePath: ['kread'], + callPipe: [['makeBuyCharacterInvitation', []]], + }, + proposal: { + give: { + Price: priceAmount, + }, + want: { + Character: kreadCharacterAmount, + }, + }, + }, + }; + + return JSON.stringify(marshaller.toCapData(harden(body))); +}; + +const sellCharacterOffer = async address => { + const kreadCharacter = await getBalanceFromPurse(address, 'character'); + if (!kreadCharacter) { + throw new Error('Character not found on user purse'); + } + + const kreadCharacterAmount = assetAsAmount( + brands.KREAdCHARACTER, + kreadCharacter, + ); + + const body = { + method: 'executeOffer', + offer: { + id: 'KREAd-sell-character-acceptance-test', + invitationSpec: { + source: 'agoricContract', + instancePath: ['kread'], + callPipe: [['makeSellCharacterInvitation', []]], + }, + proposal: { + give: { + Character: kreadCharacterAmount, + }, + want: { + Price: { + brand: brands.IST, + value: 5n * ISTunit, + }, + }, + }, + }, + }; + + return JSON.stringify(marshaller.toCapData(harden(body))); +}; + +export const mintCharacter = async address => { + return executeOffer(address, mintCharacterOffer()); +}; + +export const unequipAllItems = async address => { + return executeOffer(address, unequipAllItemsOffer(address)); +}; + +export const buyItem = async address => { + return executeOffer(address, buyItemOffer()); +}; + +export const sellItem = async address => { + return executeOffer(address, sellItemOffer(address)); +}; + +export const sellCharacter = async address => { + return executeOffer(address, sellCharacterOffer(address)); +}; + +export const buyCharacter = async address => { + return executeOffer(address, buyCharacterOffer()); +}; diff --git a/a3p-integration/proposals/z:acceptance/test-lib/psm-lib.js b/a3p-integration/proposals/z:acceptance/test-lib/psm-lib.js new file mode 100644 index 000000000000..442a947500b0 --- /dev/null +++ b/a3p-integration/proposals/z:acceptance/test-lib/psm-lib.js @@ -0,0 +1,623 @@ +/* eslint-env node */ + +import '@endo/init'; +import { + addUser, + agd, + agops, + agoric, + executeOffer, + getUser, + agopsLocation, + executeCommand, + CHAINID, + VALIDATORADDR, + GOV1ADDR, + mkTemp, +} from '@agoric/synthetic-chain'; +import { AmountMath } from '@agoric/ertp'; +import fsp from 'node:fs/promises'; +import { boardSlottingMarshaller, makeFromBoard } from './rpc.js'; +import { getBalances } from './utils.js'; +import { + retryUntilCondition, + waitUntilAccountFunded, + waitUntilOfferResult, +} from './sync-tools.js'; +import { NonNullish } from './errors.js'; + +// Export these from synthetic-chain? +const USDC_DENOM = NonNullish(process.env.USDC_DENOM); +const PSM_PAIR = NonNullish(process.env.PSM_PAIR).replace('.', '-'); + +/** + * @typedef {object} PsmMetrics + * @property {import('@agoric/ertp').Amount<'nat'>} anchorPoolBalance + * @property {import('@agoric/ertp').Amount<'nat'>} feePoolBalance + * @property {import('@agoric/ertp').Amount<'nat'>} mintedPoolBalance + * @property {import('@agoric/ertp').Amount<'nat'>} totalAnchorProvided + * @property {import('@agoric/ertp').Amount<'nat'>} totalMintedProvided + * + * @typedef {Array<{ denom: string; amount: string; }>} CosmosBalances + */ + +const fromBoard = makeFromBoard(); +const marshaller = boardSlottingMarshaller(fromBoard.convertSlotToVal); + +/** + * Import from synthetic-chain once it is updated + * + * @param {string} addr + * @param {string} wanted + * @param {string} [from] + */ +export const bankSend = (addr, wanted, from = VALIDATORADDR) => { + const chain = ['--chain-id', CHAINID]; + const fromArg = ['--from', from]; + const testKeyring = ['--keyring-backend', 'test']; + const noise = [...fromArg, ...chain, ...testKeyring, '--yes']; + + return agd.tx('bank', 'send', from, addr, wanted, ...noise); +}; + +/** + * + * @param {{ + * address: string + * instanceName: string + * newParams: Params + * deadline: bigint + * offerId: string + * }} QuestionDetails + */ +export const buildProposePSMParamChangeOffer = async ({ + address, + instanceName, + newParams, + deadline, + offerId, +}) => { + const charterAcceptOfferId = await agops.ec( + 'find-continuing-id', + '--for', + `${'charter\\ member\\ invitation'}`, + '--from', + address, + ); + console.log('charterAcceptOfferId', charterAcceptOfferId); + const [brands, instances] = await Promise.all([ + agoric + .follow('-lF', ':published.agoricNames.brand', '-o', 'text') + .then(brandsRaw => + Object.fromEntries(marshaller.fromCapData(JSON.parse(brandsRaw))), + ), + agoric + .follow('-lF', ':published.agoricNames.instance', '-o', 'text') + .then(instancesRaw => + Object.fromEntries(marshaller.fromCapData(JSON.parse(instancesRaw))), + ), + ]); + + console.log('charterAcceptOfferId', charterAcceptOfferId); + console.log('BRANDS', brands); + console.log('INSTANCE', instances); + + /** + * @param {bigint} numValInPercent + */ + const toRatio = numValInPercent => { + const commonDenominator = AmountMath.make(brands.IST, 10_000n); + const numerator = AmountMath.make(brands.IST, numValInPercent * 100n); // Convert to bps + + return { + numerator, + denominator: commonDenominator, + }; + }; + + const params = {}; + if (newParams.giveMintedFeeVal) { + params.GiveMintedFee = toRatio(newParams.giveMintedFeeVal); + } + + if (newParams.wantMintedFeeVal) { + params.WantMintedFee = toRatio(newParams.wantMintedFeeVal); + } + + if (newParams.mintLimit) { + params.MintLimit = AmountMath.make(brands.IST, newParams.mintLimit); + } + + const offerSpec = { + id: offerId, + invitationSpec: { + source: 'continuing', + previousOffer: charterAcceptOfferId, + invitationMakerName: 'VoteOnParamChange', + }, + proposal: {}, + offerArgs: { + instance: instances[instanceName], + params, + deadline, + }, + }; + + /** @type {string | object} */ + const spendAction = { + method: 'executeOffer', + offer: offerSpec, + }; + + const offer = JSON.stringify(marshaller.toCapData(harden(spendAction))); + console.log(offerSpec); + console.log(offer); + + return executeOffer(address, offer); +}; + +/** + * + * @param {{ + * committeeAddrs: Array + * position: number | string + * }} VotingDetails + */ +export const voteForNewParams = ({ committeeAddrs, position }) => { + console.log('ACTIONS voting for position', position, 'using', committeeAddrs); + return Promise.all( + committeeAddrs.map(account => + // @ts-expect-error Casting + agops.ec('vote', '--forPosition', position, '--send-from', account), + ), + ); +}; + +/** + * @param {{follow: (...params: string[]) => Promise }} io + */ +export const fetchLatestEcQuestion = async io => { + const { follow } = io; + const pathOutcome = ':published.committees.Economic_Committee.latestOutcome'; + const pathQuestion = + ':published.committees.Economic_Committee.latestQuestion'; + + const [latestOutcome, latestQuestion] = await Promise.all([ + follow('-lF', pathOutcome, '-o', 'text').then(outcomeRaw => + marshaller.fromCapData(JSON.parse(outcomeRaw)), + ), + follow('-lF', pathQuestion, '-o', 'text').then(questionRaw => + marshaller.fromCapData(JSON.parse(questionRaw)), + ), + ]); + + return { latestOutcome, latestQuestion }; +}; + +const checkCommitteeElectionResult = (electionResult, expectedResult) => { + const { + latestOutcome: { outcome, question }, + latestQuestion: { + closingRule: { deadline }, + questionHandle, + }, + } = electionResult; + const { outcome: expectedOutcome, deadline: expectedDeadline } = + expectedResult; + + return ( + expectedOutcome === outcome && + deadline === expectedDeadline && + question === questionHandle + ); +}; + +/** + * @typedef {{ + * giveMintedFeeVal: bigint; + * wantMintedFeeVal: bigint; + * mintLimit: bigint; + * }} Params + * + * + * @param {{ + * address: string + * instanceName: string + * newParams: Params + * votingDuration: number + * offerId?: string + * }} question + * + * @param {{ + * committeeAddrs: Array + * position: number + * }} voting + * + * @param {{ now: () => number; follow: (...params: string[]) => Promise}} io + */ +export const implementPsmGovParamChange = async (question, voting, io) => { + const { now: getNow, follow } = io; + const now = getNow(); + const deadline = BigInt( + question.votingDuration * 60 + Math.round(now / 1000), + ); + + await buildProposePSMParamChangeOffer({ + ...question, + deadline, + offerId: now.toString(), + }); + await voteForNewParams(voting); + + console.log('ACTIONS wait for the vote deadline to pass'); + await retryUntilCondition( + () => fetchLatestEcQuestion({ follow }), + electionResult => + checkCommitteeElectionResult(electionResult, { + outcome: 'win', + deadline, + }), + 'PSM param change election failed', + { setTimeout, retryIntervalMs: 5000, maxRetries: 15 }, + ); +}; + +/** + * @param {string} anchor + */ +export const getPsmGovernance = async anchor => { + const governanceRaw = await agoric.follow( + '-lF', + `:published.psm.IST.${anchor}.governance`, + '-o', + 'text', + ); + const { current } = marshaller.fromCapData(JSON.parse(governanceRaw)); + return current; +}; + +/** + * @param {string} anchor + */ +export const getPsmMetrics = async anchor => { + const metricsRaw = await agoric.follow( + '-lF', + `:published.psm.IST.${anchor}.metrics`, + '-o', + 'text', + ); + + return marshaller.fromCapData(JSON.parse(metricsRaw)); +}; + +export const checkGovParams = async (t, expected, psmName) => { + const current = await getPsmGovernance(psmName); + + t.log({ + give: current.WantMintedFee.value, + want: current.GiveMintedFee.value, + mintLimit: current.MintLimit, + }); + + t.like(current, expected); +}; + +/** + * + * @param {string} userName + * @param {{ + * denom: string, + * value: string + * }} expectedAnchorFunds + */ +export const checkUserInitializedSuccessfully = async ( + userName, + expectedAnchorFunds, +) => { + const userAddress = await getUser(userName); + + const balance = await getBalances([userAddress], expectedAnchorFunds.denom); + assert(balance >= BigInt(expectedAnchorFunds.value)); +}; + +/** + * + * @param {string} name + * @param {{ + * denom: string, + * value: string + * }} fund + * @param io + */ +export const initializeNewUser = async (name, fund, io) => { + const psmTrader = await addUser(name); + await Promise.all([ + bankSend(psmTrader, `20000000ubld,${fund.value}${fund.denom}`), + bankSend(psmTrader, `1000000uist`, GOV1ADDR), + ]); + + await waitUntilAccountFunded( + psmTrader, + io, + { denom: fund.denom, value: parseInt(fund.value, 10) }, + { errorMessage: `${psmTrader} not funded` }, + ); + + await checkUserInitializedSuccessfully(name, fund); +}; + +/** + * Similar to https://github.com/Agoric/agoric-3-proposals/blob/422b163fecfcf025d53431caebf6d476778b5db3/packages/synthetic-chain/src/lib/commonUpgradeHelpers.ts#L123-L139 + * However, in the case where "address" is not provisioned "agoric wallet send" is needed because + * "agops perf satisfaction" tries to follow ":published.wallet.${address}" which blocks the execution because no such path exists in + * vstorage. In situations like this "agoric wallet send" seems a better choice as it doesn't depend on following user's vstorage wallet path + * + * @param {string} address + * @param {Promise} offerPromise + */ +export const sendOfferAgoric = async (address, offerPromise) => { + const offerPath = await mkTemp('agops.XXX'); + const offer = await offerPromise; + await fsp.writeFile(offerPath, offer); + + await agoric.wallet( + '--keyring-backend=test', + 'send', + '--offer', + offerPath, + '--from', + address, + ); +}; + +/** + * @param {string} address + * @param {Array} params + * @param {{ + * follow: (...params: string[]) => Promise; + * setTimeout: (callback: Function, delay: number) => void; + * now: () => number + * }} io + */ +export const psmSwap = async (address, params, io) => { + const now = io.now(); + const offerId = `${address}-psm-swap-${now}`; + const newParams = ['psm', ...params, '--offerId', offerId]; + const offerPromise = executeCommand(agopsLocation, newParams); + await sendOfferAgoric(address, offerPromise); + + await waitUntilOfferResult(address, offerId, true, io, { + errorMessage: `${offerId} not succeeded`, + }); +}; + +/** + * + * @param {number} base + * @param {number} fee + */ +const giveAnchor = (base, fee) => Math.ceil(base / (1 - fee)); + +/** + * + * @param {number} base + * @param {number} fee + */ +const receiveAnchor = (base, fee) => Math.ceil(base * (1 - fee)); + +/** + * + * @param {CosmosBalances} balances + * @param {string} targetDenom + */ +const extractBalance = (balances, targetDenom) => { + const balance = balances.find(({ denom }) => denom === targetDenom); + if (!balance) return 0; + return Number(balance.amount); +}; + +/** + * Checking IST balances can be tricky because of the execution fee mentioned in + * https://github.com/Agoric/agoric-sdk/issues/6525. Here we first check with + * whatever is passed in. If the first attempt fails we try again to see if + * there was an execution fee charged. If still fails, we throw. + * + * @param {import('ava').ExecutionContext} t + * @param {number} actualBalance + * @param {number} expectedBalance + */ +const tryISTBalances = async (t, actualBalance, expectedBalance) => { + const firstTry = await t.try( + (tt, actual, expected) => { + tt.deepEqual(actual, expected); + }, + actualBalance, + expectedBalance, + ); + + if (!firstTry.passed) { + firstTry.discard(); + t.deepEqual(actualBalance + 200000, expectedBalance); + } else firstTry.commit(); +}; + +/** + * + * @param {import('ava').ExecutionContext} t + * @param {PsmMetrics} metricsBefore + * @param {CosmosBalances} balancesBefore + * @param {{trader: string; fee: number; anchor: string;} & ( + * | {wantMinted: number} + * | {giveMinted: number} + * )} tradeInfo + */ +export const checkSwapSucceeded = async ( + t, + metricsBefore, + balancesBefore, + tradeInfo, +) => { + const [metricsAfter, balancesAfter] = await Promise.all([ + getPsmMetrics(tradeInfo.anchor), + getBalances([tradeInfo.trader]), + ]); + + t.log('METRICS_AFTER', metricsAfter); + t.log('BALANCES_AFTER', balancesAfter); + + if ('wantMinted' in tradeInfo) { + const anchorPaid = giveAnchor( + tradeInfo.wantMinted * 1000000, + tradeInfo.fee, + ); + const mintedReceived = tradeInfo.wantMinted * 1000000; + const feePaid = anchorPaid - mintedReceived; + + t.deepEqual( + extractBalance(balancesAfter, USDC_DENOM), + extractBalance(balancesBefore, USDC_DENOM) - anchorPaid, + ); + + await tryISTBalances( + t, + extractBalance(balancesAfter, 'uist'), + extractBalance(balancesBefore, 'uist') + mintedReceived, + ); + + t.like(metricsAfter, { + anchorPoolBalance: { + value: metricsBefore.anchorPoolBalance.value + BigInt(anchorPaid), + }, + feePoolBalance: { + value: metricsBefore.feePoolBalance.value + BigInt(feePaid), + }, + mintedPoolBalance: { + value: metricsBefore.mintedPoolBalance.value + BigInt(anchorPaid), + }, + totalAnchorProvided: { + value: metricsBefore.totalAnchorProvided.value, + }, + totalMintedProvided: { + value: metricsBefore.totalMintedProvided.value + BigInt(anchorPaid), + }, + }); + } else if ('giveMinted' in tradeInfo) { + const mintedPaid = tradeInfo.giveMinted * 1000000; + const anchorReceived = receiveAnchor( + tradeInfo.giveMinted * 1000000, + tradeInfo.fee, + ); + const feePaid = mintedPaid - anchorReceived; + + t.deepEqual( + extractBalance(balancesAfter, USDC_DENOM), + extractBalance(balancesBefore, USDC_DENOM) + anchorReceived, + ); + + await tryISTBalances( + t, + extractBalance(balancesAfter, 'uist'), + extractBalance(balancesBefore, 'uist') - mintedPaid, + ); + + t.like(metricsAfter, { + anchorPoolBalance: { + value: metricsBefore.anchorPoolBalance.value - BigInt(anchorReceived), + }, + feePoolBalance: { + value: metricsBefore.feePoolBalance.value + BigInt(feePaid), + }, + mintedPoolBalance: { + value: metricsBefore.mintedPoolBalance.value - BigInt(anchorReceived), + }, + totalAnchorProvided: { + value: metricsBefore.totalAnchorProvided.value + BigInt(anchorReceived), + }, + totalMintedProvided: { + value: metricsBefore.totalMintedProvided.value, + }, + }); + } +}; + +/** + * + * @param {Array<{ denom: string; amount: string }>} balances + * @param {string} address + */ +export const adjustBalancesIfNotProvisioned = async (balances, address) => { + const { children } = await agd.query( + 'vstorage', + 'children', + 'published.wallet', + '-o', + 'json', + ); + const addressProvisioned = children.includes(address); + + if (addressProvisioned === true) return balances; + + const balancesAdjusted = []; + + for (const { denom, amount } of balances) { + if (denom === 'uist') { + const startingAmount = ( + parseInt(amount, 10) + + 250000 - + 1_000_000 + ).toString(); // provision sends 250000uist to new accounts and 1 IST is charged + balancesAdjusted.push({ denom, amount: startingAmount }); + } else { + balancesAdjusted.push({ denom, amount }); + } + } + + return balancesAdjusted; +}; + +/** + * + * @param {any} t + * @param {string} address + * @param {Record} metricsBefore + */ +export const checkSwapExceedMintLimit = async (t, address, metricsBefore) => { + const [offerResult, metricsAfter] = await Promise.all([ + agoric.follow('-lF', `:published.wallet.${address}`), + getPsmMetrics(PSM_PAIR.split('-')[1]), + ]); + const { status, updated } = offerResult; + + t.is(updated, 'offerStatus'); + t.is(status.error, 'Error: Request would exceed mint limit'); + t.like(metricsBefore, { + mintedPoolBalance: { value: metricsAfter.mintedPoolBalance.value }, + }); +}; + +/** + * @param {string} anchor + * @returns {Promise<{ maxMintableValue: number; wantFeeValue: number; giveFeeValue: number; }>} + */ +export const maxMintBelowLimit = async anchor => { + const [governance, metrics] = await Promise.all([ + getPsmGovernance(anchor), + getPsmMetrics(anchor), + ]); + + const mintLimitVal = Number(governance.MintLimit.value.value); + const mintedPoolBalanceVal = Number(metrics.mintedPoolBalance.value); + const maxMintableValue = mintLimitVal - mintedPoolBalanceVal - 1; + + const wantFeeRatio = governance.WantMintedFee.value; + const giveFeeRatio = governance.GiveMintedFee.value; + + const wantFeeValue = + Number(wantFeeRatio.numerator.value) / + Number(wantFeeRatio.denominator.value); + const giveFeeValue = + Number(giveFeeRatio.numerator.value) / + Number(giveFeeRatio.denominator.value); + + return { maxMintableValue, wantFeeValue, giveFeeValue }; +}; diff --git a/a3p-integration/proposals/z:acceptance/test-lib/sync-tools.js b/a3p-integration/proposals/z:acceptance/test-lib/sync-tools.js index f0daeddabde0..dac2ba7e04f1 100644 --- a/a3p-integration/proposals/z:acceptance/test-lib/sync-tools.js +++ b/a3p-integration/proposals/z:acceptance/test-lib/sync-tools.js @@ -16,12 +16,12 @@ /** * @typedef {object} RetryOptions - * @property {number} maxRetries - * @property {number} retryIntervalMs - * @property {(...arg0: string[]) => void} log - * @property {(object) => void} [setTimeout] - * @property {string} [errorMessage=Error] + * @property {number} [maxRetries] + * @property {number} [retryIntervalMs] + * @property {(...arg0: string[]) => void} [log] + * @property {(callback: Function, delay: number) => void} [setTimeout] * + * @typedef {RetryOptions & {errorMessage: string}} WaitUntilOptions * * @typedef {object} CosmosBalanceThreshold * @property {string} denom @@ -36,7 +36,7 @@ const ambientSetTimeout = global.setTimeout; * @param {number} ms * @param {*} sleepOptions */ -const sleep = (ms, { log = () => {}, setTimeout = ambientSetTimeout }) => +export const sleep = (ms, { log = () => {}, setTimeout = ambientSetTimeout }) => new Promise(resolve => { log(`Sleeping for ${ms}ms...`); setTimeout(resolve, ms); @@ -54,7 +54,7 @@ export const retryUntilCondition = async ( operation, condition, message, - { maxRetries = 6, retryIntervalMs = 3500, log, setTimeout }, + { maxRetries = 6, retryIntervalMs = 3500, log = console.log, setTimeout }, ) => { console.log({ maxRetries, retryIntervalMs, message }); let retries = 0; @@ -85,7 +85,7 @@ export const retryUntilCondition = async ( }; /** - * @param {RetryOptions} options + * @param {WaitUntilOptions} options */ const overrideDefaultOptions = options => { const defaultValues = { @@ -113,7 +113,7 @@ const makeGetInstances = follow => async () => { * * @param {string} contractName * @param {{follow: () => object, setTimeout: (object) => void}} ambientAuthority - * @param {RetryOptions} options + * @param {WaitUntilOptions} options */ export const waitUntilContractDeployed = ( contractName, @@ -155,7 +155,7 @@ const checkCosmosBalance = (balances, threshold) => { * @param {string} destAcct * @param {{query: () => Promise, setTimeout: (object) => void}} ambientAuthority * @param {{denom: string, value: number}} threshold - * @param {RetryOptions} options + * @param {WaitUntilOptions} options */ export const waitUntilAccountFunded = ( destAcct, @@ -197,7 +197,7 @@ const checkOfferState = (offerStatus, waitForPayouts, offerId) => { if (!status) return false; if (status.id !== offerId) return false; if (!status.numWantsSatisfied || status.numWantsSatisfied !== 1) return false; - if (waitForPayouts && status.result && status.payouts) return true; + if (waitForPayouts && status.payouts) return true; if (!waitForPayouts && status.result) return true; return false; @@ -208,8 +208,8 @@ const checkOfferState = (offerStatus, waitForPayouts, offerId) => { * @param {string} addr * @param {string} offerId * @param {boolean} waitForPayouts - * @param {{follow: () => object, setTimeout: (object) => void}} ambientAuthority - * @param {RetryOptions} options + * @param {{follow: () => object, setTimeout: (callback: Function, delay: number) => void}} ambientAuthority + * @param {WaitUntilOptions} options */ export const waitUntilOfferResult = ( addr, @@ -251,7 +251,7 @@ const checkForInvitation = update => { * * @param {string} addr * @param {{follow: () => object, setTimeout: (object) => void}} ambientAuthority - * @param {RetryOptions} options + * @param {WaitUntilOptions} options */ export const waitUntilInvitationReceived = ( addr, diff --git a/a3p-integration/proposals/z:acceptance/test.sh b/a3p-integration/proposals/z:acceptance/test.sh index a1f74a431e3f..65514c76e9f7 100755 --- a/a3p-integration/proposals/z:acceptance/test.sh +++ b/a3p-integration/proposals/z:acceptance/test.sh @@ -14,7 +14,7 @@ npm install -g tsx scripts/test-vaults.mts echo ACCEPTANCE TESTING kread -./create-kread-item-test.sh +yarn ava kread.test.js echo ACCEPTANCE TESTING valueVow yarn ava valueVow.test.js @@ -29,5 +29,8 @@ yarn ava wallet.test.js echo ACCEPTANCE TESTING vaults yarn ava vaults.test.js +echo ACCEPTANCE TESTING psm +yarn ava psm.test.js + echo ACCEPTANCE TESTING governance yarn ava governance.test.js diff --git a/a3p-integration/proposals/z:acceptance/vaults.test.js b/a3p-integration/proposals/z:acceptance/vaults.test.js index 5545a9381be7..73f6c9433a22 100644 --- a/a3p-integration/proposals/z:acceptance/vaults.test.js +++ b/a3p-integration/proposals/z:acceptance/vaults.test.js @@ -8,53 +8,15 @@ import { adjustVault, closeVault, getISTBalance, - getPriceQuote, - pushPrices, getContractInfo, ATOM_DENOM, USER1ADDR, waitForBlock, - registerOraclesForBrand, - generateOracleMap, } from '@agoric/synthetic-chain'; import { getBalances, agopsVaults } from './test-lib/utils.js'; -import { retryUntilCondition } from './test-lib/sync-tools.js'; export const scale6 = x => BigInt(x * 1_000_000); -// There may be a new vaultFactory that doesn't have prices yet, so we publish -// prices now -test.before(async t => { - const pushPriceRetryOpts = { - maxRetries: 5, // arbitrary - retryIntervalMs: 5000, // in ms - }; - t.context = { - roundId: 1, - retryOpts: { - pushPriceRetryOpts, - }, - }; - const oraclesByBrand = generateOracleMap('z-acc', ['ATOM']); - await registerOraclesForBrand('ATOM', oraclesByBrand); - - const price = 15.2; - // @ts-expect-error t.context is fine - await pushPrices(price, 'ATOM', oraclesByBrand, t.context.roundId); - - await retryUntilCondition( - () => getPriceQuote('ATOM'), - res => res === `+${scale6(price).toString()}`, - 'price not pushed yet', - { - log: t.log, - setTimeout: global.setTimeout, - // @ts-expect-error t.context is fine - ...t.context.pushPriceRetryOpts, - }, - ); -}); - test.serial('attempt to open vaults under the minimum amount', async t => { const activeVaultsBefore = await agopsVaults(USER1ADDR); await bankSend(USER1ADDR, `20000000${ATOM_DENOM}`); diff --git a/a3p-integration/proposals/z:acceptance/yarn.lock b/a3p-integration/proposals/z:acceptance/yarn.lock index 5cd3b8df2342..23e915995d69 100644 --- a/a3p-integration/proposals/z:acceptance/yarn.lock +++ b/a3p-integration/proposals/z:acceptance/yarn.lock @@ -5,55 +5,106 @@ __metadata: version: 8 cacheKey: 10c0 -"@agoric/assert@npm:0.6.1-dev-5676146.0+5676146": - version: 0.6.1-dev-5676146.0 - resolution: "@agoric/assert@npm:0.6.1-dev-5676146.0" - checksum: 10c0/3391d53d64f4ca74ae5a87b623dc7489a20d91f45716723c33e393cfe6536fb1553344b72d24ac966f49b83d56906140c263778968ff513dfcdbb30e1be68091 +"@agoric/base-zone@npm:0.1.1-dev-d7c994b.0+d7c994b": + version: 0.1.1-dev-d7c994b.0 + resolution: "@agoric/base-zone@npm:0.1.1-dev-d7c994b.0" + dependencies: + "@agoric/store": "npm:0.9.3-dev-d7c994b.0+d7c994b" + "@endo/common": "npm:^1.2.7" + "@endo/errors": "npm:^1.2.7" + "@endo/exo": "npm:^1.5.6" + "@endo/far": "npm:^1.1.8" + "@endo/pass-style": "npm:^1.4.6" + "@endo/patterns": "npm:^1.4.6" + checksum: 10c0/c739aaba377d0f9409561ece7f9ed94ef3cdad7ddbbf56609bc50ea9fe71446fccbd92bb5a4dcb11a40872fdf862b5a7836b8140b5639ca501717b569249a344 + languageName: node + linkType: hard + +"@agoric/ertp@npm:dev": + version: 0.16.3-dev-d7c994b.0 + resolution: "@agoric/ertp@npm:0.16.3-dev-d7c994b.0" + dependencies: + "@agoric/notifier": "npm:0.6.3-dev-d7c994b.0+d7c994b" + "@agoric/store": "npm:0.9.3-dev-d7c994b.0+d7c994b" + "@agoric/vat-data": "npm:0.5.3-dev-d7c994b.0+d7c994b" + "@agoric/zone": "npm:0.2.3-dev-d7c994b.0+d7c994b" + "@endo/errors": "npm:^1.2.7" + "@endo/eventual-send": "npm:^1.2.7" + "@endo/far": "npm:^1.1.8" + "@endo/marshal": "npm:^1.6.1" + "@endo/nat": "npm:^5.0.12" + "@endo/patterns": "npm:^1.4.6" + "@endo/promise-kit": "npm:^1.1.7" + checksum: 10c0/050e7755fcabb1fb624b58742f02571a7b459361ef13f508002c5c64993c22200faf66df8e931caf293e35290ce42bffef3e912839d05a18d26224263e039cf3 + languageName: node + linkType: hard + +"@agoric/internal@npm:0.3.3-dev-d7c994b.0+d7c994b, @agoric/internal@npm:dev": + version: 0.3.3-dev-d7c994b.0 + resolution: "@agoric/internal@npm:0.3.3-dev-d7c994b.0" + dependencies: + "@agoric/base-zone": "npm:0.1.1-dev-d7c994b.0+d7c994b" + "@endo/common": "npm:^1.2.7" + "@endo/errors": "npm:^1.2.7" + "@endo/far": "npm:^1.1.8" + "@endo/init": "npm:^1.1.6" + "@endo/marshal": "npm:^1.6.1" + "@endo/pass-style": "npm:^1.4.6" + "@endo/patterns": "npm:^1.4.6" + "@endo/promise-kit": "npm:^1.1.7" + "@endo/stream": "npm:^1.2.7" + anylogger: "npm:^0.21.0" + jessie.js: "npm:^0.3.4" + checksum: 10c0/ce8e58f77c92b4dab1f87ba708b1e189906cf66fcf846d0949ce24822eebca01c76ee5bb992fd4c98fe02add0dc95f502d2a0f7c4f08d6d320268b369e82a9b9 languageName: node linkType: hard -"@agoric/base-zone@npm:0.1.1-dev-5676146.0+5676146": - version: 0.1.1-dev-5676146.0 - resolution: "@agoric/base-zone@npm:0.1.1-dev-5676146.0" +"@agoric/notifier@npm:0.6.3-dev-d7c994b.0+d7c994b": + version: 0.6.3-dev-d7c994b.0 + resolution: "@agoric/notifier@npm:0.6.3-dev-d7c994b.0" dependencies: - "@agoric/store": "npm:0.9.3-dev-5676146.0+5676146" - "@endo/common": "npm:^1.1.0" - "@endo/exo": "npm:^1.2.1" - "@endo/far": "npm:^1.0.4" - "@endo/pass-style": "npm:^1.2.0" - "@endo/patterns": "npm:^1.2.0" - checksum: 10c0/b3dfa47af7cf4a686244e2a31243394b44756f127a7612f5d50c77b1a91f777514386c305866705b46219d2d1e0df2b8d5bff9e08f82275043bb0c198c0601e4 + "@agoric/internal": "npm:0.3.3-dev-d7c994b.0+d7c994b" + "@agoric/vat-data": "npm:0.5.3-dev-d7c994b.0+d7c994b" + "@endo/errors": "npm:^1.2.7" + "@endo/far": "npm:^1.1.8" + "@endo/marshal": "npm:^1.6.1" + "@endo/patterns": "npm:^1.4.6" + "@endo/promise-kit": "npm:^1.1.7" + checksum: 10c0/93951f38ea10f5eef09e0aa89db8e9bbd0579f8ed14fd0161701c2eb3070c25138b2076e7c101c53e36ecbf1da7cf477cc1c1d5e520f8107a0e5ebf02aa9796f languageName: node linkType: hard -"@agoric/internal@npm:0.3.3-dev-5676146.0": - version: 0.3.3-dev-5676146.0 - resolution: "@agoric/internal@npm:0.3.3-dev-5676146.0" +"@agoric/store@npm:0.9.3-dev-d7c994b.0+d7c994b, @agoric/store@npm:dev": + version: 0.9.3-dev-d7c994b.0 + resolution: "@agoric/store@npm:0.9.3-dev-d7c994b.0" dependencies: - "@agoric/assert": "npm:0.6.1-dev-5676146.0+5676146" - "@agoric/base-zone": "npm:0.1.1-dev-5676146.0+5676146" - "@endo/common": "npm:^1.1.0" - "@endo/far": "npm:^1.0.4" - "@endo/init": "npm:^1.0.4" - "@endo/marshal": "npm:^1.3.0" - "@endo/patterns": "npm:^1.2.0" - "@endo/promise-kit": "npm:^1.0.4" - "@endo/stream": "npm:^1.1.0" - anylogger: "npm:^0.21.0" - jessie.js: "npm:^0.3.2" - checksum: 10c0/cd2a81ff39790a1b333621b3815f0791b70d0822f201d491175e46602697c80814f1fb87a610167e541a9ad431a771cd7348afe24517a15c45d1591d3d494bc2 + "@endo/errors": "npm:^1.2.7" + "@endo/exo": "npm:^1.5.6" + "@endo/marshal": "npm:^1.6.1" + "@endo/pass-style": "npm:^1.4.6" + "@endo/patterns": "npm:^1.4.6" + checksum: 10c0/0d90e03e71dd3f9a152308b0d3ebfe9a5e31e56bf47dcd1e7c58c38dba52ecf72279aa04c44c4f4e1570428b3828419cc59b1072c3346f9fed502a8828dae0b0 languageName: node linkType: hard -"@agoric/store@npm:0.9.3-dev-5676146.0+5676146": - version: 0.9.3-dev-5676146.0 - resolution: "@agoric/store@npm:0.9.3-dev-5676146.0" +"@agoric/swingset-liveslots@npm:0.10.3-dev-d7c994b.0+d7c994b": + version: 0.10.3-dev-d7c994b.0 + resolution: "@agoric/swingset-liveslots@npm:0.10.3-dev-d7c994b.0" dependencies: - "@endo/exo": "npm:^1.2.1" - "@endo/marshal": "npm:^1.3.0" - "@endo/pass-style": "npm:^1.2.0" - "@endo/patterns": "npm:^1.2.0" - checksum: 10c0/675e73bbcac024c456b658583ec3fd14a50f69fea5fc07aadf30e593978e5cadbc82d365b13976967b5509614a7adf0adad4e84712f7e0b6c13f2a2a93c9ea63 + "@agoric/internal": "npm:0.3.3-dev-d7c994b.0+d7c994b" + "@agoric/store": "npm:0.9.3-dev-d7c994b.0+d7c994b" + "@endo/env-options": "npm:^1.1.7" + "@endo/errors": "npm:^1.2.7" + "@endo/eventual-send": "npm:^1.2.7" + "@endo/exo": "npm:^1.5.6" + "@endo/far": "npm:^1.1.8" + "@endo/init": "npm:^1.1.6" + "@endo/marshal": "npm:^1.6.1" + "@endo/nat": "npm:^5.0.12" + "@endo/pass-style": "npm:^1.4.6" + "@endo/patterns": "npm:^1.4.6" + "@endo/promise-kit": "npm:^1.1.7" + checksum: 10c0/ab846647342126e6c0f16a1709c938a75c4e75f4cfffeaeeef70ec33e193ade258d18ee748cfa220e6e38239c79692b6a6ae082facaf95519b0485d711a14a7e languageName: node linkType: hard @@ -72,167 +123,194 @@ __metadata: languageName: node linkType: hard -"@endo/base64@npm:^1.0.7": - version: 1.0.7 - resolution: "@endo/base64@npm:1.0.7" - checksum: 10c0/aab10f433f8ea588ebd1786188b6660c0be3a743c119ef2df52ee23afd4ce3844b1d954028952569a747f6657287aeced875afe8e136ea8bff4ba146a60578bd +"@agoric/vat-data@npm:0.5.3-dev-d7c994b.0+d7c994b": + version: 0.5.3-dev-d7c994b.0 + resolution: "@agoric/vat-data@npm:0.5.3-dev-d7c994b.0" + dependencies: + "@agoric/base-zone": "npm:0.1.1-dev-d7c994b.0+d7c994b" + "@agoric/store": "npm:0.9.3-dev-d7c994b.0+d7c994b" + "@agoric/swingset-liveslots": "npm:0.10.3-dev-d7c994b.0+d7c994b" + "@endo/errors": "npm:^1.2.7" + "@endo/exo": "npm:^1.5.6" + "@endo/patterns": "npm:^1.4.6" + checksum: 10c0/860280ad7f09f499d8fea3d494c787748571a12b2e636c53762924064c9ea2e6c0e7fbe50c41f804f981f32066d82d3ff0a733c58276df180e5670b5b382a79f languageName: node linkType: hard -"@endo/common@npm:^1.1.0, @endo/common@npm:^1.2.5": - version: 1.2.5 - resolution: "@endo/common@npm:1.2.5" +"@agoric/zone@npm:0.2.3-dev-d7c994b.0+d7c994b": + version: 0.2.3-dev-d7c994b.0 + resolution: "@agoric/zone@npm:0.2.3-dev-d7c994b.0" dependencies: - "@endo/errors": "npm:^1.2.5" - "@endo/eventual-send": "npm:^1.2.5" - "@endo/promise-kit": "npm:^1.1.5" - checksum: 10c0/104ca2febd87d05b97a77037cb0f281157082b722a39f3fbfca94e36984ad8bc8622e900aeba861d7ed6e6b5d103971599ec2b804eb236537576d498f9ab1fe5 + "@agoric/base-zone": "npm:0.1.1-dev-d7c994b.0+d7c994b" + "@agoric/vat-data": "npm:0.5.3-dev-d7c994b.0+d7c994b" + "@endo/errors": "npm:^1.2.7" + "@endo/far": "npm:^1.1.8" + "@endo/pass-style": "npm:^1.4.6" + checksum: 10c0/ac5cbe949e81048cbaf08b1e5ad5a91c3693a0516d21214e7638b04a2a352e531221f8d1ae1b05b4506a34ea0de2f707a36c9147268082bada887d3df99fcc84 languageName: node linkType: hard -"@endo/env-options@npm:^1.1.6": - version: 1.1.6 - resolution: "@endo/env-options@npm:1.1.6" - checksum: 10c0/0001b1cba6954cccfa40104f819378f2f5c8babc89103213a8a5da4f8f94248c8389bfa06ec37cecae81edabe570428558399313d649c64ad7c90743f563dea2 +"@endo/base64@npm:^1.0.8": + version: 1.0.8 + resolution: "@endo/base64@npm:1.0.8" + checksum: 10c0/3501efbf866acc25b9ad0912ec2383e3b976c890a18dc67b5c6eb128433708db69e8ed1cc57190305266bdcbd132659aa87edfc6d02a9886b711e8b86adc21c0 languageName: node linkType: hard -"@endo/errors@npm:^1.2.2, @endo/errors@npm:^1.2.5": - version: 1.2.5 - resolution: "@endo/errors@npm:1.2.5" +"@endo/common@npm:^1.2.7": + version: 1.2.7 + resolution: "@endo/common@npm:1.2.7" dependencies: - ses: "npm:^1.8.0" - checksum: 10c0/32eac3b332139ddec8a85a0013645482541e4f3cc0c484073dde430087f27bb683cde8b0a6e399c5b7f07af007c3b6aa589cf31935a8b8d69e5f869bf71a1662 + "@endo/errors": "npm:^1.2.7" + "@endo/eventual-send": "npm:^1.2.7" + "@endo/promise-kit": "npm:^1.1.7" + checksum: 10c0/2bd25ffc528afd6308b6168650583977139c64e56547b3ea2fee313e01650fb1a041d7b7ce54c6bb70f26c9e78345db2a50fbe3ebccabe9a5c5696eda2cca706 + languageName: node + linkType: hard + +"@endo/env-options@npm:^1.1.7": + version: 1.1.7 + resolution: "@endo/env-options@npm:1.1.7" + checksum: 10c0/5784bd68790041b08d9ead4f6c29cc7871d2e554c23fc44fff38cb20b6b4e55cdba2f78d844ba5ad4b0818185c32475ff318c1b77890d628690d7c7a6ede9475 languageName: node linkType: hard -"@endo/eventual-send@npm:^1.2.5": - version: 1.2.5 - resolution: "@endo/eventual-send@npm:1.2.5" +"@endo/errors@npm:^1.2.2, @endo/errors@npm:^1.2.7": + version: 1.2.7 + resolution: "@endo/errors@npm:1.2.7" dependencies: - "@endo/env-options": "npm:^1.1.6" - checksum: 10c0/7eaa30628582f768920659e4894b871c1056da4252b82b8ad70ed49a24c4559efb8d1655a6845984a0eae83d328179e4272b0917007a2f147dc8b15ecb0ecc52 + ses: "npm:^1.9.1" + checksum: 10c0/17eed5d01dd968d8e266db37ac44e76859d14894a2b70457d120f2f05021819671aaf1bdf7dc7c2506b84f6df616402e029695d62309fbdbdd13ed4ba34890dd languageName: node linkType: hard -"@endo/exo@npm:^1.2.1": - version: 1.5.3 - resolution: "@endo/exo@npm:1.5.3" +"@endo/eventual-send@npm:^1.2.7": + version: 1.2.7 + resolution: "@endo/eventual-send@npm:1.2.7" dependencies: - "@endo/common": "npm:^1.2.5" - "@endo/env-options": "npm:^1.1.6" - "@endo/errors": "npm:^1.2.5" - "@endo/eventual-send": "npm:^1.2.5" - "@endo/far": "npm:^1.1.5" - "@endo/pass-style": "npm:^1.4.3" - "@endo/patterns": "npm:^1.4.3" - checksum: 10c0/5510bc442730910ce2470c6ebdb6c04208c033e452cd60c8684e1769039453ad5f47de31b00629be3c6bf4183bee4a421bace142144e92740b606c591a839c72 + "@endo/env-options": "npm:^1.1.7" + checksum: 10c0/4a483169bcd9ead47a7a07d3f69bdebdc0d1e2a3198f35ad422b82c1646b64528234bdddc9e0544ac38c2ede84a50af1e126eb4086aa8b4ae4b0002895b55e86 languageName: node linkType: hard -"@endo/far@npm:^1.0.0, @endo/far@npm:^1.0.4, @endo/far@npm:^1.1.5": - version: 1.1.5 - resolution: "@endo/far@npm:1.1.5" +"@endo/exo@npm:^1.5.6": + version: 1.5.6 + resolution: "@endo/exo@npm:1.5.6" dependencies: - "@endo/errors": "npm:^1.2.5" - "@endo/eventual-send": "npm:^1.2.5" - "@endo/pass-style": "npm:^1.4.3" - checksum: 10c0/8c50a28323ab1078d0cb6fce1d7fc6da4884247d76585f37f960a2a7134fc7f293075effaae34b41801b7508a1f75d32304c19db0597709727853c4a87eb4999 + "@endo/common": "npm:^1.2.7" + "@endo/env-options": "npm:^1.1.7" + "@endo/errors": "npm:^1.2.7" + "@endo/eventual-send": "npm:^1.2.7" + "@endo/far": "npm:^1.1.8" + "@endo/pass-style": "npm:^1.4.6" + "@endo/patterns": "npm:^1.4.6" + checksum: 10c0/280fe019ec6006f5649b40093453c4ecaa71dfdcbb9767efc9f0ed4fc23081b120818c4a12896e8ec2221444889031736b569229117834048d596ecb09a44057 languageName: node linkType: hard -"@endo/init@npm:^1.0.4, @endo/init@npm:^1.1.4": - version: 1.1.4 - resolution: "@endo/init@npm:1.1.4" +"@endo/far@npm:^1.0.0, @endo/far@npm:^1.1.5, @endo/far@npm:^1.1.8": + version: 1.1.8 + resolution: "@endo/far@npm:1.1.8" dependencies: - "@endo/base64": "npm:^1.0.7" - "@endo/eventual-send": "npm:^1.2.5" - "@endo/lockdown": "npm:^1.0.10" - "@endo/promise-kit": "npm:^1.1.5" - checksum: 10c0/9e915b3b888b7a9f1d563d532ad180dea987253d71e79eda1fcda8d287391611bcca369f2d9b89c59b9f24b3adc548816954e8eaefa4f7402c68585245a686a5 + "@endo/errors": "npm:^1.2.7" + "@endo/eventual-send": "npm:^1.2.7" + "@endo/pass-style": "npm:^1.4.6" + checksum: 10c0/efb0f063e7a19fd67fe150e0a018a9e4b2abd5238b3c3d136830732aa3294bdb829c1a920607360c285eb6e3a3ae5337b6a1e9847cfcf5618247431af02c5a1e languageName: node linkType: hard -"@endo/lockdown@npm:^1.0.10": - version: 1.0.10 - resolution: "@endo/lockdown@npm:1.0.10" +"@endo/init@npm:^1.1.4, @endo/init@npm:^1.1.6": + version: 1.1.6 + resolution: "@endo/init@npm:1.1.6" dependencies: - ses: "npm:^1.8.0" - checksum: 10c0/94be0c1b14cacb2d8088dcc17998e901159a028c51170d78a8cc6a820ae76cabc7d2694f1a1956cb4eab70a8c9a0c8254d88ea4c3f3d9725b739aacf6db83d5b + "@endo/base64": "npm:^1.0.8" + "@endo/eventual-send": "npm:^1.2.7" + "@endo/lockdown": "npm:^1.0.12" + "@endo/promise-kit": "npm:^1.1.7" + checksum: 10c0/1885429e475c780bb5b7ff0fd4fcd5d76bc3a5cb1c3c2f9f2dfc06152ff1c8c3be512b6760483c8c18598e1977129cb3dd766a32c9f6efb19d70b54a1844c683 languageName: node linkType: hard -"@endo/marshal@npm:^1.3.0, @endo/marshal@npm:^1.5.3": - version: 1.5.3 - resolution: "@endo/marshal@npm:1.5.3" +"@endo/lockdown@npm:^1.0.12": + version: 1.0.12 + resolution: "@endo/lockdown@npm:1.0.12" dependencies: - "@endo/common": "npm:^1.2.5" - "@endo/errors": "npm:^1.2.5" - "@endo/eventual-send": "npm:^1.2.5" - "@endo/nat": "npm:^5.0.10" - "@endo/pass-style": "npm:^1.4.3" - "@endo/promise-kit": "npm:^1.1.5" - checksum: 10c0/05f4fceef7727971d3d2a1b8d87f4d9c6651772f9d231e2daa36c3ed0b0e13c3b8d26cb4828ecaadf4329bf77792a293507eadcff7a61df292d4e390936993d1 + ses: "npm:^1.9.1" + checksum: 10c0/0b9d36f359ffe8eadd1e799aa0340ccb0680d48c9b6249c380c27724824c4d875dada9fbec096fb4e2ac76b32c7536955524d3eb6579451a618707602fb958f4 languageName: node linkType: hard -"@endo/nat@npm:^5.0.10": - version: 5.0.10 - resolution: "@endo/nat@npm:5.0.10" - checksum: 10c0/7ad2aa2d216d517409c771aebb465aceb6ea8b88ec808c2dc030d7ffc7fe7d601d8401572f3866384a63ff2aa74209a22f29e1561e773d91d7ad2d81fa13fc7e +"@endo/marshal@npm:^1.5.3, @endo/marshal@npm:^1.6.1": + version: 1.6.1 + resolution: "@endo/marshal@npm:1.6.1" + dependencies: + "@endo/common": "npm:^1.2.7" + "@endo/errors": "npm:^1.2.7" + "@endo/eventual-send": "npm:^1.2.7" + "@endo/nat": "npm:^5.0.12" + "@endo/pass-style": "npm:^1.4.6" + "@endo/promise-kit": "npm:^1.1.7" + checksum: 10c0/e64983abccd833b2a7eb63547e8c5a629f073d3e422229475d470ace95c2640a89e9a9879c46e8389cca8c9e75823ea1c27e27cbeeb8c1c4005146b2c530c530 languageName: node linkType: hard -"@endo/pass-style@npm:^1.2.0, @endo/pass-style@npm:^1.4.3": - version: 1.4.3 - resolution: "@endo/pass-style@npm:1.4.3" +"@endo/nat@npm:^5.0.12": + version: 5.0.12 + resolution: "@endo/nat@npm:5.0.12" + checksum: 10c0/deb792b6a0c9fe9c0e7cf74cc725d8bc36934571f4f06ac3b6def2a0622ac79b0278753c574f9b55a88b063d1186fd6971bbe63326077a7d37982c4c37a1a24c + languageName: node + linkType: hard + +"@endo/pass-style@npm:^1.4.6": + version: 1.4.6 + resolution: "@endo/pass-style@npm:1.4.6" dependencies: - "@endo/env-options": "npm:^1.1.6" - "@endo/errors": "npm:^1.2.5" - "@endo/eventual-send": "npm:^1.2.5" - "@endo/promise-kit": "npm:^1.1.5" + "@endo/env-options": "npm:^1.1.7" + "@endo/errors": "npm:^1.2.7" + "@endo/eventual-send": "npm:^1.2.7" + "@endo/promise-kit": "npm:^1.1.7" "@fast-check/ava": "npm:^1.1.5" - checksum: 10c0/f24c528b1219f5aa122f9a04e80459dec3e9664e7849019b172ad8354870b849b643c8dfc79104857827457d66b2bb09bade9b2c6ea717a97e613ecf6d53c1f9 + checksum: 10c0/fec9d21bb4c70314e92c72f7ae41ec147ac839a23d54f613d689b84f81206e49e657f3fb414db454cbd6ab67dd2a319b1ae25c42b3a1c881edd5de120496b8b4 languageName: node linkType: hard -"@endo/patterns@npm:^1.2.0, @endo/patterns@npm:^1.4.3": - version: 1.4.3 - resolution: "@endo/patterns@npm:1.4.3" +"@endo/patterns@npm:^1.4.6": + version: 1.4.6 + resolution: "@endo/patterns@npm:1.4.6" dependencies: - "@endo/common": "npm:^1.2.5" - "@endo/errors": "npm:^1.2.5" - "@endo/eventual-send": "npm:^1.2.5" - "@endo/marshal": "npm:^1.5.3" - "@endo/promise-kit": "npm:^1.1.5" - checksum: 10c0/10aabc6459d1b5d26e8946ab1b88db23eda80231aa6a0b6c9835568eee1daf745d23c29fa7f202bf11859a7ae77d5f51071c3d863d34e259a62c382ec797bb03 + "@endo/common": "npm:^1.2.7" + "@endo/errors": "npm:^1.2.7" + "@endo/eventual-send": "npm:^1.2.7" + "@endo/marshal": "npm:^1.6.1" + "@endo/promise-kit": "npm:^1.1.7" + checksum: 10c0/518cf4f88ff6aaf6c9df01fbe9f63570aaace763f2a169f986145b039cbd872802154b21736f751fc4cce497d3380aa6be41d2d51e169c8e63a1edb1751d1808 languageName: node linkType: hard -"@endo/promise-kit@npm:^1.0.4, @endo/promise-kit@npm:^1.1.5": - version: 1.1.5 - resolution: "@endo/promise-kit@npm:1.1.5" +"@endo/promise-kit@npm:^1.1.7": + version: 1.1.7 + resolution: "@endo/promise-kit@npm:1.1.7" dependencies: - ses: "npm:^1.8.0" - checksum: 10c0/3a9fb59546507dbbb8c83ada4de664ca4f6085ffcb56c9e3e07789e002e717454b1ee5ae1273549935a7e77ac42be7ae8ddca94ff6d4f16914210d31159ce1a4 + ses: "npm:^1.9.1" + checksum: 10c0/98a8d743c437f106f266871874acd811c0e028fc89553738bbd46a0fea5871b9ba7ef0449ec38e7e3768fc21684993ecdbbd06f5f3429cd69fbe4b867d4c2bd5 languageName: node linkType: hard -"@endo/stream@npm:^1.1.0": - version: 1.2.5 - resolution: "@endo/stream@npm:1.2.5" +"@endo/stream@npm:^1.2.7": + version: 1.2.7 + resolution: "@endo/stream@npm:1.2.7" dependencies: - "@endo/eventual-send": "npm:^1.2.5" - "@endo/promise-kit": "npm:^1.1.5" - ses: "npm:^1.8.0" - checksum: 10c0/625fd9b8b485149c269a01673b76b33fadd0702d76eb37f136c9f7558252e3d51cc9602b2880f1b43971a00f41e5d3e3d2b3a6ebef6f0253bb314d9a144a2cf5 + "@endo/eventual-send": "npm:^1.2.7" + "@endo/promise-kit": "npm:^1.1.7" + ses: "npm:^1.9.1" + checksum: 10c0/d96a2350200cc76ede5eed49e5d780d6d21f63007b42a83658bf5174e7b61e96bfe6b8f11ed2d33ad7f9eb6c3ec2db2a79079bc1679260ac7dac04a34a4a515e languageName: node linkType: hard "@endo/zip@npm:^1.0.7": - version: 1.0.7 - resolution: "@endo/zip@npm:1.0.7" - checksum: 10c0/a1c0d155448ce877012b34c8fe8cd3a58de9eb807514c81cddeebb802ee8e552b27d8a9a40fab3f3e4c49e0cb7fea6902fa1dd12a23ff6f30b56161fc3edc1f8 + version: 1.0.8 + resolution: "@endo/zip@npm:1.0.8" + checksum: 10c0/bb74862121932cd27eef59326325c4b61671ce0962033a2ad18e6d6978a9e94bfe604dbfa8c0b039a38fa7eefc495e6a69c583c0e75929cd267979b2c65b775b languageName: node linkType: hard @@ -476,24 +554,24 @@ __metadata: linkType: hard "@npmcli/agent@npm:^2.0.0": - version: 2.2.0 - resolution: "@npmcli/agent@npm:2.2.0" + version: 2.2.2 + resolution: "@npmcli/agent@npm:2.2.2" 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 + socks-proxy-agent: "npm:^8.0.3" + checksum: 10c0/325e0db7b287d4154ecd164c0815c08007abfb07653cc57bceded17bb7fd240998a3cbdbe87d700e30bef494885eccc725ab73b668020811d56623d145b524ae languageName: node linkType: hard "@npmcli/fs@npm:^3.1.0": - version: 3.1.0 - resolution: "@npmcli/fs@npm:3.1.0" + version: 3.1.1 + resolution: "@npmcli/fs@npm:3.1.1" dependencies: semver: "npm:^7.3.5" - checksum: 10c0/162b4a0b8705cd6f5c2470b851d1dc6cd228c86d2170e1769d738c1fbb69a87160901411c3c035331e9e99db72f1f1099a8b734bf1637cc32b9a5be1660e4e1e + checksum: 10c0/c37a5b4842bfdece3d14dfdb054f73fe15ed2d3da61b34ff76629fb5b1731647c49166fd2a8bf8b56fcfa51200382385ea8909a3cbecdad612310c114d3f6c99 languageName: node linkType: hard @@ -535,25 +613,25 @@ __metadata: languageName: node linkType: hard -"@vercel/nft@npm:^0.26.2": - version: 0.26.4 - resolution: "@vercel/nft@npm:0.26.4" +"@vercel/nft@npm:^0.27.5": + version: 0.27.5 + resolution: "@vercel/nft@npm:0.27.5" 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" + acorn-import-attributes: "npm:^1.9.5" 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" + micromatch: "npm:^4.0.8" node-gyp-build: "npm:^4.2.2" resolve-from: "npm:^5.0.0" bin: nft: out/cli.js - checksum: 10c0/d347fcd7f5371a83362732d0b1b80b9471a2ed3917d6324cc6037392099d6bdc8eae69f0db61bafc87ba2d62af03ef21efe62a7eb52c8eb20341ebcb58903f0d + checksum: 10c0/24455056df4330c9709400e0f9bd5c25870a7694256ef2f1e0812d3435386db3b95a7c7a57f4d74774b081eaf225d4afbf2bd891ce82f9b3e14da10b413538fe languageName: node linkType: hard @@ -571,7 +649,7 @@ __metadata: languageName: node linkType: hard -"acorn-import-attributes@npm:^1.9.2": +"acorn-import-attributes@npm:^1.9.5": version: 1.9.5 resolution: "acorn-import-attributes@npm:1.9.5" peerDependencies: @@ -580,19 +658,21 @@ __metadata: languageName: node linkType: hard -"acorn-walk@npm:^8.3.2": - version: 8.3.2 - resolution: "acorn-walk@npm:8.3.2" - checksum: 10c0/7e2a8dad5480df7f872569b9dccff2f3da7e65f5353686b1d6032ab9f4ddf6e3a2cb83a9b52cf50b1497fd522154dda92f0abf7153290cc79cd14721ff121e52 +"acorn-walk@npm:^8.3.4": + version: 8.3.4 + resolution: "acorn-walk@npm:8.3.4" + dependencies: + acorn: "npm:^8.11.0" + checksum: 10c0/76537ac5fb2c37a64560feaf3342023dadc086c46da57da363e64c6148dc21b57d49ace26f949e225063acb6fb441eabffd89f7a3066de5ad37ab3e328927c62 languageName: node linkType: hard -"acorn@npm:^8.11.3, acorn@npm:^8.6.0": - version: 8.11.3 - resolution: "acorn@npm:8.11.3" +"acorn@npm:^8.11.0, acorn@npm:^8.13.0, acorn@npm:^8.6.0": + version: 8.14.0 + resolution: "acorn@npm:8.14.0" bin: acorn: bin/acorn - checksum: 10c0/3ff155f8812e4a746fee8ecff1f227d527c4c45655bb1fad6347c3cb58e46190598217551b1500f18542d2bbe5c87120cb6927f5a074a59166fbdd9468f0a299 + checksum: 10c0/6d4ee461a7734b2f48836ee0fbb752903606e576cc100eb49340295129ca0b452f3ba91ddd4424a1d4406a98adfb2ebb6bd0ff4c49d7a0930c10e462719bbfd7 languageName: node linkType: hard @@ -605,12 +685,12 @@ __metadata: 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" +"agent-base@npm:^7.0.2, agent-base@npm:^7.1.0, agent-base@npm:^7.1.1": + version: 7.1.1 + resolution: "agent-base@npm:7.1.1" dependencies: debug: "npm:^4.3.4" - checksum: 10c0/fc974ab57ffdd8421a2bc339644d312a9cca320c20c3393c9d8b1fd91731b9bbabdb985df5fc860f5b79d81c3e350daa3fcb31c5c07c0bb385aafc817df004ce + checksum: 10c0/e59ce7bed9c63bf071a30cc471f2933862044c97fd9958967bfe22521d7a0f601ce4ed5a8c011799d0c726ca70312142ae193bbebb60f576b52be19d4a363b50 languageName: node linkType: hard @@ -632,9 +712,9 @@ __metadata: linkType: hard "ansi-regex@npm:^6.0.1": - version: 6.0.1 - resolution: "ansi-regex@npm:6.0.1" - checksum: 10c0/cbe16dbd2c6b2735d1df7976a7070dd277326434f0212f43abf6d87674095d247968209babdaad31bb00882fa68807256ba9be340eec2f1004de14ca75f52a08 + version: 6.1.0 + resolution: "ansi-regex@npm:6.1.0" + checksum: 10c0/a91daeddd54746338478eef88af3439a7edf30f8e23196e2d6ed182da9add559c601266dbef01c2efa46a958ad6f1f8b176799657616c702b5b02e799e7fd8dc languageName: node linkType: hard @@ -716,17 +796,17 @@ __metadata: linkType: hard "ava@npm:^6.1.2": - version: 6.1.2 - resolution: "ava@npm:6.1.2" + version: 6.2.0 + resolution: "ava@npm:6.2.0" dependencies: - "@vercel/nft": "npm:^0.26.2" - acorn: "npm:^8.11.3" - acorn-walk: "npm:^8.3.2" + "@vercel/nft": "npm:^0.27.5" + acorn: "npm:^8.13.0" + acorn-walk: "npm:^8.3.4" 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" + callsites: "npm:^4.2.0" + cbor: "npm:^9.0.2" chalk: "npm:^5.3.0" chunkd: "npm:^2.0.1" ci-info: "npm:^4.0.0" @@ -736,10 +816,10 @@ __metadata: 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" + debug: "npm:^4.3.7" + emittery: "npm:^1.0.3" + figures: "npm:^6.1.0" + globby: "npm:^14.0.2" ignore-by-default: "npm:^2.1.0" indent-string: "npm:^5.0.0" is-plain-object: "npm:^5.0.0" @@ -747,17 +827,17 @@ __metadata: matcher: "npm:^5.0.0" memoize: "npm:^10.0.0" ms: "npm:^2.1.3" - p-map: "npm:^7.0.1" + p-map: "npm:^7.0.2" package-config: "npm:^5.0.0" - picomatch: "npm:^3.0.1" + picomatch: "npm:^4.0.2" plur: "npm:^5.1.0" - pretty-ms: "npm:^9.0.0" + pretty-ms: "npm:^9.1.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" + write-file-atomic: "npm:^6.0.0" yargs: "npm:^17.7.2" peerDependencies: "@ava/typescript": "*" @@ -766,7 +846,7 @@ __metadata: optional: true bin: ava: entrypoints/cli.mjs - checksum: 10c0/f35cb1f9bc716714e7c78a601985745774096e4ecd34f9310b858d5779307afa2245ad24274e2d55dd1022c226f4fbdb41947476300977f0b653be0e627adaa4 + checksum: 10c0/25a37413c9ee1b5322dc5a266f546236ea4b52e5c04ae4b52a7b26db9263eebe2dbcda687bf4d464867e558e9148e4567aa09a7ec91d46e3218ab93204e3c653 languageName: node linkType: hard @@ -841,12 +921,12 @@ __metadata: languageName: node linkType: hard -"braces@npm:^3.0.2": - version: 3.0.2 - resolution: "braces@npm:3.0.2" +"braces@npm:^3.0.3": + version: 3.0.3 + resolution: "braces@npm:3.0.3" dependencies: - fill-range: "npm:^7.0.1" - checksum: 10c0/321b4d675791479293264019156ca322163f02dc06e3c4cab33bb15cd43d80b51efef69b0930cfde3acd63d126ebca24cd0544fa6f261e093a0fb41ab9dda381 + fill-range: "npm:^7.1.1" + checksum: 10c0/7c6dfd30c338d2997ba77500539227b9d1f85e388a5f43220865201e407e076783d0881f2d297b9f80951b4c957fcf0b51c1d2d24227631643c3f7c284b0aa04 languageName: node linkType: hard @@ -861,8 +941,8 @@ __metadata: linkType: hard "cacache@npm:^18.0.0": - version: 18.0.1 - resolution: "cacache@npm:18.0.1" + version: 18.0.4 + resolution: "cacache@npm:18.0.4" dependencies: "@npmcli/fs": "npm:^3.1.0" fs-minipass: "npm:^3.0.0" @@ -876,18 +956,18 @@ __metadata: ssri: "npm:^10.0.0" tar: "npm:^6.1.11" unique-filename: "npm:^3.0.0" - checksum: 10c0/a31666805a80a8b16ad3f85faf66750275a9175a3480896f4f6d31b5d53ef190484fabd71bdb6d2ea5603c717fbef09f4af03d6a65b525c8ef0afaa44c361866 + checksum: 10c0/6c055bafed9de4f3dcc64ac3dc7dd24e863210902b7c470eb9ce55a806309b3efff78033e3d8b4f7dcc5d467f2db43c6a2857aaaf26f0094b8a351d44c42179f languageName: node linkType: hard -"callsites@npm:^4.1.0": - version: 4.1.0 - resolution: "callsites@npm:4.1.0" - checksum: 10c0/91700844127a6dcd4792d231a12dd8e9ec10525eb9962180a8558417d7e3f443e52a4f14746ad2838eaf14f79431ee1539d13bd188da280f720a06a91bd1157a +"callsites@npm:^4.2.0": + version: 4.2.0 + resolution: "callsites@npm:4.2.0" + checksum: 10c0/8f7e269ec09fc0946bb22d838a8bc7932e1909ab4a833b964749f4d0e8bdeaa1f253287c4f911f61781f09620b6925ccd19a5ea4897489c4e59442c660c312a3 languageName: node linkType: hard -"cbor@npm:^9.0.1": +"cbor@npm:^9.0.2": version: 9.0.2 resolution: "cbor@npm:9.0.2" dependencies: @@ -1080,15 +1160,15 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:^4.3.4": - version: 4.3.4 - resolution: "debug@npm:4.3.4" +"debug@npm:4, debug@npm:^4.3.4, debug@npm:^4.3.7": + version: 4.3.7 + resolution: "debug@npm:4.3.7" dependencies: - ms: "npm:2.1.2" + ms: "npm:^2.1.3" peerDependenciesMeta: supports-color: optional: true - checksum: 10c0/cedbec45298dd5c501d01b92b119cd3faebe5438c3917ff11ae1bff86a6c722930ac9c8659792824013168ba6db7c4668225d845c633fbdafbbf902a6389f736 + checksum: 10c0/1471db19c3b06d485a622d62f65947a19a23fbd0dd73f7fd3eafb697eec5360cde447fb075919987899b1a2096e85d35d4eb5a4de09a57600ac9cf7e6c8e768b languageName: node linkType: hard @@ -1116,9 +1196,9 @@ __metadata: linkType: hard "detect-libc@npm:^2.0.0": - version: 2.0.2 - resolution: "detect-libc@npm:2.0.2" - checksum: 10c0/a9f4ffcd2701525c589617d98afe5a5d0676c8ea82bcc4ed6f3747241b79f781d36437c59a5e855254c864d36a3e9f8276568b6b531c28d6e53b093a15703f11 + version: 2.0.3 + resolution: "detect-libc@npm:2.0.3" + checksum: 10c0/88095bda8f90220c95f162bf92cad70bd0e424913e655c20578600e35b91edc261af27531cf160a331e185c0ced93944bc7e09939143225f56312d7fd800fdb7 languageName: node linkType: hard @@ -1129,17 +1209,17 @@ __metadata: languageName: node linkType: hard -"emittery@npm:^1.0.1": - version: 1.0.1 - resolution: "emittery@npm:1.0.1" - checksum: 10c0/2587f2f42bb5e004ba1cde61352d2151f4dd4f29eb79ad36f82e200da2faec9742d7bfca1492a024d60396e001e4b07d9b2b9c43be33547ff751ba8ff87c42ce +"emittery@npm:^1.0.3": + version: 1.0.3 + resolution: "emittery@npm:1.0.3" + checksum: 10c0/91605d044f3891dd1f8ab731aeb94b520488b21e707f7064dcbcf5303bac3b4e7133dfa23c343ede1fc970340bd78a9b1aed522b805bc15104606bba630dd71e languageName: node linkType: hard "emoji-regex@npm:^10.3.0": - version: 10.3.0 - resolution: "emoji-regex@npm:10.3.0" - checksum: 10c0/b4838e8dcdceb44cf47f59abe352c25ff4fe7857acaf5fb51097c427f6f75b44d052eb907a7a3b86f86bc4eae3a93f5c2b7460abe79c407307e6212d65c91163 + version: 10.4.0 + resolution: "emoji-regex@npm:10.4.0" + checksum: 10c0/a3fcedfc58bfcce21a05a5f36a529d81e88d602100145fcca3dc6f795e3c8acc4fc18fe773fbf9b6d6e9371205edb3afa2668ec3473fa2aa7fd47d2a9d46482d languageName: node linkType: hard @@ -1273,9 +1353,9 @@ __metadata: linkType: hard "escalade@npm:^3.1.1": - version: 3.1.1 - resolution: "escalade@npm:3.1.1" - checksum: 10c0/afd02e6ca91ffa813e1108b5e7756566173d6bc0d1eb951cb44d6b21702ec17c1cf116cfe75d4a2b02e05acb0b808a7a9387d0d1ca5cf9c04ad03a8445c3e46d + version: 3.2.0 + resolution: "escalade@npm:3.2.0" + checksum: 10c0/ced4dd3a78e15897ed3be74e635110bbf3b08877b0a41be50dcb325ee0e0b5f65fc2d50e9845194d7c4633f327e2e1c6cce00a71b617c5673df0374201d67f65 languageName: node linkType: hard @@ -1318,8 +1398,8 @@ __metadata: linkType: hard "execa@npm:^9.3.1": - version: 9.3.1 - resolution: "execa@npm:9.3.1" + version: 9.5.1 + resolution: "execa@npm:9.5.1" dependencies: "@sindresorhus/merge-streams": "npm:^4.0.0" cross-spawn: "npm:^7.0.3" @@ -1328,12 +1408,12 @@ __metadata: human-signals: "npm:^8.0.0" is-plain-obj: "npm:^4.1.0" is-stream: "npm:^4.0.1" - npm-run-path: "npm:^5.2.0" + npm-run-path: "npm:^6.0.0" pretty-ms: "npm:^9.0.0" signal-exit: "npm:^4.1.0" strip-final-newline: "npm:^4.0.0" yoctocolors: "npm:^2.0.0" - checksum: 10c0/113979ff56575f6cb69fd021eb3894a674fb59b264f5e8c2b9b30e301629abc4f44cee881e680f9fb3b7d4956645df76a2d8c0006869dea985f96ec65f07b226 + checksum: 10c0/1a628d535c5a088f9e17a735bb3143efc4198095392b319ba877b2975d5c3c57724536dccb6f68f1cd9b3af331c5a9e8c1aeb338d52ab316b1e008ff453374a7 languageName: node linkType: hard @@ -1381,15 +1461,15 @@ __metadata: linkType: hard "fastq@npm:^1.6.0": - version: 1.15.0 - resolution: "fastq@npm:1.15.0" + version: 1.17.1 + resolution: "fastq@npm:1.17.1" dependencies: reusify: "npm:^1.0.4" - checksum: 10c0/5ce4f83afa5f88c9379e67906b4d31bc7694a30826d6cc8d0f0473c966929017fda65c2174b0ec89f064ede6ace6c67f8a4fe04cef42119b6a55b0d465554c24 + checksum: 10c0/1095f16cea45fb3beff558bb3afa74ca7a9250f5a670b65db7ed585f92b4b48381445cd328b3d87323da81e43232b5d5978a8201bde84e0cd514310f1ea6da34 languageName: node linkType: hard -"figures@npm:^6.0.1, figures@npm:^6.1.0": +"figures@npm:^6.1.0": version: 6.1.0 resolution: "figures@npm:6.1.0" dependencies: @@ -1405,12 +1485,12 @@ __metadata: languageName: node linkType: hard -"fill-range@npm:^7.0.1": - version: 7.0.1 - resolution: "fill-range@npm:7.0.1" +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" dependencies: to-regex-range: "npm:^5.0.1" - checksum: 10c0/7cdad7d426ffbaadf45aeb5d15ec675bbd77f7597ad5399e3d2766987ed20bda24d5fac64b3ee79d93276f5865608bb22344a26b9b1ae6c4d00bd94bf611623f + checksum: 10c0/b75b691bbe065472f38824f694c2f7449d7f5004aa950426a2c28f0306c60db9b880c0b0e4ed819997ffb882d1da02cfcfc819bddc94d71627f5269682edf018 languageName: node linkType: hard @@ -1422,12 +1502,12 @@ __metadata: linkType: hard "foreground-child@npm:^3.1.0": - version: 3.1.1 - resolution: "foreground-child@npm:3.1.1" + version: 3.3.0 + resolution: "foreground-child@npm:3.3.0" dependencies: cross-spawn: "npm:^7.0.0" signal-exit: "npm:^4.0.1" - checksum: 10c0/9700a0285628abaeb37007c9a4d92bd49f67210f09067638774338e146c8e9c825c5c877f072b2f75f41dc6a2d0be8664f79ffc03f6576649f54a84fb9b47de0 + checksum: 10c0/028f1d41000553fcfa6c4bb5c372963bf3d9bf0b1f25a87d1a6253014343fb69dfb1b42d9625d7cf44c8ba429940f3d0ff718b62105d4d4a4f6ef8ca0a53faa2 languageName: node linkType: hard @@ -1507,9 +1587,9 @@ __metadata: 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 + version: 1.3.0 + resolution: "get-east-asian-width@npm:1.3.0" + checksum: 10c0/1a049ba697e0f9a4d5514c4623781c5246982bdb61082da6b5ae6c33d838e52ce6726407df285cdbb27ec1908b333cf2820989bd3e986e37bb20979437fdf34b languageName: node linkType: hard @@ -1524,11 +1604,11 @@ __metadata: linkType: hard "get-tsconfig@npm:^4.7.5": - version: 4.7.6 - resolution: "get-tsconfig@npm:4.7.6" + version: 4.8.1 + resolution: "get-tsconfig@npm:4.8.1" dependencies: resolve-pkg-maps: "npm:^1.0.0" - checksum: 10c0/2240e1b13e996dfbb947d177f422f83d09d1f93c9ce16959ebb3c2bdf8bdf4f04f98eba043859172da1685f9c7071091f0acfa964ebbe4780394d83b7dc3f58a + checksum: 10c0/536ee85d202f604f4b5fb6be81bcd6e6d9a96846811e83e9acc6de4a04fb49506edea0e1b8cf1d5ee7af33e469916ec2809d4c5445ab8ae015a7a51fbd1572f9 languageName: node linkType: hard @@ -1549,17 +1629,18 @@ __metadata: linkType: hard "glob@npm:^10.2.2, glob@npm:^10.3.10": - version: 10.3.10 - resolution: "glob@npm:10.3.10" + version: 10.4.5 + resolution: "glob@npm:10.4.5" 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" + jackspeak: "npm:^3.1.2" + minimatch: "npm:^9.0.4" + minipass: "npm:^7.1.2" + package-json-from-dist: "npm:^1.0.0" + path-scurry: "npm:^1.11.1" bin: glob: dist/esm/bin.mjs - checksum: 10c0/13d8a1feb7eac7945f8c8480e11cd4a44b24d26503d99a8d8ac8d5aefbf3e9802a2b6087318a829fad04cb4e829f25c5f4f1110c68966c498720dd261c7e344d + checksum: 10c0/19a9759ea77b8e3ca0a43c2f07ecddc2ad46216b786bb8f993c445aee80d345925a21e5280c7b7c6c59e860a0154b84e4b2b60321fea92cd3c56b4a7489f160e languageName: node linkType: hard @@ -1577,9 +1658,9 @@ __metadata: languageName: node linkType: hard -"globby@npm:^14.0.0": - version: 14.0.1 - resolution: "globby@npm:14.0.1" +"globby@npm:^14.0.2": + version: 14.0.2 + resolution: "globby@npm:14.0.2" dependencies: "@sindresorhus/merge-streams": "npm:^2.1.0" fast-glob: "npm:^3.3.2" @@ -1587,7 +1668,7 @@ __metadata: path-type: "npm:^5.0.0" slash: "npm:^5.1.0" unicorn-magic: "npm:^0.1.0" - checksum: 10c0/749a6be91cf455c161ebb5c9130df3991cb9fd7568425db850a8279a6cf45acd031c5069395beb7aeb4dd606b64f0d6ff8116c93726178d8e6182fee58c2736d + checksum: 10c0/3f771cd683b8794db1e7ebc8b6b888d43496d93a82aad4e9d974620f578581210b6c5a6e75ea29573ed16a1345222fab6e9b877a8d1ed56eeb147e09f69c6f78 languageName: node linkType: hard @@ -1613,12 +1694,12 @@ __metadata: linkType: hard "http-proxy-agent@npm:^7.0.0": - version: 7.0.0 - resolution: "http-proxy-agent@npm:7.0.0" + version: 7.0.2 + resolution: "http-proxy-agent@npm:7.0.2" dependencies: agent-base: "npm:^7.1.0" debug: "npm:^4.3.4" - checksum: 10c0/a11574ff39436cee3c7bc67f259444097b09474605846ddd8edf0bf4ad8644be8533db1aa463426e376865047d05dc22755e638632819317c0c2f1b2196657c8 + checksum: 10c0/4207b06a4580fb85dd6dff521f0abf6db517489e70863dca1a0291daa7f2d3d2d6015a57bd702af068ea5cf9f1f6ff72314f5f5b4228d299c0904135d2aef921 languageName: node linkType: hard @@ -1633,12 +1714,12 @@ __metadata: linkType: hard "https-proxy-agent@npm:^7.0.1": - version: 7.0.2 - resolution: "https-proxy-agent@npm:7.0.2" + version: 7.0.5 + resolution: "https-proxy-agent@npm:7.0.5" dependencies: agent-base: "npm:^7.0.2" debug: "npm:4" - checksum: 10c0/7735eb90073db087e7e79312e3d97c8c04baf7ea7ca7b013382b6a45abbaa61b281041a98f4e13c8c80d88f843785bcc84ba189165b4b4087b1e3496ba656d77 + checksum: 10c0/2490e3acec397abeb88807db52cac59102d5ed758feee6df6112ab3ccd8325e8a1ce8bce6f4b66e5470eca102d31e425ace904242e4fa28dbe0c59c4bafa7b2c languageName: node linkType: hard @@ -1673,9 +1754,9 @@ __metadata: linkType: hard "ignore@npm:^5.2.4": - version: 5.3.0 - resolution: "ignore@npm:5.3.0" - checksum: 10c0/dc06bea5c23aae65d0725a957a0638b57e235ae4568dda51ca142053ed2c352de7e3bc93a69b2b32ac31966a1952e9a93c5ef2e2ab7c6b06aef9808f6b55b571 + version: 5.3.2 + resolution: "ignore@npm:5.3.2" + checksum: 10c0/f9f652c957983634ded1e7f02da3b559a0d4cc210fca3792cb67f1b153623c9c42efdc1c4121af171e295444459fc4a9201101fb041b1104a3c000bccb188337 languageName: node linkType: hard @@ -1724,10 +1805,13 @@ __metadata: languageName: node linkType: hard -"ip@npm:^2.0.0": - version: 2.0.0 - resolution: "ip@npm:2.0.0" - checksum: 10c0/8d186cc5585f57372847ae29b6eba258c68862055e18a75cc4933327232cb5c107f89800ce29715d542eef2c254fbb68b382e780a7414f9ee7caf60b7a473958 +"ip-address@npm:^9.0.5": + version: 9.0.5 + resolution: "ip-address@npm:9.0.5" + dependencies: + jsbn: "npm:1.1.0" + sprintf-js: "npm:^1.1.3" + checksum: 10c0/331cd07fafcb3b24100613e4b53e1a2b4feab11e671e655d46dc09ee233da5011284d09ca40c4ecbdfe1d0004f462958675c224a804259f2f78d2465a87824bc languageName: node linkType: hard @@ -1811,9 +1895,9 @@ __metadata: linkType: hard "is-unicode-supported@npm:^2.0.0": - version: 2.0.0 - resolution: "is-unicode-supported@npm:2.0.0" - checksum: 10c0/3013dfb8265fe9f9a0d1e9433fc4e766595631a8d85d60876c457b4bedc066768dab1477c553d02e2f626d88a4e019162706e04263c94d74994ef636a33b5f94 + version: 2.1.0 + resolution: "is-unicode-supported@npm:2.1.0" + checksum: 10c0/a0f53e9a7c1fdbcf2d2ef6e40d4736fdffff1c9f8944c75e15425118ff3610172c87bf7bc6c34d3903b04be59790bb2212ddbe21ee65b5a97030fc50370545a5 languageName: node linkType: hard @@ -1831,20 +1915,20 @@ __metadata: languageName: node linkType: hard -"jackspeak@npm:^2.3.5": - version: 2.3.6 - resolution: "jackspeak@npm:2.3.6" +"jackspeak@npm:^3.1.2": + version: 3.4.3 + resolution: "jackspeak@npm:3.4.3" dependencies: "@isaacs/cliui": "npm:^8.0.2" "@pkgjs/parseargs": "npm:^0.11.0" dependenciesMeta: "@pkgjs/parseargs": optional: true - checksum: 10c0/f01d8f972d894cd7638bc338e9ef5ddb86f7b208ce177a36d718eac96ec86638a6efa17d0221b10073e64b45edc2ce15340db9380b1f5d5c5d000cbc517dc111 + checksum: 10c0/6acc10d139eaefdbe04d2f679e6191b3abf073f111edf10b1de5302c97ec93fffeb2fdd8681ed17f16268aa9dd4f8c588ed9d1d3bffbbfa6e8bf897cbb3149b9 languageName: node linkType: hard -"jessie.js@npm:^0.3.2": +"jessie.js@npm:^0.3.4": version: 0.3.4 resolution: "jessie.js@npm:0.3.4" dependencies: @@ -1872,6 +1956,13 @@ __metadata: languageName: node linkType: hard +"jsbn@npm:1.1.0": + version: 1.1.0 + resolution: "jsbn@npm:1.1.0" + checksum: 10c0/4f907fb78d7b712e11dea8c165fe0921f81a657d3443dde75359ed52eb2b5d33ce6773d97985a089f09a65edd80b11cb75c767b57ba47391fee4c969f7215c96 + languageName: node + linkType: hard + "load-json-file@npm:^7.0.1": version: 7.0.1 resolution: "load-json-file@npm:7.0.1" @@ -1886,19 +1977,10 @@ __metadata: 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 +"lru-cache@npm:^10.0.1, lru-cache@npm:^10.2.0": + version: 10.4.3 + resolution: "lru-cache@npm:10.4.3" + checksum: 10c0/ebd04fbca961e6c1d6c0af3799adcc966a1babe798f685bb84e6599266599cd95d94630b10262f5424539bc4640107e8a33aa28585374abf561d30d16f4b39fb languageName: node linkType: hard @@ -1912,8 +1994,8 @@ __metadata: linkType: hard "make-fetch-happen@npm:^13.0.0": - version: 13.0.0 - resolution: "make-fetch-happen@npm:13.0.0" + version: 13.0.1 + resolution: "make-fetch-happen@npm:13.0.1" dependencies: "@npmcli/agent": "npm:^2.0.0" cacache: "npm:^18.0.0" @@ -1924,9 +2006,10 @@ __metadata: minipass-flush: "npm:^1.0.5" minipass-pipeline: "npm:^1.2.4" negotiator: "npm:^0.6.3" + proc-log: "npm:^4.2.0" promise-retry: "npm:^2.0.1" ssri: "npm:^10.0.0" - checksum: 10c0/43b9f6dcbc6fe8b8604cb6396957c3698857a15ba4dbc38284f7f0e61f248300585ef1eb8cc62df54e9c724af977e45b5cdfd88320ef7f53e45070ed3488da55 + checksum: 10c0/df5f4dbb6d98153b751bccf4dc4cc500de85a96a9331db9805596c46aa9f99d9555983954e6c1266d9f981ae37a9e4647f42b9a4bb5466f867f4012e582c9e7e languageName: node linkType: hard @@ -1964,13 +2047,13 @@ __metadata: languageName: node linkType: hard -"micromatch@npm:^4.0.2, micromatch@npm:^4.0.4": - version: 4.0.5 - resolution: "micromatch@npm:4.0.5" +"micromatch@npm:^4.0.4, micromatch@npm:^4.0.8": + version: 4.0.8 + resolution: "micromatch@npm:4.0.8" dependencies: - braces: "npm:^3.0.2" + braces: "npm:^3.0.3" picomatch: "npm:^2.3.1" - checksum: 10c0/3d6505b20f9fa804af5d8c596cb1c5e475b9b0cd05f652c5b56141cf941bd72adaeb7a436fda344235cef93a7f29b7472efc779fcdb83b478eab0867b95cdeff + checksum: 10c0/166fa6eb926b9553f32ef81f5f531d27b4ce7da60e5baf8c021d043b27a388fb95e46a8038d5045877881e673f8134122b59624d5cecbd16eb50a42e7a6b5ca8 languageName: node linkType: hard @@ -1997,12 +2080,12 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.1": - version: 9.0.3 - resolution: "minimatch@npm:9.0.3" +"minimatch@npm:^9.0.4": + version: 9.0.5 + resolution: "minimatch@npm:9.0.5" dependencies: brace-expansion: "npm:^2.0.1" - checksum: 10c0/85f407dcd38ac3e180f425e86553911d101455ca3ad5544d6a7cec16286657e4f8a9aa6695803025c55e31e35a91a2252b5dc8e7d527211278b8b65b4dbd5eac + checksum: 10c0/de96cf5e35bdf0eab3e2c853522f98ffbe9a36c37797778d2665231ec1f20a9447a7e567cb640901f89e4daaa95ae5d70c65a9e8aa2bb0019b6facbc3c0575ed languageName: node linkType: hard @@ -2023,8 +2106,8 @@ __metadata: linkType: hard "minipass-fetch@npm:^3.0.0": - version: 3.0.4 - resolution: "minipass-fetch@npm:3.0.4" + version: 3.0.5 + resolution: "minipass-fetch@npm:3.0.5" dependencies: encoding: "npm:^0.1.13" minipass: "npm:^7.0.3" @@ -2033,7 +2116,7 @@ __metadata: dependenciesMeta: encoding: optional: true - checksum: 10c0/1b63c1f3313e88eeac4689f1b71c9f086598db9a189400e3ee960c32ed89e06737fa23976c9305c2d57464fb3fcdc12749d3378805c9d6176f5569b0d0ee8a75 + checksum: 10c0/9d702d57f556274286fdd97e406fc38a2f5c8d15e158b498d7393b1105974b21249289ec571fa2b51e038a4872bfc82710111cf75fae98c662f3d6f95e72152b languageName: node linkType: hard @@ -2080,10 +2163,10 @@ __metadata: 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 +"minipass@npm:^5.0.0 || ^6.0.2 || ^7.0.0, minipass@npm:^7.0.2, minipass@npm:^7.0.3, minipass@npm:^7.1.2": + version: 7.1.2 + resolution: "minipass@npm:7.1.2" + checksum: 10c0/b0fd20bb9fb56e5fa9a8bfac539e8915ae07430a619e4b86ff71f5fc757ef3924b23b2c4230393af1eda647ed3d75739e4e0acb250a6b1eb277cf7f8fe449557 languageName: node linkType: hard @@ -2113,13 +2196,6 @@ __metadata: 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" @@ -2135,18 +2211,18 @@ __metadata: linkType: hard "negotiator@npm:^0.6.3": - version: 0.6.3 - resolution: "negotiator@npm:0.6.3" - checksum: 10c0/3ec9fd413e7bf071c937ae60d572bc67155262068ed522cf4b3be5edbe6ddf67d095ec03a3a14ebf8fc8e95f8e1d61be4869db0dbb0de696f6b837358bd43fc2 + version: 0.6.4 + resolution: "negotiator@npm:0.6.4" + checksum: 10c0/3e677139c7fb7628a6f36335bf11a885a62c21d5390204590a1a214a5631fcbe5ea74ef6a610b60afe84b4d975cbe0566a23f20ee17c77c73e74b80032108dea languageName: node linkType: hard "node-abi@npm:^3.3.0": - version: 3.54.0 - resolution: "node-abi@npm:3.54.0" + version: 3.71.0 + resolution: "node-abi@npm:3.71.0" dependencies: semver: "npm:^7.3.5" - checksum: 10c0/9ebbb21e6951aa51e831549ed62b68dc56bcc10f6b21ffd04195a16a6abf5ddfc48b6ae5e3334720fe4459cafde5ec8103025902efff5599d0539f8656fc694e + checksum: 10c0/dbd0792ea729329cd9d099f28a5681ff9e8a6db48cf64e1437bf6a7fd669009d1e758a784619a1c4cc8bfd1ed17162f042c787654edf19a1f64b5018457c9c1f languageName: node linkType: hard @@ -2165,19 +2241,19 @@ __metadata: linkType: hard "node-gyp-build@npm:^4.2.2": - version: 4.8.0 - resolution: "node-gyp-build@npm:4.8.0" + version: 4.8.2 + resolution: "node-gyp-build@npm:4.8.2" bin: node-gyp-build: bin.js node-gyp-build-optional: optional.js node-gyp-build-test: build-test.js - checksum: 10c0/85324be16f81f0235cbbc42e3eceaeb1b5ab94c8d8f5236755e1435b4908338c65a4e75f66ee343cbcb44ddf9b52a428755bec16dcd983295be4458d95c8e1ad + checksum: 10c0/d816b43974d31d6257b6e87d843f2626c72389a285208394bc57a7766b210454d2642860a5e5b5c333d8ecabaeabad3b31b94f58cf8ca1aabdef0c320d02baaa languageName: node linkType: hard "node-gyp@npm:latest": - version: 10.0.1 - resolution: "node-gyp@npm:10.0.1" + version: 10.2.0 + resolution: "node-gyp@npm:10.2.0" dependencies: env-paths: "npm:^2.2.0" exponential-backoff: "npm:^3.1.1" @@ -2185,13 +2261,13 @@ __metadata: graceful-fs: "npm:^4.2.6" make-fetch-happen: "npm:^13.0.0" nopt: "npm:^7.0.0" - proc-log: "npm:^3.0.0" + proc-log: "npm:^4.1.0" semver: "npm:^7.3.5" - tar: "npm:^6.1.2" + tar: "npm:^6.2.1" which: "npm:^4.0.0" bin: node-gyp: bin/node-gyp.js - checksum: 10c0/abddfff7d873312e4ed4a5fb75ce893a5c4fb69e7fcb1dfa71c28a6b92a7f1ef6b62790dffb39181b5a82728ba8f2f32d229cf8cbe66769fe02cea7db4a555aa + checksum: 10c0/00630d67dbd09a45aee0a5d55c05e3916ca9e6d427ee4f7bc392d2d3dc5fad7449b21fc098dd38260a53d9dcc9c879b36704a1994235d4707e7271af7e9a835b languageName: node linkType: hard @@ -2214,22 +2290,23 @@ __metadata: linkType: hard "nopt@npm:^7.0.0": - version: 7.2.0 - resolution: "nopt@npm:7.2.0" + version: 7.2.1 + resolution: "nopt@npm:7.2.1" dependencies: abbrev: "npm:^2.0.0" bin: nopt: bin/nopt.js - checksum: 10c0/9bd7198df6f16eb29ff16892c77bcf7f0cc41f9fb5c26280ac0def2cf8cf319f3b821b3af83eba0e74c85807cc430a16efe0db58fe6ae1f41e69519f585b6aff + checksum: 10c0/a069c7c736767121242037a22a788863accfa932ab285a1eb569eb8cd534b09d17206f68c37f096ae785647435e0c5a5a0a67b42ec743e481a455e5ae6a6df81 languageName: node linkType: hard -"npm-run-path@npm:^5.2.0": - version: 5.3.0 - resolution: "npm-run-path@npm:5.3.0" +"npm-run-path@npm:^6.0.0": + version: 6.0.0 + resolution: "npm-run-path@npm:6.0.0" dependencies: path-key: "npm:^4.0.0" - checksum: 10c0/124df74820c40c2eb9a8612a254ea1d557ddfab1581c3e751f825e3e366d9f00b0d76a3c94ecd8398e7f3eee193018622677e95816e8491f0797b21e30b2deba + unicorn-magic: "npm:^0.3.0" + checksum: 10c0/b223c8a0dcd608abf95363ea5c3c0ccc3cd877daf0102eaf1b0f2390d6858d8337fbb7c443af2403b067a7d2c116d10691ecd22ab3c5273c44da1ff8d07753bd languageName: node linkType: hard @@ -2270,7 +2347,7 @@ __metadata: languageName: node linkType: hard -"p-map@npm:^7.0.1": +"p-map@npm:^7.0.2": version: 7.0.2 resolution: "p-map@npm:7.0.2" checksum: 10c0/e10548036648d1c043153f9997112fe5a7de54a319210238628f8ea22ee36587fd6ee740811f88b60bbf29d932e23ae35df7fced40df477116c84c18e797047e @@ -2287,6 +2364,13 @@ __metadata: languageName: node linkType: hard +"package-json-from-dist@npm:^1.0.0": + version: 1.0.1 + resolution: "package-json-from-dist@npm:1.0.1" + checksum: 10c0/62ba2785eb655fec084a257af34dbe24292ab74516d6aecef97ef72d4897310bc6898f6c85b5cd22770eaa1ce60d55a0230e150fb6a966e3ecd6c511e23d164b + languageName: node + linkType: hard + "parse-ms@npm:^4.0.0": version: 4.0.0 resolution: "parse-ms@npm:4.0.0" @@ -2315,13 +2399,13 @@ __metadata: languageName: node linkType: hard -"path-scurry@npm:^1.10.1": - version: 1.10.1 - resolution: "path-scurry@npm:1.10.1" +"path-scurry@npm:^1.11.1": + version: 1.11.1 + resolution: "path-scurry@npm:1.11.1" dependencies: - lru-cache: "npm:^9.1.1 || ^10.0.0" + lru-cache: "npm:^10.2.0" minipass: "npm:^5.0.0 || ^6.0.2 || ^7.0.0" - checksum: 10c0/e5dc78a7348d25eec61ab166317e9e9c7b46818aa2c2b9006c507a6ff48c672d011292d9662527213e558f5652ce0afcc788663a061d8b59ab495681840c0c1e + checksum: 10c0/32a13711a2a505616ae1cc1b5076801e453e7aae6ac40ab55b388bb91b9d0547a52f5aaceff710ea400205f18691120d4431e520afbe4266b836fadede15872d languageName: node linkType: hard @@ -2339,10 +2423,10 @@ __metadata: languageName: node linkType: hard -"picomatch@npm:^3.0.1": - version: 3.0.1 - resolution: "picomatch@npm:3.0.1" - checksum: 10c0/70ec738569f1864658378b7abdab8939d15dae0718c1df994eae3346fd33daf6a3c1ff4e0c1a0cd1e2c0319130985b63a2cff34d192f2f2acbb78aca76111736 +"picomatch@npm:^4.0.2": + version: 4.0.2 + resolution: "picomatch@npm:4.0.2" + checksum: 10c0/7c51f3ad2bb42c776f49ebf964c644958158be30d0a510efd5a395e8d49cb5acfed5b82c0c5b365523ce18e6ab85013c9ebe574f60305892ec3fa8eee8304ccc languageName: node linkType: hard @@ -2356,8 +2440,8 @@ __metadata: linkType: hard "prebuild-install@npm:^7.1.1": - version: 7.1.1 - resolution: "prebuild-install@npm:7.1.1" + version: 7.1.2 + resolution: "prebuild-install@npm:7.1.2" dependencies: detect-libc: "npm:^2.0.0" expand-template: "npm:^2.0.3" @@ -2373,23 +2457,23 @@ __metadata: tunnel-agent: "npm:^0.6.0" bin: prebuild-install: bin.js - checksum: 10c0/6dc70f36b0f4adcb2fe0ed38d874ab28b571fb1a9725d769e8ba3f64a15831e58462de09f3e6e64569bcc4a3e03b9328b56faa0d45fe10ae1574478814536c76 + checksum: 10c0/e64868ba9ef2068fd7264f5b03e5298a901e02a450acdb1f56258d88c09dea601eefdb3d1dfdff8513fdd230a92961712be0676192626a3b4d01ba154d48bdd3 languageName: node linkType: hard -"pretty-ms@npm:^9.0.0": - version: 9.0.0 - resolution: "pretty-ms@npm:9.0.0" +"pretty-ms@npm:^9.0.0, pretty-ms@npm:^9.1.0": + version: 9.1.0 + resolution: "pretty-ms@npm:9.1.0" dependencies: parse-ms: "npm:^4.0.0" - checksum: 10c0/ba4a2acd1fe92a1c629e5cdeb555d7fa344ae9920e20fa00e8ac1db61b8d3dff8638ffc70c7569f681e375df68c9f31291c2c1912cefd02ef1b1bdd0861a4aed + checksum: 10c0/fd111aad8800a04dfd654e6016da69bdaa6fc6a4c280f8e727cffd8b5960558e94942f1a94d4aa6e4d179561a0fbb0366a9ebe0ccefbbb0f8ff853b129cdefb9 languageName: node linkType: hard -"proc-log@npm:^3.0.0": - version: 3.0.0 - resolution: "proc-log@npm:3.0.0" - checksum: 10c0/f66430e4ff947dbb996058f6fd22de2c66612ae1a89b097744e17fb18a4e8e7a86db99eda52ccf15e53f00b63f4ec0b0911581ff2aac0355b625c8eac509b0dc +"proc-log@npm:^4.1.0, proc-log@npm:^4.2.0": + version: 4.2.0 + resolution: "proc-log@npm:4.2.0" + checksum: 10c0/17db4757c2a5c44c1e545170e6c70a26f7de58feb985091fb1763f5081cab3d01b181fb2dd240c9f4a4255a1d9227d163d5771b7e69c9e49a561692db865efb9 languageName: node linkType: hard @@ -2404,12 +2488,12 @@ __metadata: linkType: hard "pump@npm:^3.0.0": - version: 3.0.0 - resolution: "pump@npm:3.0.0" + version: 3.0.2 + resolution: "pump@npm:3.0.2" dependencies: end-of-stream: "npm:^1.1.0" once: "npm:^1.3.1" - checksum: 10c0/bbdeda4f747cdf47db97428f3a135728669e56a0ae5f354a9ac5b74556556f5446a46f720a8f14ca2ece5be9b4d5d23c346db02b555f46739934cc6c093a5478 + checksum: 10c0/5ad655cb2a7738b4bcf6406b24ad0970d680649d996b55ad20d1be8e0c02394034e4c45ff7cd105d87f1e9b96a0e3d06fd28e11fae8875da26e7f7a8e2c9726f languageName: node linkType: hard @@ -2511,7 +2595,9 @@ __metadata: version: 0.0.0-use.local resolution: "root-workspace-0b6124@workspace:." dependencies: - "@agoric/internal": "npm:0.3.3-dev-5676146.0" + "@agoric/ertp": "npm:dev" + "@agoric/internal": "npm:dev" + "@agoric/store": "npm:dev" "@agoric/synthetic-chain": "npm:^0.3.0" "@endo/errors": "npm:^1.2.2" "@endo/far": "npm:^1.1.5" @@ -2557,13 +2643,11 @@ __metadata: 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" + version: 7.6.3 + resolution: "semver@npm:7.6.3" bin: semver: bin/semver.js - checksum: 10c0/5160b06975a38b11c1ab55950cb5b8a23db78df88275d3d8a42ccf1f29e55112ac995b3a26a522c36e3b5f76b0445f1eef70d696b8c7862a2b4303d7b0e7609e + checksum: 10c0/88f33e148b210c153873cb08cfe1e281d518aaa9a666d4d148add6560db5cd3c582f3a08ccb91f38d5f379ead256da9931234ed122057f40bb5766e65e58adaf languageName: node linkType: hard @@ -2576,12 +2660,12 @@ __metadata: languageName: node linkType: hard -"ses@npm:^1.8.0": - version: 1.8.0 - resolution: "ses@npm:1.8.0" +"ses@npm:^1.9.1": + version: 1.9.1 + resolution: "ses@npm:1.9.1" dependencies: - "@endo/env-options": "npm:^1.1.6" - checksum: 10c0/4b2114e586a547dd2a71477e0a42e8ea5d0ea9c3ff135d0dbfb63569eeda19c7152db76b82bcad12a2969d3f5fb09e5fa52e921b5a2831560e6876ca1f9ba207 + "@endo/env-options": "npm:^1.1.7" + checksum: 10c0/1e795542954f635aaee2749a1d548460f2978257cb29daaea76b814ef99ffa64ab5cca05fbc3d51a814a57cf9fc4563988ee93312cc53bae4eb63dfff0f0682a languageName: node linkType: hard @@ -2664,24 +2748,31 @@ __metadata: languageName: node linkType: hard -"socks-proxy-agent@npm:^8.0.1": - version: 8.0.2 - resolution: "socks-proxy-agent@npm:8.0.2" +"socks-proxy-agent@npm:^8.0.3": + version: 8.0.4 + resolution: "socks-proxy-agent@npm:8.0.4" dependencies: - agent-base: "npm:^7.0.2" + agent-base: "npm:^7.1.1" debug: "npm:^4.3.4" - socks: "npm:^2.7.1" - checksum: 10c0/a842402fc9b8848a31367f2811ca3cd14c4106588b39a0901cd7a69029998adfc6456b0203617c18ed090542ad0c24ee4e9d4c75a0c4b75071e214227c177eb7 + socks: "npm:^2.8.3" + checksum: 10c0/345593bb21b95b0508e63e703c84da11549f0a2657d6b4e3ee3612c312cb3a907eac10e53b23ede3557c6601d63252103494caa306b66560f43af7b98f53957a languageName: node linkType: hard -"socks@npm:^2.7.1": - version: 2.7.1 - resolution: "socks@npm:2.7.1" +"socks@npm:^2.8.3": + version: 2.8.3 + resolution: "socks@npm:2.8.3" dependencies: - ip: "npm:^2.0.0" + ip-address: "npm:^9.0.5" smart-buffer: "npm:^4.2.0" - checksum: 10c0/43f69dbc9f34fc8220bc51c6eea1c39715ab3cfdb115d6e3285f6c7d1a603c5c75655668a5bbc11e3c7e2c99d60321fb8d7ab6f38cda6a215fadd0d6d0b52130 + checksum: 10c0/d54a52bf9325165770b674a67241143a3d8b4e4c8884560c4e0e078aace2a728dffc7f70150660f51b85797c4e1a3b82f9b7aa25e0a0ceae1a243365da5c51a7 + languageName: node + linkType: hard + +"sprintf-js@npm:^1.1.3": + version: 1.1.3 + resolution: "sprintf-js@npm:1.1.3" + checksum: 10c0/09270dc4f30d479e666aee820eacd9e464215cdff53848b443964202bf4051490538e5dd1b42e1a65cf7296916ca17640aebf63dae9812749c7542ee5f288dec languageName: node linkType: hard @@ -2693,11 +2784,11 @@ __metadata: linkType: hard "ssri@npm:^10.0.0": - version: 10.0.5 - resolution: "ssri@npm:10.0.5" + version: 10.0.6 + resolution: "ssri@npm:10.0.6" dependencies: minipass: "npm:^7.0.3" - checksum: 10c0/b091f2ae92474183c7ac5ed3f9811457e1df23df7a7e70c9476eaa9a0c4a0c8fc190fb45acefbf023ca9ee864dd6754237a697dc52a0fb182afe65d8e77443d8 + checksum: 10c0/e5a1e23a4057a86a97971465418f22ea89bd439ac36ade88812dd920e4e61873e8abd6a9b72a03a67ef50faa00a2daf1ab745c5a15b46d03e0544a0296354227 languageName: node linkType: hard @@ -2733,13 +2824,13 @@ __metadata: linkType: hard "string-width@npm:^7.0.0": - version: 7.1.0 - resolution: "string-width@npm:7.1.0" + version: 7.2.0 + resolution: "string-width@npm:7.2.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 + checksum: 10c0/eb0430dd43f3199c7a46dcbf7a0b34539c76fe3aa62763d0b0655acdcbdf360b3f66f3d58ca25ba0205f42ea3491fa00f09426d3b7d3040e506878fc7664c9b9 languageName: node linkType: hard @@ -2821,9 +2912,9 @@ __metadata: languageName: node linkType: hard -"tar@npm:^6.1.11, tar@npm:^6.1.2": - version: 6.2.0 - resolution: "tar@npm:6.2.0" +"tar@npm:^6.1.11, tar@npm:^6.2.1": + version: 6.2.1 + resolution: "tar@npm:6.2.1" dependencies: chownr: "npm:^2.0.0" fs-minipass: "npm:^2.0.0" @@ -2831,7 +2922,7 @@ __metadata: minizlib: "npm:^2.1.1" mkdirp: "npm:^1.0.3" yallist: "npm:^4.0.0" - checksum: 10c0/02ca064a1a6b4521fef88c07d389ac0936730091f8c02d30ea60d472e0378768e870769ab9e986d87807bfee5654359cf29ff4372746cc65e30cbddc352660d8 + checksum: 10c0/a5eca3eb50bc11552d453488344e6507156b9193efd7635e98e867fab275d527af53d8866e2370cd09dfe74378a18111622ace35af6a608e5223a7d27fe99537 languageName: node linkType: hard @@ -2866,8 +2957,8 @@ __metadata: linkType: hard "tsx@npm:^4.17.0": - version: 4.17.0 - resolution: "tsx@npm:4.17.0" + version: 4.19.2 + resolution: "tsx@npm:4.19.2" dependencies: esbuild: "npm:~0.23.0" fsevents: "npm:~2.3.3" @@ -2877,7 +2968,7 @@ __metadata: optional: true bin: tsx: dist/cli.mjs - checksum: 10c0/ad720b81d6447c7695d24c27947fa1a2b6db9d2ef03216389edd6fa0006aa479bc0d8348a1ac9975a08edef4ce791ff5629a24d8dccbb0987f42e5407785cfa4 + checksum: 10c0/63164b889b1d170403e4d8753a6755dec371f220f5ce29a8e88f1f4d6085a784a12d8dc2ee669116611f2c72757ac9beaa3eea5c452796f541bdd2dc11753721 languageName: node linkType: hard @@ -2898,22 +2989,22 @@ __metadata: linkType: hard "typescript@npm:^5.5.4": - version: 5.5.4 - resolution: "typescript@npm:5.5.4" + version: 5.6.3 + resolution: "typescript@npm:5.6.3" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/422be60f89e661eab29ac488c974b6cc0a660fb2228003b297c3d10c32c90f3bcffc1009b43876a082515a3c376b1eefcce823d6e78982e6878408b9a923199c + checksum: 10c0/44f61d3fb15c35359bc60399cb8127c30bae554cd555b8e2b46d68fa79d680354b83320ad419ff1b81a0bdf324197b29affe6cc28988cd6a74d4ac60c94f9799 languageName: node linkType: hard "typescript@patch:typescript@npm%3A^5.5.4#optional!builtin": - version: 5.5.4 - resolution: "typescript@patch:typescript@npm%3A5.5.4#optional!builtin::version=5.5.4&hash=b45daf" + version: 5.6.3 + resolution: "typescript@patch:typescript@npm%3A5.6.3#optional!builtin::version=5.6.3&hash=b45daf" bin: tsc: bin/tsc tsserver: bin/tsserver - checksum: 10c0/10dd9881baba22763de859e8050d6cb6e2db854197495c6f1929b08d1eb2b2b00d0b5d9b0bcee8472f1c3f4a7ef6a5d7ebe0cfd703f853aa5ae465b8404bc1ba + checksum: 10c0/ac8307bb06bbfd08ae7137da740769b7d8c3ee5943188743bb622c621f8ad61d244767480f90fbd840277fbf152d8932aa20c33f867dea1bb5e79b187ca1a92f languageName: node linkType: hard @@ -2924,6 +3015,13 @@ __metadata: languageName: node linkType: hard +"unicorn-magic@npm:^0.3.0": + version: 0.3.0 + resolution: "unicorn-magic@npm:0.3.0" + checksum: 10c0/0a32a997d6c15f1c2a077a15b1c4ca6f268d574cf5b8975e778bb98e6f8db4ef4e86dfcae4e158cd4c7e38fb4dd383b93b13eefddc7f178dea13d3ac8a603271 + languageName: node + linkType: hard + "unique-filename@npm:^3.0.0": version: 3.0.0 resolution: "unique-filename@npm:3.0.0" @@ -3033,13 +3131,13 @@ __metadata: languageName: node linkType: hard -"write-file-atomic@npm:^5.0.1": - version: 5.0.1 - resolution: "write-file-atomic@npm:5.0.1" +"write-file-atomic@npm:^6.0.0": + version: 6.0.0 + resolution: "write-file-atomic@npm:6.0.0" dependencies: imurmurhash: "npm:^0.1.4" signal-exit: "npm:^4.0.1" - checksum: 10c0/e8c850a8e3e74eeadadb8ad23c9d9d63e4e792bd10f4836ed74189ef6e996763959f1249c5650e232f3c77c11169d239cbfc8342fc70f3fe401407d23810505d + checksum: 10c0/ae2f1c27474758a9aca92037df6c1dd9cb94c4e4983451210bd686bfe341f142662f6aa5913095e572ab037df66b1bfe661ed4ce4c0369ed0e8219e28e141786 languageName: node linkType: hard diff --git a/golang/cosmos/app/upgrade.go b/golang/cosmos/app/upgrade.go index 4b5565045c04..f661bf4bddc0 100644 --- a/golang/cosmos/app/upgrade.go +++ b/golang/cosmos/app/upgrade.go @@ -18,6 +18,7 @@ var upgradeNamesOfThisVersion = []string{ "UNRELEASED_A3P_INTEGRATION", "UNRELEASED_main", "UNRELEASED_devnet", + "UNRELEASED_emerynet", "UNRELEASED_REAPPLY", } @@ -55,7 +56,8 @@ func isPrimaryUpgradeName(name string) bool { case validUpgradeName("UNRELEASED_BASIC"), validUpgradeName("UNRELEASED_A3P_INTEGRATION"), validUpgradeName("UNRELEASED_main"), - validUpgradeName("UNRELEASED_devnet"): + validUpgradeName("UNRELEASED_devnet"), + validUpgradeName("UNRELEASED_emerynet"): return true case validUpgradeName("UNRELEASED_REAPPLY"): return false @@ -79,10 +81,10 @@ func buildProposalStepWithArgs(moduleName string, entrypoint string, opts map[st t := template.Must(template.New("").Parse(`{ "module": "{{.moduleName}}", "entrypoint": "{{.entrypoint}}", - "args": [ {{.args}} ] + "args": [ {{.optsArg}} ] }`)) - args, err := json.Marshal(opts) + optsArg, err := json.Marshal(opts) if err != nil { return nil, err } @@ -91,7 +93,7 @@ func buildProposalStepWithArgs(moduleName string, entrypoint string, opts map[st err = t.Execute(&result, map[string]any{ "moduleName": moduleName, "entrypoint": entrypoint, - "args": string(args), + "optsArg": string(optsArg), }) if err != nil { return nil, err @@ -106,23 +108,29 @@ func buildProposalStepWithArgs(moduleName string, entrypoint string, opts map[st } func getVariantFromUpgradeName(upgradeName string) string { - switch upgradeName { - case "UNRELEASED_A3P_INTEGRATION": - return "A3P_INTEGRATION" - case "UNRELEASED_main": - return "MAINNET" - case "UNRELEASED_devnet": - return "DEVNET" - // Noupgrade for this version. - case "UNRELEASED_BASIC": - return "" - default: - return "" - } + switch upgradeName { + case "UNRELEASED_A3P_INTEGRATION": + return "A3P_INTEGRATION" + case "UNRELEASED_main": + return "MAINNET" + case "UNRELEASED_devnet": + return "DEVNET" + case "UNRELEASED_emerynet": + return "EMERYNET" + // Noupgrade for this version. + case "UNRELEASED_BASIC": + return "" + default: + return "" + } } func replaceElectorateCoreProposalStep(upgradeName string) (vm.CoreProposalStep, error) { - variant := getVariantFromUpgradeName(upgradeName) + variant := getVariantFromUpgradeName(upgradeName) + + if variant == "" { + return nil, nil + } return buildProposalStepWithArgs( "@agoric/builders/scripts/inter-protocol/replace-electorate-core.js", @@ -134,7 +142,11 @@ func replaceElectorateCoreProposalStep(upgradeName string) (vm.CoreProposalStep, } func replacePriceFeedsCoreProposal(upgradeName string) (vm.CoreProposalStep, error) { - variant := getVariantFromUpgradeName(upgradeName) + variant := getVariantFromUpgradeName(upgradeName) + + if variant == "" { + return nil, nil + } return buildProposalStepWithArgs( "@agoric/builders/scripts/inter-protocol/updatePriceFeeds.js", @@ -165,33 +177,42 @@ func unreleasedUpgradeHandler(app *GaiaApp, targetUpgrade string) func(sdk.Conte replaceElectorateStep, err := replaceElectorateCoreProposalStep(targetUpgrade) if err != nil { return nil, err + } else if replaceElectorateStep != nil { + CoreProposalSteps = append(CoreProposalSteps, replaceElectorateStep) } priceFeedUpdate, err := replacePriceFeedsCoreProposal(targetUpgrade) if err != nil { return nil, err + } else if priceFeedUpdate != nil { + CoreProposalSteps = append(CoreProposalSteps, + priceFeedUpdate, + // The following have a dependency onto the price feed proposal + vm.CoreProposalStepForModules( + "@agoric/builders/scripts/vats/add-auction.js", + ), + vm.CoreProposalStepForModules( + "@agoric/builders/scripts/vats/upgradeVaults.js", + ), + ) } // Each CoreProposalStep runs sequentially, and can be constructed from // one or more modules executing in parallel within the step. - CoreProposalSteps = []vm.CoreProposalStep{ - replaceElectorateStep, - priceFeedUpdate, + CoreProposalSteps = append(CoreProposalSteps, vm.CoreProposalStepForModules( - "@agoric/builders/scripts/vats/add-auction.js", + // Upgrade Zoe (no new ZCF needed). + "@agoric/builders/scripts/vats/upgrade-zoe.js", ), + // Revive KREAd characters vm.CoreProposalStepForModules( - "@agoric/builders/scripts/vats/upgradeVaults.js", + "@agoric/builders/scripts/vats/revive-kread.js", ), vm.CoreProposalStepForModules( - // Upgrade Zoe (no new ZCF needed). - "@agoric/builders/scripts/vats/upgrade-zoe.js", + // Upgrade to include a cleanup from https://github.com/Agoric/agoric-sdk/pull/10319 + "@agoric/builders/scripts/smart-wallet/build-wallet-factory2-upgrade.js", ), - // Revive KREAd characters - vm.CoreProposalStepForModules( - "@agoric/builders/scripts/vats/revive-kread.js", - ), - } + ) } app.upgradeDetails = &upgradeDetails{ diff --git a/golang/cosmos/cmd/agd/agvm.go b/golang/cosmos/cmd/agd/agvm.go index 262e2c51e68f..2127e5928405 100644 --- a/golang/cosmos/cmd/agd/agvm.go +++ b/golang/cosmos/cmd/agd/agvm.go @@ -27,9 +27,9 @@ func NewVMCommand(logger log.Logger, binary string, args []string, vmFromAgd, vm fdToAgd := fdFromAgd + 1 // ExtraFiles begins at fd numStdFiles, so we need to compute the array. - cmd.ExtraFiles = make([]*os.File, fdToAgd - numStdFiles + 1) - cmd.ExtraFiles[fdFromAgd - numStdFiles] = vmFromAgd - cmd.ExtraFiles[fdToAgd - numStdFiles] = vmToAgd + cmd.ExtraFiles = make([]*os.File, fdToAgd-numStdFiles+1) + cmd.ExtraFiles[fdFromAgd-numStdFiles] = vmFromAgd + cmd.ExtraFiles[fdToAgd-numStdFiles] = vmToAgd // Pass the file descriptor numbers in the environment. cmd.Env = append( diff --git a/golang/cosmos/cmd/agd/find_binary.go b/golang/cosmos/cmd/agd/find_binary.go index 336ee25a34c2..3fee55be1956 100644 --- a/golang/cosmos/cmd/agd/find_binary.go +++ b/golang/cosmos/cmd/agd/find_binary.go @@ -8,7 +8,7 @@ import ( // FindBinaryNextToMe looks for binName next to the current executable. // It returns an absolute filename for binName, or an error. -func FindBinaryNextToMe(walkUp int, path... string) (string, error) { +func FindBinaryNextToMe(walkUp int, path ...string) (string, error) { ex, err := os.Executable() if err != nil { return "", err @@ -32,7 +32,7 @@ func FindBinaryNextToMe(walkUp int, path... string) (string, error) { if _, err = os.Stat(bin); err != nil { return "", err } - + return bin, nil } diff --git a/golang/cosmos/vm/client.go b/golang/cosmos/vm/client.go index ac3fa067d3e7..05be0a8becb6 100644 --- a/golang/cosmos/vm/client.go +++ b/golang/cosmos/vm/client.go @@ -12,8 +12,8 @@ const ReceiveMessageMethod = "agvm.ReceiveMessage" // Message is what we send to the VM. type Message struct { - Port int - Data string + Port int + Data string NeedsReply bool } @@ -24,7 +24,9 @@ var _ rpc.ClientCodec = (*ClientCodec)(nil) // runtime and the VM in the single-process dual-runtime configuration. // // We expect to call it via the legacy API with signature: -// sendToController func(needsReply bool, msg string) (string, error) +// +// sendToController func(needsReply bool, msg string) (string, error) +// // where msg and the returned string are JSON-encoded values. // // Note that the net/rpc framework cannot express a call that does not expect a @@ -32,22 +34,22 @@ var _ rpc.ClientCodec = (*ClientCodec)(nil) // having the WriteRequest() method fabricate a Receive() call to clear the rpc // state. type ClientCodec struct { - ctx context.Context - send func(port, rPort int, msg string) - outbound map[int]rpc.Request - inbound chan *rpc.Response - replies map[uint64]string + ctx context.Context + send func(port, rPort int, msg string) + outbound map[int]rpc.Request + inbound chan *rpc.Response + replies map[uint64]string replyToRead uint64 } // NewClientCodec creates a new ClientCodec. func NewClientCodec(ctx context.Context, send func(int, int, string)) *ClientCodec { return &ClientCodec{ - ctx: ctx, - send: send, + ctx: ctx, + send: send, outbound: make(map[int]rpc.Request), - inbound: make(chan *rpc.Response), - replies: make(map[uint64]string), + inbound: make(chan *rpc.Response), + replies: make(map[uint64]string), } } @@ -97,7 +99,7 @@ func (cc *ClientCodec) Receive(rPort int, isError bool, data string) error { delete(cc.outbound, rPort) resp := &rpc.Response{ ServiceMethod: outb.ServiceMethod, - Seq: outb.Seq, + Seq: outb.Seq, } if isError { resp.Error = data diff --git a/golang/cosmos/x/vbank/types/key.go b/golang/cosmos/x/vbank/types/key.go index 5bd84ab78360..69ab859e4669 100644 --- a/golang/cosmos/x/vbank/types/key.go +++ b/golang/cosmos/x/vbank/types/key.go @@ -7,7 +7,7 @@ const ( // StoreKey to be used when creating the KVStore StoreKey = ModuleName - ReservePoolName = "vbank/reserve" - GiveawayPoolName = "vbank/giveaway" - ProvisionPoolName = "vbank/provision" + ReservePoolName = "vbank/reserve" + GiveawayPoolName = "vbank/giveaway" + ProvisionPoolName = "vbank/provision" ) diff --git a/packages/agoric-cli/package.json b/packages/agoric-cli/package.json index 67ebc7bf629d..5c7e8ddbbbca 100644 --- a/packages/agoric-cli/package.json +++ b/packages/agoric-cli/package.json @@ -72,7 +72,7 @@ "@iarna/toml": "^2.2.3", "anylogger": "^0.21.0", "chalk": "^5.2.0", - "commander": "^11.1.0", + "commander": "^12.1.0", "deterministic-json": "^1.0.5", "esm": "agoric-labs/esm#Agoric-built", "inquirer": "^8.2.2", diff --git a/packages/agoric-cli/src/commands/auction.js b/packages/agoric-cli/src/commands/auction.js index 99ffd43355c9..e07729a56f3f 100644 --- a/packages/agoric-cli/src/commands/auction.js +++ b/packages/agoric-cli/src/commands/auction.js @@ -59,11 +59,6 @@ export const makeAuctionCommand = ( 'descending clock step size', BigInt, ) - .option( - '--discount-step ', - 'proposed value (basis points)', - BigInt, - ) .requiredOption( '--charterAcceptOfferId ', 'offer that had continuing invitation result', diff --git a/packages/agoric-cli/src/sdk-package-names.js b/packages/agoric-cli/src/sdk-package-names.js index bd78d1387fb0..483c22208ad9 100644 --- a/packages/agoric-cli/src/sdk-package-names.js +++ b/packages/agoric-cli/src/sdk-package-names.js @@ -17,6 +17,7 @@ export default [ "@agoric/deployment", "@agoric/ertp", "@agoric/eslint-config", + "@agoric/fast-usdc", "@agoric/governance", "@agoric/import-manager", "@agoric/inter-protocol", @@ -49,6 +50,5 @@ export default [ "@agoric/xsnap-lockdown", "@agoric/zoe", "@agoric/zone", - "agoric", - "fast-usdc" + "agoric" ]; diff --git a/packages/boot/test/bootstrapTests/price-feed-replace.test.ts b/packages/boot/test/bootstrapTests/price-feed-replace.test.ts index 84a077f336ec..a9c0ce6e177b 100644 --- a/packages/boot/test/bootstrapTests/price-feed-replace.test.ts +++ b/packages/boot/test/bootstrapTests/price-feed-replace.test.ts @@ -101,7 +101,7 @@ test.serial('setupVaults; run updatePriceFeeds proposals', async t => { t.log('building all relevant CoreEvals'); const coreEvals = await Promise.all([ - buildProposal(priceFeedBuilder, ['main']), + buildProposal(priceFeedBuilder, ['MAINNET']), buildProposal('@agoric/builders/scripts/vats/upgradeVaults.js'), buildProposal('@agoric/builders/scripts/vats/add-auction.js'), ]); diff --git a/packages/boot/test/bootstrapTests/updateGovernedParams.test.ts b/packages/boot/test/bootstrapTests/updateGovernedParams.test.ts index f38d83bc5e7b..5410fcc59d78 100644 --- a/packages/boot/test/bootstrapTests/updateGovernedParams.test.ts +++ b/packages/boot/test/bootstrapTests/updateGovernedParams.test.ts @@ -134,7 +134,7 @@ test('modify manager & director params; update vats, check', async t => { const priceFeedBuilder = '@agoric/builders/scripts/inter-protocol/updatePriceFeeds.js'; const coreEvals = await Promise.all([ - buildProposal(priceFeedBuilder, ['main']), + buildProposal(priceFeedBuilder, ['MAINNET']), buildProposal('@agoric/builders/scripts/vats/upgradeVaults.js'), buildProposal('@agoric/builders/scripts/vats/add-auction.js'), ]); diff --git a/packages/builders/scripts/inter-protocol/replace-electorate-core.js b/packages/builders/scripts/inter-protocol/replace-electorate-core.js index 4545cbacfbc5..76f07d6d008a 100644 --- a/packages/builders/scripts/inter-protocol/replace-electorate-core.js +++ b/packages/builders/scripts/inter-protocol/replace-electorate-core.js @@ -6,16 +6,19 @@ * where [ENVIRONMENT] is one of the following: * - MAINNET * - DEVNET + * - EMERYNET * - A3P_INTEGRATION * - BOOTSTRAP_TEST * * Example: * agoric run replace-electorate-core.js MAINNET */ -/* global process */ import { makeHelpers } from '@agoric/deploy-script-support'; import { getManifestForReplaceAllElectorates } from '@agoric/inter-protocol/src/proposals/replaceElectorate.js'; +/** @typedef {Parameters[1]['options']} ReplaceElectorateOptions */ + +/** @type {Record} */ const configurations = { MAINNET: { committeeName: 'Economic Committee', @@ -45,6 +48,18 @@ const configurations = { addressesToRemove: ['agoric1w8wktaur4zf8qmmtn3n7x3r0jhsjkjntcm3u6h'], }, }, + EMERYNET: { + committeeName: 'Economic Committee', + voterAddresses: { + gov1: 'agoric1ldmtatp24qlllgxmrsjzcpe20fvlkp448zcuce', + gov2: 'agoric140dmkrz2e42ergjj7gyvejhzmjzurvqeq82ang', + gov4: 'agoric1f0h5zgxyg3euxsqzs0506uj4cmu56y30pqx46s', + }, + highPrioritySendersConfig: { + addressesToAdd: ['agoric1f0h5zgxyg3euxsqzs0506uj4cmu56y30pqx46s'], + addressesToRemove: ['agoric1w8wktaur4zf8qmmtn3n7x3r0jhsjkjntcm3u6h'], + }, + }, A3P_INTEGRATION: { committeeName: 'Economic Committee', voterAddresses: { @@ -76,20 +91,33 @@ const configurations = { }; const { keys } = Object; -const Usage = `agoric run replace-electorate-core.js ${keys(configurations).join(' | ')}`; +const knownVariants = keys(configurations); + /** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */ export const defaultProposalBuilder = async ({ publishRef, install }, opts) => { - const config = configurations[opts.variant]; + const config = opts.config || configurations[opts.variant]; if (!config) { - console.error(Usage); - process.exit(1); + const error = `Unknown variant "${opts.variant}". Expected one of ${knownVariants.join(', ')}`; + console.error(error); + throw Error(error); } + const { committeeName, voterAddresses, highPrioritySendersConfig } = config; + console.log( + 'Generating replace committee proposal with config', + JSON.stringify({ + committeeName, + voterAddresses, + highPrioritySendersConfig, + }), + ); return harden({ sourceSpec: '@agoric/inter-protocol/src/proposals/replaceElectorate.js', getManifestCall: [ getManifestForReplaceAllElectorates.name, { - ...config, + committeeName, + voterAddresses, + highPrioritySendersConfig, economicCommitteeRef: publishRef( install( '@agoric/governance/src/committee.js', @@ -101,15 +129,35 @@ export const defaultProposalBuilder = async ({ publishRef, install }, opts) => { }); }; +const Usage = `agoric run replace-electorate-core.js ${[...knownVariants, ''].join(' | ')}`; + /** @type {import('@agoric/deploy-script-support/src/externalTypes.js').DeployScriptFunction} */ export default async (homeP, endowments) => { const { scriptArgs } = endowments; - const variant = scriptArgs?.[0]; - console.log('replace-committee', scriptArgs, variant); + const variantOrConfig = scriptArgs?.[0]; + console.log('replace-electorate-core.js', variantOrConfig); + + const opts = {}; + + if (typeof variantOrConfig === 'string') { + if (variantOrConfig[0] === '{') { + try { + opts.config = JSON.parse(variantOrConfig); + } catch (err) { + throw Error(`Failed to parse config argument ${variantOrConfig}`); + } + } else { + opts.variant = variantOrConfig; + } + } else { + console.error(Usage); + throw Error(Usage); + } const { writeCoreEval } = await makeHelpers(homeP, endowments); - await writeCoreEval(`replace-committee-${variant}`, (utils, opts) => - defaultProposalBuilder(utils, { ...opts, variant }), + await writeCoreEval( + `replace-committee-${opts.variant || 'from-config'}`, + utils => defaultProposalBuilder(utils, opts), ); }; diff --git a/packages/builders/scripts/inter-protocol/updatePriceFeeds.js b/packages/builders/scripts/inter-protocol/updatePriceFeeds.js index c6a96157abf9..6b5f0c2e4424 100644 --- a/packages/builders/scripts/inter-protocol/updatePriceFeeds.js +++ b/packages/builders/scripts/inter-protocol/updatePriceFeeds.js @@ -13,7 +13,7 @@ const configurations = { ], inBrandNames: ['ATOM', 'stATOM'], }, - main: { + MAINNET: { oracleAddresses: [ 'agoric144rrhh4m09mh7aaffhm6xy223ym76gve2x7y78', // DSRV 'agoric19d6gnr9fyp6hev4tlrg87zjrzsd5gzr5qlfq2p', // Stakin @@ -24,7 +24,7 @@ const configurations = { inBrandNames: ['ATOM', 'stATOM', 'stOSMO', 'stTIA', 'stkATOM'], contractTerms: { minSubmissionCount: 3 }, }, - devnet: { + DEVNET: { oracleAddresses: [ 'agoric1lw4e4aas9q84tq0q92j85rwjjjapf8dmnllnft', // DSRV 'agoric1zj6vrrrjq4gsyr9lw7dplv4vyejg3p8j2urm82', // Stakin @@ -34,23 +34,39 @@ const configurations = { ], inBrandNames: ['ATOM', 'stTIA', 'stkATOM'], }, + EMERYNET: { + oracleAddresses: [ + 'agoric1ldmtatp24qlllgxmrsjzcpe20fvlkp448zcuce', // GOV1 + 'agoric140dmkrz2e42ergjj7gyvejhzmjzurvqeq82ang', // GOV2 + ], + inBrandNames: ['ATOM', 'stATOM', 'stOSMO', 'stTIA', 'stkATOM'], + }, }; const { keys } = Object; -const Usage = `agoric run updatePriceFeed.js ${keys(configurations).join(' | ')}`; +const knownVariants = keys(configurations); + /** @type {import('@agoric/deploy-script-support/src/externalTypes.js').CoreEvalBuilder} */ export const defaultProposalBuilder = async ({ publishRef, install }, opts) => { - const config = configurations[opts.variant]; + const config = opts.config || configurations[opts.variant]; if (!config) { - console.error(Usage); - throw Error(Usage); + const error = `Unknown variant "${opts.variant}". Expected one of ${knownVariants.join(', ')}`; + console.error(error); + throw Error(error); } + const { oracleAddresses, inBrandNames, contractTerms } = config; + console.log( + 'Generating price feeds update proposal with config', + JSON.stringify({ oracleAddresses, inBrandNames, contractTerms }), + ); return harden({ sourceSpec: '@agoric/inter-protocol/src/proposals/deploy-price-feeds.js', getManifestCall: [ getManifestForPriceFeeds.name, { - ...config, + oracleAddresses, + inBrandNames, + contractTerms, priceAggregatorRef: publishRef( install( '@agoric/inter-protocol/src/price/fluxAggregatorContract.js', @@ -68,15 +84,35 @@ export const defaultProposalBuilder = async ({ publishRef, install }, opts) => { }); }; +const Usage = `agoric run updatePriceFeeds.js ${[...knownVariants, ''].join(' | ')}`; + /** @type {import('@agoric/deploy-script-support/src/externalTypes.js').DeployScriptFunction} */ export default async (homeP, endowments) => { const { scriptArgs } = endowments; - const variant = scriptArgs?.[0]; - console.log('updatePriceFeeds', scriptArgs, variant); + const variantOrConfig = scriptArgs?.[0]; + console.log('updatePriceFeeds.js', variantOrConfig); + + const opts = {}; + + if (typeof variantOrConfig === 'string') { + if (variantOrConfig[0] === '{') { + try { + opts.config = JSON.parse(variantOrConfig); + } catch (err) { + throw Error(`Failed to parse config argument ${variantOrConfig}`); + } + } else { + opts.variant = variantOrConfig; + } + } else { + console.error(Usage); + throw Error(Usage); + } const { writeCoreEval } = await makeHelpers(homeP, endowments); - await writeCoreEval(`gov-price-feeds-${variant}`, (utils, opts) => - defaultProposalBuilder(utils, { ...opts, variant }), + await writeCoreEval( + `gov-price-feeds-${opts.variant || 'from-config'}`, + utils => defaultProposalBuilder(utils, opts), ); }; diff --git a/packages/cosmic-swingset/src/launch-chain.js b/packages/cosmic-swingset/src/launch-chain.js index c8b113d5528d..c2211d66a4c5 100644 --- a/packages/cosmic-swingset/src/launch-chain.js +++ b/packages/cosmic-swingset/src/launch-chain.js @@ -527,6 +527,8 @@ export async function launch({ inboundNum, sender, count: messages.length, + messages, + ack, }); if (!mb.deliverInbound(sender, messages, ack)) { return; @@ -539,6 +541,7 @@ export async function launch({ type: 'cosmic-swingset-bridge-inbound', inboundNum, source, + body, }); if (!bridgeInbound) throw Fail`bridgeInbound undefined`; // console.log(`doBridgeInbound`); @@ -547,7 +550,7 @@ export async function launch({ bridgeInbound(source, body); } - async function installBundle(bundleJson) { + async function installBundle(bundleJson, inboundNum) { let bundle; try { bundle = JSON.parse(bundleJson); @@ -564,6 +567,13 @@ export async function launch({ const { endoZipBase64Sha512 } = bundle; + controller.writeSlogObject({ + type: 'cosmic-swingset-install-bundle', + inboundNum, + endoZipBase64Sha512, + error, + }); + if (installationPublisher === undefined) { return; } @@ -645,7 +655,7 @@ export async function launch({ } case ActionType.INSTALL_BUNDLE: { - p = installBundle(action.bundle); + p = installBundle(action.bundle, inboundNum); break; } @@ -714,6 +724,12 @@ export async function launch({ // Then, update the timer device with the new external time, which might // push work onto the kernel run-queue (if any timers were ready to wake). const addedToQueue = timer.poll(blockTime); + controller.writeSlogObject({ + type: 'cosmic-swingset-timer-poll', + blockHeight, + blockTime, + added: addedToQueue, + }); console.debug( `polled; blockTime:${blockTime}, h:${blockHeight}; ADDED =`, addedToQueue, diff --git a/packages/fast-usdc/README.md b/packages/fast-usdc/README.md index 76a23f4c3292..f606d5576575 100644 --- a/packages/fast-usdc/README.md +++ b/packages/fast-usdc/README.md @@ -3,12 +3,6 @@ Development package for the Fast USDC product. Here in agoric-sdk as a convenience for integration testing and iterating on the SDK affordances required for the product. -# Naming - -The package is `fast-usdc`, not `@agoric/fast-usdc`, because it's not part of the SDK. - -It should not appear in the NPM directory. To this end the package is marked as private. - # Factoring This package is meant to contain all the code for the Fast USDC product. However there are some constraints: diff --git a/packages/fast-usdc/package.json b/packages/fast-usdc/package.json index b54b1a6bbe78..21b669555f47 100644 --- a/packages/fast-usdc/package.json +++ b/packages/fast-usdc/package.json @@ -1,8 +1,8 @@ { - "name": "fast-usdc", + "name": "@agoric/fast-usdc", "private": true, "version": "0.1.0", - "description": "Create an Agoric Javascript smart contract application", + "description": "CLI and library for Fast USDC product", "type": "module", "files": [ "contract", @@ -27,7 +27,6 @@ "ts-blank-space": "^0.4.1" }, "dependencies": { - "agoric": "^0.21.1", "commander": "^12.1.0" }, "ava": { diff --git a/packages/internal/src/node/fs-stream.js b/packages/internal/src/node/fs-stream.js index eb7f335f45c6..8e7ae36a48b5 100644 --- a/packages/internal/src/node/fs-stream.js +++ b/packages/internal/src/node/fs-stream.js @@ -1,8 +1,11 @@ import { createWriteStream } from 'node:fs'; +import process from 'node:process'; import { open } from 'node:fs/promises'; /** - * @param {import('fs').ReadStream | import('fs').WriteStream} stream + * @param {import('fs').ReadStream + * | import('fs').WriteStream + * | import('net').Socket} stream * @returns {Promise} */ export const fsStreamReady = stream => @@ -48,45 +51,51 @@ export const makeFsStreamWriter = async filePath => { return undefined; } - const handle = await open(filePath, 'a'); + const handle = await (filePath !== '-' ? open(filePath, 'a') : undefined); - const stream = createWriteStream(noPath, { fd: handle.fd }); + const stream = handle + ? createWriteStream(noPath, { fd: handle.fd }) + : process.stdout; await fsStreamReady(stream); let flushed = Promise.resolve(); let closed = false; - const write = async data => { - if (closed) { - throw Error('Stream closed'); - } - - /** @type {Promise} */ - const written = new Promise((resolve, reject) => { - stream.write(data, err => { - if (err) { - reject(err); - } else { - resolve(); - } - }); - }); + const updateFlushed = p => { flushed = flushed.then( - () => written, - async err => - Promise.reject( - written.then( - () => err, - writtenError => AggregateError([err, writtenError]), - ), + () => p, + err => + p.then( + () => Promise.reject(err), + pError => + Promise.reject( + pError !== err ? AggregateError([err, pError]) : err, + ), ), ); + flushed.catch(() => {}); + }; + + const write = async data => { + /** @type {Promise} */ + const written = closed + ? Promise.reject(Error('Stream closed')) + : new Promise((resolve, reject) => { + stream.write(data, err => { + if (err) { + reject(err); + } else { + resolve(); + } + }); + }); + updateFlushed(written); return written; }; const flush = async () => { await flushed; - await handle.sync().catch(err => { + await handle?.sync().catch(err => { if (err.code === 'EINVAL') { return; } @@ -95,10 +104,14 @@ export const makeFsStreamWriter = async filePath => { }; const close = async () => { + // TODO: Consider creating a single Error here to use a write rejection closed = true; await flush(); - stream.close(); + // @ts-expect-error calling a possibly missing method + stream.close?.(); }; + stream.on('error', err => updateFlushed(Promise.reject(err))); + return harden({ write, flush, close }); }; diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index 4ca8fa5f285b..cd0cb0585c00 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -29,9 +29,12 @@ "@endo/marshal": "^1.6.1", "@endo/stream": "^1.2.7", "@opentelemetry/api": "~1.3.0", + "@opentelemetry/api-logs": "0.53.0", "@opentelemetry/exporter-prometheus": "~0.35.0", + "@opentelemetry/exporter-logs-otlp-http": "0.53.0", "@opentelemetry/exporter-trace-otlp-http": "~0.35.0", "@opentelemetry/resources": "~1.9.0", + "@opentelemetry/sdk-logs": "0.53.0", "@opentelemetry/sdk-metrics": "~1.9.0", "@opentelemetry/sdk-trace-base": "~1.9.0", "@opentelemetry/semantic-conventions": "~1.27.0", diff --git a/packages/telemetry/src/context-aware-slog-file.js b/packages/telemetry/src/context-aware-slog-file.js new file mode 100644 index 000000000000..003680fc2bd4 --- /dev/null +++ b/packages/telemetry/src/context-aware-slog-file.js @@ -0,0 +1,42 @@ +/* eslint-env node */ + +import { makeFsStreamWriter } from '@agoric/internal/src/node/fs-stream.js'; +import { makeContextualSlogProcessor } from './context-aware-slog.js'; +import { serializeSlogObj } from './serialize-slog-obj.js'; + +/** + * @param {import('./index.js').MakeSlogSenderOptions} options + */ +export const makeSlogSender = async options => { + const { CHAIN_ID, CONTEXTUAL_SLOGFILE } = options.env || {}; + if (!CONTEXTUAL_SLOGFILE) + return console.warn( + 'Ignoring invocation of slogger "context-aware-slog-file" without the presence of "CONTEXTUAL_SLOGFILE"', + ); + + const stream = await makeFsStreamWriter(CONTEXTUAL_SLOGFILE); + + if (!stream) + return console.error( + `Couldn't create a write stream on file "${CONTEXTUAL_SLOGFILE}"`, + ); + + const contextualSlogProcessor = makeContextualSlogProcessor({ + 'chain-id': CHAIN_ID, + }); + + /** + * @param {import('./context-aware-slog.js').Slog} slog + */ + const slogSender = slog => { + const contextualizedSlog = contextualSlogProcessor(slog); + + // eslint-disable-next-line prefer-template + stream.write(serializeSlogObj(contextualizedSlog) + '\n').catch(() => {}); + }; + + return Object.assign(slogSender, { + forceFlush: () => stream.flush(), + shutdown: () => stream.close(), + }); +}; diff --git a/packages/telemetry/src/context-aware-slog.js b/packages/telemetry/src/context-aware-slog.js new file mode 100644 index 000000000000..33c2739efc5a --- /dev/null +++ b/packages/telemetry/src/context-aware-slog.js @@ -0,0 +1,383 @@ +/* eslint-env node */ + +/** + * @typedef {Partial<{ + * 'block.height': Slog['blockHeight']; + * 'block.time': Slog['blockTime']; + * 'crank.deliveryNum': Slog['deliveryNum']; + * 'crank.num': Slog['crankNum']; + * 'crank.type': Slog['crankType']; + * 'crank.vatID': Slog['vatID']; + * init: boolean; + * replay: boolean; + * 'run.id': string; + * 'run.num': string | null; + * 'run.trigger.blockHeight': Slog['blockHeight']; + * 'run.trigger.msgIdx': number; + * 'run.trigger.sender': Slog['sender']; + * 'run.trigger.source': Slog['source']; + * 'run.trigger.bundleHash': Slog['endoZipBase64Sha512']; + * 'run.trigger.time': Slog['blockTime']; + * 'run.trigger.txHash': string; + * 'run.trigger.type': string; + * }> + * } Context + * + * @typedef {{ + * 'crank.syscallNum'?: Slog['syscallNum']; + * 'process.uptime': Slog['monotime']; + * } & Context} LogAttributes + * + * @typedef {{ + * blockHeight?: number; + * blockTime?: number; + * crankNum?: bigint; + * crankType?: string; + * deliveryNum?: bigint; + * inboundNum?: string; + * monotime: number; + * remainingBeans?: bigint; + * replay?: boolean; + * runNum?: number; + * sender?: string; + * source?: string; + * endoZipBase64Sha512?: string; + * syscallNum?: number; + * time: number; + * type: string; + * vatID?: string; + * }} Slog + */ + +const SLOG_TYPES = { + CLIST: 'clist', + CONSOLE: 'console', + COSMIC_SWINGSET: { + AFTER_COMMIT_STATS: 'cosmic-swingset-after-commit-stats', + BEGIN_BLOCK: 'cosmic-swingset-begin-block', + BOOTSTRAP_BLOCK: { + FINISH: 'cosmic-swingset-bootstrap-block-finish', + START: 'cosmic-swingset-bootstrap-block-start', + }, + COMMIT: { + FINISH: 'cosmic-swingset-commit-finish', + START: 'cosmic-swingset-commit-start', + }, + END_BLOCK: { + FINISH: 'cosmic-swingset-end-block-finish', + START: 'cosmic-swingset-end-block-start', + }, + // eslint-disable-next-line no-restricted-syntax + RUN: { + FINISH: 'cosmic-swingset-run-finish', + START: 'cosmic-swingset-run-start', + }, + }, + COSMIC_SWINGSET_TRIGGERS: { + BRIDGE_INBOUND: 'cosmic-swingset-bridge-inbound', + DELIVER_INBOUND: 'cosmic-swingset-deliver-inbound', + TIMER_POLL: 'cosmic-swingset-timer-poll', + INSTALL_BUNDLE: 'cosmic-swingset-install-bundle', + }, + CRANK: { + FINISH: 'crank-finish', + START: 'crank-start', + }, + DELIVER: 'deliver', + DELIVER_RESULT: 'deliver-result', + KERNEL: { + INIT: { + FINISH: 'kernel-init-finish', + START: 'kernel-init-start', + }, + }, + REPLAY: { + FINISH: 'finish-replay', + START: 'start-replay', + }, + SYSCALL: 'syscall', + SYSCALL_RESULT: 'syscall-result', +}; + +/** + * @template {Record} [T={}] + * @param {T} [staticContext] + * @param {Partial<{ persistContext: (context: Context) => void; restoreContext: () => Context | null; }>} [persistenceUtils] + */ +export const makeContextualSlogProcessor = ( + staticContext, + persistenceUtils = {}, +) => { + /** @type Array */ + let [ + blockContext, + crankContext, + initContext, + lastPersistedTriggerContext, + replayContext, + triggerContext, + ] = [null, null, null, null, null, null]; + + /** + * @param {Context} context + */ + const persistContext = context => { + lastPersistedTriggerContext = context; + return persistenceUtils?.persistContext?.(context); + }; + + const restoreContext = () => { + if (!lastPersistedTriggerContext) + lastPersistedTriggerContext = + persistenceUtils?.restoreContext?.() || null; + return lastPersistedTriggerContext; + }; + + /** + * @param {Slog} slog + * @returns {{ attributes: T & LogAttributes, body: Partial; timestamp: Slog['time'] }} + */ + const slogProcessor = ({ monotime, time: timestamp, ...body }) => { + const finalBody = { ...body }; + + /** @type {{'crank.syscallNum'?: Slog['syscallNum']}} */ + const eventLogAttributes = {}; + + /** + * Add any before report operations here + * like setting context data + */ + switch (body.type) { + case SLOG_TYPES.KERNEL.INIT.START: { + initContext = { init: true }; + break; + } + case SLOG_TYPES.COSMIC_SWINGSET.BEGIN_BLOCK: { + blockContext = { + 'block.height': finalBody.blockHeight, + 'block.time': finalBody.blockTime, + }; + break; + } + case SLOG_TYPES.COSMIC_SWINGSET.BOOTSTRAP_BLOCK.START: { + blockContext = { + 'block.height': finalBody.blockHeight || 0, + 'block.time': finalBody.blockTime, + }; + break; + } + case SLOG_TYPES.COSMIC_SWINGSET.END_BLOCK.START: + case SLOG_TYPES.COSMIC_SWINGSET.END_BLOCK.FINISH: + case SLOG_TYPES.COSMIC_SWINGSET.BOOTSTRAP_BLOCK.FINISH: + case SLOG_TYPES.COSMIC_SWINGSET.COMMIT.START: + case SLOG_TYPES.COSMIC_SWINGSET.COMMIT.FINISH: + case SLOG_TYPES.COSMIC_SWINGSET.AFTER_COMMIT_STATS: { + assert(!!blockContext && !triggerContext); + break; + } + case SLOG_TYPES.COSMIC_SWINGSET_TRIGGERS.BRIDGE_INBOUND: + case SLOG_TYPES.COSMIC_SWINGSET_TRIGGERS.DELIVER_INBOUND: { + const [blockHeight, txHash, msgIdx] = ( + finalBody.inboundNum || '' + ).split('-'); + const [, triggerType] = + /cosmic-swingset-([^-]+)-inbound/.exec(body.type) || []; + + triggerContext = { + 'run.num': undefined, + 'run.id': `${triggerType}-${finalBody.inboundNum}`, + 'run.trigger.type': triggerType, + 'run.trigger.source': finalBody.source, + 'run.trigger.sender': finalBody.sender, + 'run.trigger.blockHeight': Number(blockHeight), + 'run.trigger.txHash': txHash, + 'run.trigger.msgIdx': Number(msgIdx), + }; + break; + } + case SLOG_TYPES.COSMIC_SWINGSET_TRIGGERS.INSTALL_BUNDLE: { + const [blockHeight, txHash, msgIdx] = ( + finalBody.inboundNum || '' + ).split('-'); + + const triggerType = 'install-bundle'; + + triggerContext = { + 'run.num': undefined, + 'run.id': `${triggerType}-${finalBody.inboundNum}`, + 'run.trigger.type': triggerType, + 'run.trigger.bundleHash': finalBody.endoZipBase64Sha512, + 'run.trigger.blockHeight': Number(blockHeight), + 'run.trigger.txHash': txHash, + 'run.trigger.msgIdx': Number(msgIdx), + }; + + break; + } + case SLOG_TYPES.COSMIC_SWINGSET_TRIGGERS.TIMER_POLL: { + const triggerType = 'timer-poll'; + + triggerContext = { + 'run.num': undefined, + 'run.id': `${triggerType}-${finalBody.inboundNum}`, + 'run.trigger.type': triggerType, + 'run.trigger.time': finalBody.blockTime, + 'run.trigger.blockHeight': finalBody.blockHeight, + }; + + break; + } + // eslint-disable-next-line no-restricted-syntax + case SLOG_TYPES.COSMIC_SWINGSET.RUN.START: { + if (!finalBody.runNum) { + assert(!triggerContext); + triggerContext = restoreContext(); // Restore persisted context if any + } else if (!triggerContext) { + assert(!!blockContext); + // TODO: add explicit slog events of both timer poll and install bundle + // https://github.com/Agoric/agoric-sdk/issues/10332 + triggerContext = { + 'run.num': undefined, + 'run.id': `unknown-${finalBody.blockHeight}-${finalBody.runNum}`, + 'run.trigger.type': 'unknown', + 'run.trigger.blockHeight': finalBody.blockHeight, + }; + } + + if (!triggerContext) triggerContext = {}; + triggerContext['run.num'] = `${finalBody.runNum}`; + + break; + } + case SLOG_TYPES.CRANK.START: { + crankContext = { + 'crank.num': finalBody.crankNum, + 'crank.type': finalBody.crankType, + }; + break; + } + case SLOG_TYPES.CLIST: { + assert(!!crankContext); + crankContext['crank.vatID'] = finalBody.vatID; + break; + } + case SLOG_TYPES.REPLAY.START: + case SLOG_TYPES.REPLAY.FINISH: { + replayContext = { replay: true, 'crank.vatID': finalBody.vatID }; + break; + } + case SLOG_TYPES.DELIVER: { + if (replayContext) { + assert(finalBody.replay); + replayContext = { + ...replayContext, + 'crank.vatID': finalBody.vatID, + 'crank.deliveryNum': finalBody.deliveryNum, + }; + } else { + assert(!!crankContext && !finalBody.replay); + crankContext = { + ...crankContext, + 'crank.vatID': finalBody.vatID, + 'crank.deliveryNum': finalBody.deliveryNum, + }; + } + + delete finalBody.deliveryNum; + delete finalBody.replay; + + break; + } + case SLOG_TYPES.DELIVER_RESULT: { + delete finalBody.deliveryNum; + delete finalBody.replay; + + break; + } + case SLOG_TYPES.SYSCALL: + case SLOG_TYPES.SYSCALL_RESULT: { + eventLogAttributes['crank.syscallNum'] = finalBody.syscallNum; + + delete finalBody.deliveryNum; + delete finalBody.replay; + delete finalBody.syscallNum; + + break; + } + case SLOG_TYPES.CONSOLE: { + delete finalBody.crankNum; + delete finalBody.deliveryNum; + + break; + } + default: + // All other log types are logged as is (using existing contexts) without + // any change to the slogs or any contributions to the contexts. This also + // means that any unexpected slog type will pass through. To fix that, add + // all remaining cases of expected slog types above with a simple break + // statement and log a warning here + break; + } + + const logAttributes = { + ...staticContext, + 'process.uptime': monotime, + ...initContext, // Optional prelude + ...blockContext, // Block is the first level of execution nesting + ...triggerContext, // run and trigger info is nested next + ...crankContext, // Finally cranks are the last level of nesting + ...replayContext, // Replay is a substitute for crank context during vat page in + ...eventLogAttributes, + }; + + /** + * Add any after report operations here + * like resetting context data + */ + switch (body.type) { + case SLOG_TYPES.KERNEL.INIT.FINISH: { + initContext = null; + break; + } + case SLOG_TYPES.COSMIC_SWINGSET.BOOTSTRAP_BLOCK.START: { + triggerContext = { + 'run.num': undefined, + 'run.id': `bootstrap-${finalBody.blockTime}`, + 'run.trigger.type': 'bootstrap', + 'run.trigger.time': finalBody.blockTime, + }; + break; + } + case SLOG_TYPES.COSMIC_SWINGSET.AFTER_COMMIT_STATS: + case SLOG_TYPES.COSMIC_SWINGSET.BOOTSTRAP_BLOCK.FINISH: { + blockContext = null; + break; + } + // eslint-disable-next-line no-restricted-syntax + case SLOG_TYPES.COSMIC_SWINGSET.RUN.FINISH: { + assert(!!triggerContext); + persistContext(finalBody.remainingBeans ? {} : triggerContext); + triggerContext = null; + break; + } + case SLOG_TYPES.CRANK.FINISH: { + crankContext = null; + break; + } + case SLOG_TYPES.REPLAY.FINISH: { + replayContext = null; + break; + } + default: + break; + } + + return { + attributes: /** @type {T & LogAttributes} */ (logAttributes), + body: finalBody, + timestamp, + }; + }; + + return slogProcessor; +}; diff --git a/packages/telemetry/src/ingest-slog-entrypoint.js b/packages/telemetry/src/ingest-slog-entrypoint.js index 3a10d8463f28..ee6c6fca36e3 100755 --- a/packages/telemetry/src/ingest-slog-entrypoint.js +++ b/packages/telemetry/src/ingest-slog-entrypoint.js @@ -11,7 +11,8 @@ import { makeSlogSender } from './make-slog-sender.js'; const LINE_COUNT_TO_FLUSH = 10000; const ELAPSED_MS_TO_FLUSH = 3000; -const MAX_LINE_COUNT_PER_PERIOD = 1000; +const MAX_LINE_COUNT_PER_PERIOD = 10000; +const MAX_BLOCKS_PER_PERIOD = 10; const PROCESSING_PERIOD = 1000; async function run() { @@ -29,7 +30,7 @@ async function run() { return; } - const [slogFile] = args; + const slogFile = args[0] === '-' ? undefined : args[0]; const slogSender = await makeSlogSender({ serviceName, stateDir: '.', @@ -56,14 +57,21 @@ async function run() { const lines = readline.createInterface({ input: slogF }); const slogFileName = slogFile || '*stdin*'; - const progressFileName = `${slogFileName}.ingest-progress`; - if (!fs.existsSync(progressFileName)) { - const progress = { virtualTimeOffset: 0, lastSlogTime: 0 }; - fs.writeFileSync(progressFileName, JSON.stringify(progress)); + const progressFileName = slogFile && `${slogFileName}.ingest-progress`; + const progress = { virtualTimeOffset: 0, lastSlogTime: 0 }; + if (progressFileName) { + if (!fs.existsSync(progressFileName)) { + fs.writeFileSync(progressFileName, JSON.stringify(progress)); + } else { + Object.assign( + progress, + JSON.parse(fs.readFileSync(progressFileName).toString()), + ); + } } - const progress = JSON.parse(fs.readFileSync(progressFileName).toString()); let linesProcessedThisPeriod = 0; + let blocksInThisPeriod = 0; let startOfLastPeriod = 0; let lastTime = Date.now(); @@ -75,10 +83,12 @@ async function run() { return; } await slogSender.forceFlush?.(); - fs.writeFileSync(progressFileName, JSON.stringify(progress)); + if (progressFileName) { + fs.writeFileSync(progressFileName, JSON.stringify(progress)); + } }; - console.log(`parsing`, slogFileName); + console.warn(`parsing`, slogFileName); let update = false; const maybeUpdateStats = async now => { @@ -106,9 +116,14 @@ async function run() { continue; } + const isAfterCommit = obj.type === 'cosmic-swingset-after-commit-stats'; + // Maybe wait for the next period to process a bunch of lines. let maybeWait; - if (linesProcessedThisPeriod >= MAX_LINE_COUNT_PER_PERIOD) { + if ( + linesProcessedThisPeriod >= MAX_LINE_COUNT_PER_PERIOD || + blocksInThisPeriod >= MAX_BLOCKS_PER_PERIOD + ) { const delayMS = PROCESSING_PERIOD - (now - startOfLastPeriod); maybeWait = new Promise(resolve => setTimeout(resolve, delayMS)); } @@ -118,8 +133,8 @@ async function run() { if (now - startOfLastPeriod >= PROCESSING_PERIOD) { startOfLastPeriod = now; linesProcessedThisPeriod = 0; + blocksInThisPeriod = 0; } - linesProcessedThisPeriod += 1; if (progress.virtualTimeOffset) { const virtualTime = obj.time + progress.virtualTimeOffset; @@ -133,10 +148,17 @@ async function run() { // Use the original. slogSender(obj); } + + linesProcessedThisPeriod += 1; + if (isAfterCommit) { + blocksInThisPeriod += 1; + lastTime = Date.now(); + await stats(true); + } } await stats(true); - console.log( + console.warn( `done parsing`, slogFileName, `(${lineCount} lines, ${byteCount} bytes)`, diff --git a/packages/telemetry/src/otel-context-aware-slog.js b/packages/telemetry/src/otel-context-aware-slog.js new file mode 100644 index 000000000000..51891460eba8 --- /dev/null +++ b/packages/telemetry/src/otel-context-aware-slog.js @@ -0,0 +1,131 @@ +/* eslint-env node */ +import { logs, SeverityNumber } from '@opentelemetry/api-logs'; +import { OTLPLogExporter } from '@opentelemetry/exporter-logs-otlp-http'; +import { Resource } from '@opentelemetry/resources'; +import { + LoggerProvider, + SimpleLogRecordProcessor, +} from '@opentelemetry/sdk-logs'; +import { readFileSync, writeFileSync } from 'fs'; +import { makeContextualSlogProcessor } from './context-aware-slog.js'; +import { getResourceAttributes } from './index.js'; +import { serializeSlogObj } from './serialize-slog-obj.js'; + +const DEFAULT_CONTEXT_FILE = 'slog-context.json'; +const FILE_ENCODING = 'utf8'; + +/** + * @param {string} filePath + */ +export const getContextFilePersistenceUtils = filePath => { + console.warn(`Using file ${filePath} for slogger context`); + + return { + /** + * @param {import('./context-aware-slog.js').Context} context + */ + persistContext: context => { + try { + writeFileSync(filePath, serializeSlogObj(context), FILE_ENCODING); + } catch (err) { + console.error('Error writing context to file: ', err); + } + }, + + /** + * @returns {import('./context-aware-slog.js').Context | null} + */ + restoreContext: () => { + try { + return JSON.parse(readFileSync(filePath, FILE_ENCODING)); + } catch (parseErr) { + console.error('Error reading context from file: ', parseErr); + return null; + } + }, + }; +}; + +/** + * @param {import('./index.js').MakeSlogSenderOptions} options + */ +export const makeSlogSender = async options => { + const { CHAIN_ID, OTEL_EXPORTER_OTLP_ENDPOINT } = options.env || {}; + if (!(OTEL_EXPORTER_OTLP_ENDPOINT && options.stateDir)) + return console.error( + 'Ignoring invocation of slogger "context-aware-slog" without the presence of "OTEL_EXPORTER_OTLP_ENDPOINT" and "stateDir"', + ); + + const loggerProvider = new LoggerProvider({ + resource: new Resource(getResourceAttributes(options)), + }); + + const otelLogExporter = new OTLPLogExporter({ keepAlive: true }); + const logRecordProcessor = new SimpleLogRecordProcessor(otelLogExporter); + + loggerProvider.addLogRecordProcessor(logRecordProcessor); + + logs.setGlobalLoggerProvider(loggerProvider); + const logger = logs.getLogger('default'); + + const persistenceUtils = getContextFilePersistenceUtils( + process.env.SLOG_CONTEXT_FILE_PATH || + `${options.stateDir}/${DEFAULT_CONTEXT_FILE}`, + ); + + const contextualSlogProcessor = makeContextualSlogProcessor( + { 'chain-id': CHAIN_ID }, + persistenceUtils, + ); + + /** + * @param {import('./context-aware-slog.js').Slog} slog + */ + const slogSender = slog => { + const { timestamp, ...logRecord } = contextualSlogProcessor(slog); + + const [secondsStr, fractionStr] = String(timestamp).split('.'); + const seconds = parseInt(secondsStr, 10); + const nanoSeconds = parseInt( + (fractionStr || String(0)).padEnd(9, String(0)).slice(0, 9), + 10, + ); + + logger.emit({ + ...JSON.parse(serializeSlogObj(logRecord)), + severityNumber: SeverityNumber.INFO, + timestamp: [seconds, nanoSeconds], + }); + }; + + const shutdown = async () => { + await Promise.resolve(); + const errors = []; + + try { + await logRecordProcessor.shutdown(); + } catch (err) { + errors.push(err); + } + + try { + await otelLogExporter.forceFlush(); + } catch (err) { + errors.push(err); + } + + switch (errors.length) { + case 0: + return; + case 1: + throw errors[0]; + default: + throw AggregateError(errors); + } + }; + + return Object.assign(slogSender, { + forceFlush: () => otelLogExporter.forceFlush(), + shutdown, + }); +}; diff --git a/packages/telemetry/src/slog-file.js b/packages/telemetry/src/slog-file.js index 3c091211a5f5..e7b49d559bd1 100644 --- a/packages/telemetry/src/slog-file.js +++ b/packages/telemetry/src/slog-file.js @@ -11,7 +11,7 @@ export const makeSlogSender = async ({ env: { SLOGFILE } = {} } = {}) => { const slogSender = (slogObj, jsonObj = serializeSlogObj(slogObj)) => { // eslint-disable-next-line prefer-template - void stream.write(jsonObj + '\n'); + stream.write(jsonObj + '\n').catch(() => {}); }; return Object.assign(slogSender, { diff --git a/packages/telemetry/src/slog-to-otel.js b/packages/telemetry/src/slog-to-otel.js index d4b4abc4a442..87b36fd269d9 100644 --- a/packages/telemetry/src/slog-to-otel.js +++ b/packages/telemetry/src/slog-to-otel.js @@ -915,7 +915,7 @@ export const makeSlogToOtelKit = (tracer, overrideAttrs = {}) => { break; } case 'cosmic-swingset-upgrade-finish': { - spans.pop(['slogAttrs.blockHeight', slogAttrs.blockHeight]); + spans.pop(['upgrade', slogAttrs.blockHeight]); dbTransactionManager.end(); break; } @@ -971,6 +971,16 @@ export const makeSlogToOtelKit = (tracer, overrideAttrs = {}) => { spans.pop('bridge-inbound'); break; } + case 'cosmic-swingset-timer-poll': { + spans.push(['timer-poll', slogAttrs.blockTime]); + spans.pop('timer-poll'); + break; + } + case 'cosmic-swingset-install-bundle': { + spans.push(['install-bundle', slogAttrs.endoZipBase64Sha512]); + spans.pop('install-bundle'); + break; + } case 'cosmic-swingset-end-block-start': { // Add `end-block` as an event onto the encompassing `block` span spans.top()?.addEvent('end-block-action', cleanAttrs(slogAttrs), now); diff --git a/yarn.lock b/yarn.lock index f2059f6e6bc1..ce24469095a3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1544,13 +1544,6 @@ resolved "https://registry.yarnpkg.com/@endo/env-options/-/env-options-1.1.7.tgz#f8f9186010cff12506fdd8f5c8cd4d9051830fd8" integrity sha512-8twSTbM45rzIP0lHw99ei1EaW98H2BXYKjCTUcq1qgK2OvQWaoiXNcJvUQQo1g7i3oPwbXTQsY69L+nTNeCDyA== -"@endo/errors@^1.2.6": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@endo/errors/-/errors-1.2.6.tgz#d237b08dfb32a1c5474d83b4cbeb6363783a7767" - integrity sha512-Ly8qCgEoc3d23qklib87PPC829KmkpIkPSMnIiEFnTCedVs55LCoXz01bVEanR4lrCB/qkzjx7n21BwWbscc8Q== - dependencies: - ses "^1.9.0" - "@endo/errors@^1.2.7": version "1.2.7" resolved "https://registry.yarnpkg.com/@endo/errors/-/errors-1.2.7.tgz#cd8513a8e5544f4caec3eb47dd2ec101b445ea8f" @@ -1578,13 +1571,6 @@ "@babel/traverse" "^7.23.6" source-map-js "^1.2.0" -"@endo/eventual-send@^1.2.6": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@endo/eventual-send/-/eventual-send-1.2.6.tgz#43d0f4567e3318491b3720bd7d13eef5448f5384" - integrity sha512-wD2OhDDvW8y519q6B8H5jox5mXau6OdTIlYQGzI2lk7xtPasydh2SgdQsX6u1jLAXVcJuNqW7wWgLmvk42ncVA== - dependencies: - "@endo/env-options" "^1.1.7" - "@endo/eventual-send@^1.2.7": version "1.2.7" resolved "https://registry.yarnpkg.com/@endo/eventual-send/-/eventual-send-1.2.7.tgz#b4f5408bba1dd1974f147ecb8c346d443b5a31f5" @@ -1605,16 +1591,7 @@ "@endo/pass-style" "^1.4.6" "@endo/patterns" "^1.4.6" -"@endo/far@^1.0.0": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@endo/far/-/far-1.1.6.tgz#ca5804da58762cf8b7ecbf8bdd902254d898d456" - integrity sha512-rpMzGyyumpk0rXxIh189zimhMJknzfyJX+HCiYHXELk/iuX53HqwqVobP9HWB65lD9M2nwySgXWtxI75Lx4Afw== - dependencies: - "@endo/errors" "^1.2.6" - "@endo/eventual-send" "^1.2.6" - "@endo/pass-style" "^1.4.4" - -"@endo/far@^1.1.8": +"@endo/far@^1.0.0", "@endo/far@^1.1.8": version "1.1.8" resolved "https://registry.yarnpkg.com/@endo/far/-/far-1.1.8.tgz#c8212b8182dd671719dc54e55f6406115f2966de" integrity sha512-xtfKPj1bhefpMouI+6q6zjfwDSSnaCZaSDqjClBrx6SnEO1B3ARdxtmiMEOgCdsw1XakvQwq8HDUWqDWEusJFQ== @@ -1689,17 +1666,6 @@ "@endo/stream" "^1.2.7" ses "^1.9.1" -"@endo/pass-style@^1.4.4": - version "1.4.4" - resolved "https://registry.yarnpkg.com/@endo/pass-style/-/pass-style-1.4.4.tgz#01c1d6ffc4af3e39b7c8cb8b912d9f6b28d02e55" - integrity sha512-RlZMt2kKQUYfrxh9G4RZ8eQs+Bb6DwT7P8TbJZGfgIRYajL5I5zAdByz9PA8P0+aj4PZpKnTUfKwlhNs+tNV0w== - dependencies: - "@endo/env-options" "^1.1.7" - "@endo/errors" "^1.2.6" - "@endo/eventual-send" "^1.2.6" - "@endo/promise-kit" "^1.1.6" - "@fast-check/ava" "^1.1.5" - "@endo/pass-style@^1.4.6": version "1.4.6" resolved "https://registry.yarnpkg.com/@endo/pass-style/-/pass-style-1.4.6.tgz#75092d33ad5183be120fb662361eef44c28f7768" @@ -1722,13 +1688,6 @@ "@endo/marshal" "^1.6.1" "@endo/promise-kit" "^1.1.7" -"@endo/promise-kit@^1.1.6": - version "1.1.6" - resolved "https://registry.yarnpkg.com/@endo/promise-kit/-/promise-kit-1.1.6.tgz#0357c09973fd28be0ef8cb18fbfbb3cfaf1f993b" - integrity sha512-14HtlfeUfm9voakcDF4hK15NlyzHtlPFBjJh42ZmWW3aGXmUJQTI/yIdv0zPXcMkogCdeBNKXpQSqIsYehAowQ== - dependencies: - ses "^1.9.0" - "@endo/promise-kit@^1.1.7": version "1.1.7" resolved "https://registry.yarnpkg.com/@endo/promise-kit/-/promise-kit-1.1.7.tgz#04c84ef2a2047b94925fcc8ad4feb22cb0a7b2a0" @@ -3042,6 +3001,13 @@ dependencies: "@octokit/openapi-types" "^18.0.0" +"@opentelemetry/api-logs@0.53.0": + version "0.53.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/api-logs/-/api-logs-0.53.0.tgz#c478cbd8120ec2547b64edfa03a552cfe42170be" + integrity sha512-8HArjKx+RaAI8uEIgcORbZIPklyh1YLjPSBus8hjRmvLi6DeFzgOcdZ7KwPabKj8mXF8dX0hyfAyGfycz0DbFw== + dependencies: + "@opentelemetry/api" "^1.0.0" + "@opentelemetry/api@^1.0.0": version "1.4.1" resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.4.1.tgz#ff22eb2e5d476fbc2450a196e40dd243cc20c28f" @@ -3052,6 +3018,13 @@ resolved "https://registry.yarnpkg.com/@opentelemetry/api/-/api-1.3.0.tgz#27c6f776ac3c1c616651e506a89f438a0ed6a055" integrity sha512-YveTnGNsFFixTKJz09Oi4zYkiLT5af3WpZDu4aIUM7xX+2bHAkOJayFTVQd6zB8kkWPpbua4Ha6Ql00grdLlJQ== +"@opentelemetry/core@1.26.0", "@opentelemetry/core@^1.14.0": + version "1.26.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.26.0.tgz#7d84265aaa850ed0ca5813f97d831155be42b328" + integrity sha512-1iKxXXE8415Cdv0yjG3G6hQnB5eVEsJce3QaawX8SjDn0mAS0ZM8fAbZZJD4ajvhC15cePvosSCut404KrIIvQ== + dependencies: + "@opentelemetry/semantic-conventions" "1.27.0" + "@opentelemetry/core@1.9.1": version "1.9.1" resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.9.1.tgz#e343337e1a7bf30e9a6aef3ef659b9b76379762a" @@ -3059,12 +3032,16 @@ dependencies: "@opentelemetry/semantic-conventions" "1.9.1" -"@opentelemetry/core@^1.14.0": - version "1.15.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/core/-/core-1.15.2.tgz#5b170bf223a2333884bbc2d29d95812cdbda7c9f" - integrity sha512-+gBv15ta96WqkHZaPpcDHiaz0utiiHZVfm2YOYSqFGrUaJpPkMoSuLBB58YFQGi6Rsb9EHos84X6X5+9JspmLw== +"@opentelemetry/exporter-logs-otlp-http@0.53.0": + version "0.53.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.53.0.tgz#1b4a152ea427ec4581532880fd0d620cc559cb11" + integrity sha512-cSRKgD/n8rb+Yd+Cif6EnHEL/VZg1o8lEcEwFji1lwene6BdH51Zh3feAD9p2TyVoBKrl6Q9Zm2WltSp2k9gWQ== dependencies: - "@opentelemetry/semantic-conventions" "1.15.2" + "@opentelemetry/api-logs" "0.53.0" + "@opentelemetry/core" "1.26.0" + "@opentelemetry/otlp-exporter-base" "0.53.0" + "@opentelemetry/otlp-transformer" "0.53.0" + "@opentelemetry/sdk-logs" "0.53.0" "@opentelemetry/exporter-prometheus@~0.35.0": version "0.35.1" @@ -3093,6 +3070,14 @@ dependencies: "@opentelemetry/core" "1.9.1" +"@opentelemetry/otlp-exporter-base@0.53.0": + version "0.53.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.53.0.tgz#dfe51874b869c687c3cb463b70cddda7de282762" + integrity sha512-UCWPreGQEhD6FjBaeDuXhiMf6kkBODF0ZQzrk/tuQcaVDJ+dDQ/xhJp192H9yWnKxVpEjFrSSLnpqmX4VwX+eA== + dependencies: + "@opentelemetry/core" "1.26.0" + "@opentelemetry/otlp-transformer" "0.53.0" + "@opentelemetry/otlp-transformer@0.35.1": version "0.35.1" resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-transformer/-/otlp-transformer-0.35.1.tgz#d4333b71324b83dbb1b0b3a4cfd769b3e214c6f9" @@ -3103,6 +3088,27 @@ "@opentelemetry/sdk-metrics" "1.9.1" "@opentelemetry/sdk-trace-base" "1.9.1" +"@opentelemetry/otlp-transformer@0.53.0": + version "0.53.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/otlp-transformer/-/otlp-transformer-0.53.0.tgz#55d435db5ed5cf56b99c010827294dd4921c45c2" + integrity sha512-rM0sDA9HD8dluwuBxLetUmoqGJKSAbWenwD65KY9iZhUxdBHRLrIdrABfNDP7aiTjcgK8XFyTn5fhDz7N+W6DA== + dependencies: + "@opentelemetry/api-logs" "0.53.0" + "@opentelemetry/core" "1.26.0" + "@opentelemetry/resources" "1.26.0" + "@opentelemetry/sdk-logs" "0.53.0" + "@opentelemetry/sdk-metrics" "1.26.0" + "@opentelemetry/sdk-trace-base" "1.26.0" + protobufjs "^7.3.0" + +"@opentelemetry/resources@1.26.0": + version "1.26.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.26.0.tgz#da4c7366018bd8add1f3aa9c91c6ac59fd503cef" + integrity sha512-CPNYchBE7MBecCSVy0HKpUISEeJOniWqcHaAHpmasZ3j9o6V3AyBzhRc90jdmemq0HOxDr6ylhUbDhBqqPpeNw== + dependencies: + "@opentelemetry/core" "1.26.0" + "@opentelemetry/semantic-conventions" "1.27.0" + "@opentelemetry/resources@1.9.1", "@opentelemetry/resources@~1.9.0": version "1.9.1" resolved "https://registry.yarnpkg.com/@opentelemetry/resources/-/resources-1.9.1.tgz#5ad3d80ba968a3a0e56498ce4bc82a6a01f2682f" @@ -3111,6 +3117,23 @@ "@opentelemetry/core" "1.9.1" "@opentelemetry/semantic-conventions" "1.9.1" +"@opentelemetry/sdk-logs@0.53.0": + version "0.53.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-logs/-/sdk-logs-0.53.0.tgz#ec8b69278c4e683c13c58ed4285a47c27f5799c6" + integrity sha512-dhSisnEgIj/vJZXZV6f6KcTnyLDx/VuQ6l3ejuZpMpPlh9S1qMHiZU9NMmOkVkwwHkMy3G6mEBwdP23vUZVr4g== + dependencies: + "@opentelemetry/api-logs" "0.53.0" + "@opentelemetry/core" "1.26.0" + "@opentelemetry/resources" "1.26.0" + +"@opentelemetry/sdk-metrics@1.26.0": + version "1.26.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-1.26.0.tgz#37bb0afb1d4447f50aab9cdd05db6f2d8b86103e" + integrity sha512-0SvDXmou/JjzSDOjUmetAAvcKQW6ZrvosU0rkbDGpXvvZN+pQF6JbK/Kd4hNdK4q/22yeruqvukXEJyySTzyTQ== + dependencies: + "@opentelemetry/core" "1.26.0" + "@opentelemetry/resources" "1.26.0" + "@opentelemetry/sdk-metrics@1.9.1", "@opentelemetry/sdk-metrics@~1.9.0": version "1.9.1" resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-1.9.1.tgz#babc162a81df9884c16b1e67c2dd26ab478f3080" @@ -3120,6 +3143,15 @@ "@opentelemetry/resources" "1.9.1" lodash.merge "4.6.2" +"@opentelemetry/sdk-trace-base@1.26.0": + version "1.26.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.26.0.tgz#0c913bc6d2cfafd901de330e4540952269ae579c" + integrity sha512-olWQldtvbK4v22ymrKLbIcBi9L2SpMO84sCPY54IVsJhP9fRsxJT194C/AVaAuJzLE30EdhhM1VmvVYR7az+cw== + dependencies: + "@opentelemetry/core" "1.26.0" + "@opentelemetry/resources" "1.26.0" + "@opentelemetry/semantic-conventions" "1.27.0" + "@opentelemetry/sdk-trace-base@1.9.1", "@opentelemetry/sdk-trace-base@~1.9.0": version "1.9.1" resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-trace-base/-/sdk-trace-base-1.9.1.tgz#c349491b432a7e0ae7316f0b48b2d454d79d2b84" @@ -3129,21 +3161,16 @@ "@opentelemetry/resources" "1.9.1" "@opentelemetry/semantic-conventions" "1.9.1" -"@opentelemetry/semantic-conventions@1.15.2": - version "1.15.2" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.15.2.tgz#3bafb5de3e20e841dff6cb3c66f4d6e9694c4241" - integrity sha512-CjbOKwk2s+3xPIMcd5UNYQzsf+v94RczbdNix9/kQh38WiQkM90sUOi3if8eyHFgiBjBjhwXrA7W3ydiSQP9mw== +"@opentelemetry/semantic-conventions@1.27.0", "@opentelemetry/semantic-conventions@~1.27.0": + version "1.27.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.27.0.tgz#1a857dcc95a5ab30122e04417148211e6f945e6c" + integrity sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg== "@opentelemetry/semantic-conventions@1.9.1": version "1.9.1" resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.9.1.tgz#ad3367684a57879392513479e0a436cb2ac46dad" integrity sha512-oPQdbFDmZvjXk5ZDoBGXG8B4tSB/qW5vQunJWQMFUBp7Xe8O1ByPANueJ+Jzg58esEBegyyxZ7LRmfJr7kFcFg== -"@opentelemetry/semantic-conventions@~1.27.0": - version "1.27.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/semantic-conventions/-/semantic-conventions-1.27.0.tgz#1a857dcc95a5ab30122e04417148211e6f945e6c" - integrity sha512-sAay1RrB+ONOem0OZanAR1ZI/k7yDpnOQSQmTMuGImUQb2y8EbSaCJ94FQluM74xoU03vlb2d2U90hZluL6nQg== - "@parcel/watcher@2.0.4": version "2.0.4" resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.0.4.tgz#f300fef4cc38008ff4b8c29d92588eced3ce014b" @@ -4936,11 +4963,6 @@ commander@7.1.0: resolved "https://registry.yarnpkg.com/commander/-/commander-7.1.0.tgz#f2eaecf131f10e36e07d894698226e36ae0eb5ff" integrity sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg== -commander@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-11.1.0.tgz#62fdce76006a68e5c1ab3314dc92e800eb83d906" - integrity sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ== - commander@^12.1.0: version "12.1.0" resolved "https://registry.yarnpkg.com/commander/-/commander-12.1.0.tgz#01423b36f501259fdaac4d0e4d60c96c991585d3" @@ -10052,7 +10074,7 @@ proto-list@~1.2.1: resolved "https://registry.yarnpkg.com/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849" integrity sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk= -protobufjs@^6.8.8, protobufjs@^7.2.4, protobufjs@^7.2.6: +protobufjs@^6.8.8, protobufjs@^7.2.4, protobufjs@^7.2.6, protobufjs@^7.3.0: version "7.4.0" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-7.4.0.tgz#7efe324ce9b3b61c82aae5de810d287bc08a248a" integrity sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw== @@ -10649,13 +10671,6 @@ serve-static@^2.1.0: parseurl "^1.3.3" send "^1.0.0" -ses@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/ses/-/ses-1.9.0.tgz#ebf2de9759a21b09550aef0645c3f9b817409381" - integrity sha512-ZDAkixRUIPId1oXVxDhj1sIzFUeJ3vzaJCd64Ra1owuVH6Bcd+IOGrJtiFqUTA+YC9w8jTE9XkZTwin+hkbn5Q== - dependencies: - "@endo/env-options" "^1.1.7" - ses@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ses/-/ses-1.9.1.tgz#54991a775cea5f9e27292bbb6706941a8203062a"