From 97f4c942142d0e2aa7cca803cbda97d896c5f1ae Mon Sep 17 00:00:00 2001 From: J M Rossy Date: Wed, 22 Nov 2023 12:48:00 -0500 Subject: [PATCH] Various CLI fixes and UX improvements (#2952) ### Description - Fixes https://github.com/hyperlane-xyz/issues/issues/747 - Fixes https://github.com/hyperlane-xyz/issues/issues/746 - Fixes https://github.com/hyperlane-xyz/issues/issues/730 - Fixes https://github.com/hyperlane-xyz/issues/issues/727 - Fixes https://github.com/hyperlane-xyz/issues/issues/729 - Fixes https://github.com/hyperlane-xyz/hyperlane-monorepo/issues/2234 - Fixes https://github.com/hyperlane-xyz/issues/issues/728 ### Drive-by changes Make chai and mocha versions consistent across monorepo ### Backward compatibility Yes ### Testing Setup unit testing for CLI and run as part of CI jobs --- .changeset/shy-apes-provide.md | 5 + solidity/package.json | 2 +- typescript/cli/.mocharc.json | 8 ++ typescript/cli/cli.ts | 6 +- typescript/cli/examples/chain-config.yaml | 6 ++ typescript/cli/logger.ts | 1 + typescript/cli/package.json | 12 ++- typescript/cli/src/config/chain.test.ts | 18 ++++ typescript/cli/src/config/chain.ts | 29 ++++-- typescript/cli/src/config/warp.ts | 2 +- typescript/cli/src/deploy/core.ts | 2 +- typescript/cli/src/deploy/warp.ts | 24 +++-- typescript/cli/src/utils/chains.ts | 21 +++-- typescript/cli/src/utils/files.ts | 20 +++- typescript/cli/src/utils/time.test.ts | 10 ++ typescript/cli/src/utils/time.ts | 12 ++- typescript/helloworld/package.json | 3 +- typescript/infra/package.json | 4 +- typescript/sdk/package.json | 3 +- typescript/utils/package.json | 7 +- yarn.lock | 110 ++++------------------ 21 files changed, 159 insertions(+), 146 deletions(-) create mode 100644 .changeset/shy-apes-provide.md create mode 100644 typescript/cli/.mocharc.json create mode 100644 typescript/cli/src/config/chain.test.ts create mode 100644 typescript/cli/src/utils/time.test.ts diff --git a/.changeset/shy-apes-provide.md b/.changeset/shy-apes-provide.md new file mode 100644 index 0000000000..b89e285a39 --- /dev/null +++ b/.changeset/shy-apes-provide.md @@ -0,0 +1,5 @@ +--- +'@hyperlane-xyz/cli': patch +--- + +Various user experience improvements diff --git a/solidity/package.json b/solidity/package.json index 12e18bd914..6aaa23f4c1 100644 --- a/solidity/package.json +++ b/solidity/package.json @@ -13,7 +13,7 @@ "@nomiclabs/hardhat-waffle": "^2.0.6", "@typechain/ethers-v5": "^10.0.0", "@typechain/hardhat": "^6.0.0", - "chai": "^4.3.0", + "chai": "^4.3.6", "ethereum-waffle": "^4.0.10", "ethers": "^5.7.2", "hardhat": "^2.19.0", diff --git a/typescript/cli/.mocharc.json b/typescript/cli/.mocharc.json new file mode 100644 index 0000000000..1f56f16c30 --- /dev/null +++ b/typescript/cli/.mocharc.json @@ -0,0 +1,8 @@ +{ + "extensions": ["ts"], + "spec": ["src/**/*.test.*"], + "node-option": [ + "experimental-specifier-resolution=node", + "loader=ts-node/esm" + ] +} \ No newline at end of file diff --git a/typescript/cli/cli.ts b/typescript/cli/cli.ts index a25672e7ea..5265f8462c 100644 --- a/typescript/cli/cli.ts +++ b/typescript/cli/cli.ts @@ -8,6 +8,7 @@ import { configCommand } from './src/commands/config.js'; import { deployCommand } from './src/commands/deploy.js'; import { sendCommand } from './src/commands/send.js'; import { statusCommand } from './src/commands/status.js'; +import { readJson } from './src/utils/files.js'; // From yargs code: const MISSING_PARAMS_ERROR = 'Not enough non-option arguments'; @@ -15,15 +16,16 @@ const MISSING_PARAMS_ERROR = 'Not enough non-option arguments'; console.log(chalk.blue('Hyperlane'), chalk.magentaBright('CLI')); try { + const version = readJson('./package.json').version; + await yargs(process.argv.slice(2)) .scriptName('hyperlane') - // TODO get version num from package.json - .version(false) .command(chainsCommand) .command(configCommand) .command(deployCommand) .command(sendCommand) .command(statusCommand) + .version(version) .demandCommand() .strict() .help() diff --git a/typescript/cli/examples/chain-config.yaml b/typescript/cli/examples/chain-config.yaml index 40333a44b4..5a7cb32bef 100644 --- a/typescript/cli/examples/chain-config.yaml +++ b/typescript/cli/examples/chain-config.yaml @@ -2,6 +2,7 @@ # Consists of a map of chain names to metadata # Schema here: https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/typescript/sdk/src/metadata/chainMetadataTypes.ts --- +# You can define a full config for a new chain mychainname: # Required fields: chainId: 1234567890 # Number: Use EIP-155 for EVM chains @@ -42,3 +43,8 @@ mychainname: estimateBlockTime: 15 # Number: Rough estimate of time per block in seconds # transactionOverrides: # Object: Properties to include when forming transaction requests # Any tx fields are allowed + +# Alternatively, you can extend a core chain config with only fields to be overridden +sepolia: + rpcUrls: + - http: https://mycustomrpc.com diff --git a/typescript/cli/logger.ts b/typescript/cli/logger.ts index 271431edc8..5f2c220d31 100644 --- a/typescript/cli/logger.ts +++ b/typescript/cli/logger.ts @@ -50,6 +50,7 @@ export const logPink = (...args: any) => export const logGray = (...args: any) => console.log(chalk.gray(...args)); export const logGreen = (...args: any) => console.log(chalk.green(...args)); export const logRed = (...args: any) => console.log(chalk.red(...args)); +export const logTip = (...args: any) => console.log(chalk.bgYellow(...args)); export const errorRed = (...args: any) => console.error(chalk.red(...args)); export const log = (...args: any) => console.log(...args); export const logTable = (...args: any) => console.table(...args); diff --git a/typescript/cli/package.json b/typescript/cli/package.json index 5086abc6cb..c0787cb75b 100644 --- a/typescript/cli/package.json +++ b/typescript/cli/package.json @@ -4,6 +4,7 @@ "description": "A command-line utility for common Hyperlane operations", "dependencies": { "@hyperlane-xyz/sdk": "3.1.7", + "@hyperlane-xyz/utils": "3.1.7", "@inquirer/prompts": "^3.0.0", "bignumber.js": "^9.1.1", "chalk": "^5.3.0", @@ -14,26 +15,31 @@ "zod": "^3.21.2" }, "devDependencies": { + "@types/mocha": "^10.0.1", "@types/node": "^18.14.5", "@types/yargs": "^17.0.24", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", + "chai": "^4.3.6", "eslint": "^8.43.0", "eslint-config-prettier": "^8.8.0", + "mocha": "^10.2.0", "prettier": "^2.8.8", "typescript": "^5.1.6" }, "scripts": { "hyperlane": "node ./dist/cli.js", "build": "tsc", - "dev": "tsc --watch", "clean": "rm -rf ./dist", + "dev": "tsc --watch", "lint": "eslint . --ext .ts", - "prettier": "prettier --write ./src ./examples" + "prettier": "prettier --write ./src ./examples", + "test": "mocha --config .mocharc.json" }, "files": [ "./dist", - "./examples" + "./examples", + "package.json" ], "main": "./dist/index.js", "types": "./dist/index.d.ts", diff --git a/typescript/cli/src/config/chain.test.ts b/typescript/cli/src/config/chain.test.ts new file mode 100644 index 0000000000..99f2a55c73 --- /dev/null +++ b/typescript/cli/src/config/chain.test.ts @@ -0,0 +1,18 @@ +import { expect } from 'chai'; + +import { readChainConfigs } from './chain.js'; + +describe('readChainConfigs', () => { + const chainToMetadata = readChainConfigs('./examples/chain-config.yaml'); + + it('parses and validates correctly', () => { + expect(chainToMetadata.mychainname.chainId).to.equal(1234567890); + }); + + it('merges core configs', () => { + expect(chainToMetadata.sepolia.chainId).to.equal(11155111); + expect(chainToMetadata.sepolia.rpcUrls[0].http).to.equal( + 'https://mycustomrpc.com', + ); + }); +}); diff --git a/typescript/cli/src/config/chain.ts b/typescript/cli/src/config/chain.ts index 7088fc8f14..7a1f2509e8 100644 --- a/typescript/cli/src/config/chain.ts +++ b/typescript/cli/src/config/chain.ts @@ -1,16 +1,21 @@ import { confirm, input, select } from '@inquirer/prompts'; -import fs from 'fs'; import { ChainMap, ChainMetadata, ChainMetadataSchema, + chainMetadata as coreChainMetadata, } from '@hyperlane-xyz/sdk'; -import { ProtocolType } from '@hyperlane-xyz/utils'; +import { ProtocolType, objMerge } from '@hyperlane-xyz/utils'; import { errorRed, log, logBlue, logGreen } from '../../logger.js'; import { getMultiProvider } from '../context.js'; -import { FileFormat, mergeYamlOrJson, readYamlOrJson } from '../utils/files.js'; +import { + FileFormat, + isFile, + mergeYamlOrJson, + readYamlOrJson, +} from '../utils/files.js'; export function readChainConfigs(filePath: string) { log(`Reading file configs in ${filePath}`); @@ -25,8 +30,16 @@ export function readChainConfigs(filePath: string) { process.exit(1); } - for (const [chain, metadata] of Object.entries(chainToMetadata)) { - const parseResult = ChainMetadataSchema.safeParse(metadata); + // Validate configs from file and merge in core configs as needed + for (const chain of Object.keys(chainToMetadata)) { + if (coreChainMetadata[chain]) { + // For core chains, merge in the default config to allow users to override only some fields + chainToMetadata[chain] = objMerge( + coreChainMetadata[chain], + chainToMetadata[chain], + ); + } + const parseResult = ChainMetadataSchema.safeParse(chainToMetadata[chain]); if (!parseResult.success) { errorRed( `Chain config for ${chain} is invalid, please see https://github.com/hyperlane-xyz/hyperlane-monorepo/blob/main/typescript/cli/examples/chain-config.yaml for an example`, @@ -34,13 +47,13 @@ export function readChainConfigs(filePath: string) { errorRed(JSON.stringify(parseResult.error.errors)); process.exit(1); } - if (metadata.name !== chain) { + if (chainToMetadata[chain].name !== chain) { errorRed(`Chain ${chain} name does not match key`); process.exit(1); } } - // Ensure multiprovider accepts this metadata + // Ensure MultiProvider accepts this metadata getMultiProvider(chainToMetadata); logGreen(`All chain configs in ${filePath} are valid`); @@ -48,7 +61,7 @@ export function readChainConfigs(filePath: string) { } export function readChainConfigsIfExists(filePath: string) { - if (!fs.existsSync(filePath)) { + if (!isFile(filePath)) { log('No chain config file provided'); return {}; } else { diff --git a/typescript/cli/src/config/warp.ts b/typescript/cli/src/config/warp.ts index 1b456b21df..f793959d9a 100644 --- a/typescript/cli/src/config/warp.ts +++ b/typescript/cli/src/config/warp.ts @@ -99,7 +99,7 @@ export async function createWarpConfig({ const syntheticChains = await runMultiChainSelectionStep( customChains, - 'Select the chains to which the base token will be connected', + 'Select chains to which the base token will be connected', ); // TODO add more prompts here to support customizing the token metadata diff --git a/typescript/cli/src/deploy/core.ts b/typescript/cli/src/deploy/core.ts index 12bbbdda52..fd3aa7a6bd 100644 --- a/typescript/cli/src/deploy/core.ts +++ b/typescript/cli/src/deploy/core.ts @@ -79,7 +79,7 @@ export async function runCoreDeploy({ if (!chains?.length) { chains = await runMultiChainSelectionStep( customChains, - 'Select chains to which core contacts will be deployed', + 'Select chains to connect', ); } const artifacts = await runArtifactStep(chains, artifactsPath); diff --git a/typescript/cli/src/deploy/warp.ts b/typescript/cli/src/deploy/warp.ts index 317df98c06..d44b75e82b 100644 --- a/typescript/cli/src/deploy/warp.ts +++ b/typescript/cli/src/deploy/warp.ts @@ -28,6 +28,7 @@ import { getMergedContractAddresses, } from '../context.js'; import { + isFile, prepNewArtifactsFiles, runFileSelectionStep, writeJson, @@ -53,12 +54,14 @@ export async function runWarpDeploy({ }) { const { multiProvider, signer } = getContextWithSigner(key, chainConfigPath); - if (!warpConfigPath) { + if (!warpConfigPath || !isFile(warpConfigPath)) { warpConfigPath = await runFileSelectionStep( './configs', 'Warp config', 'warp', ); + } else { + log(`Using warp config at ${warpConfigPath}`); } const warpRouteConfig = readWarpRouteConfig(warpConfigPath); @@ -115,11 +118,6 @@ async function runBuildConfigStep({ const mergedContractAddrs = getMergedContractAddresses(artifacts); - logGray( - 'Contract addresses from artifacts:\n', - JSON.stringify(mergedContractAddrs[baseChainName], null, 4), - ); - // Create configs that coalesce together values from the config file, // the artifacts, and the SDK as a fallback const configMap: ChainMap = { @@ -130,12 +128,12 @@ async function runBuildConfigStep({ ? base.address! : ethers.constants.AddressZero, owner, - mailbox: base.mailbox || mergedContractAddrs[baseChainName].mailbox, + mailbox: base.mailbox || mergedContractAddrs[baseChainName]?.mailbox, interchainSecurityModule: base.interchainSecurityModule || - mergedContractAddrs[baseChainName].interchainSecurityModule || - mergedContractAddrs[baseChainName].multisigIsm, - // ismFactory: mergedContractAddrs[baseChainName].routingIsmFactory, // fix when updating from routingIsm + mergedContractAddrs[baseChainName]?.interchainSecurityModule || + mergedContractAddrs[baseChainName]?.multisigIsm, + // ismFactory: mergedContractAddrs[baseChainName].routingIsmFactory, // TODO fix when updating from routingIsm foreignDeployment: base.foreignDeployment, name: baseMetadata.name, symbol: baseMetadata.symbol, @@ -154,9 +152,9 @@ async function runBuildConfigStep({ mailbox: synthetic.mailbox || mergedContractAddrs[sChainName].mailbox, interchainSecurityModule: synthetic.interchainSecurityModule || - mergedContractAddrs[sChainName].interchainSecurityModule || - mergedContractAddrs[sChainName].multisigIsm, - // ismFactory: mergedContractAddrs[sChainName].routingIsmFactory, // fix + mergedContractAddrs[sChainName]?.interchainSecurityModule || + mergedContractAddrs[sChainName]?.multisigIsm, + // ismFactory: mergedContractAddrs[sChainName].routingIsmFactory, // TODO fix foreignDeployment: synthetic.foreignDeployment, }; } diff --git a/typescript/cli/src/utils/chains.ts b/typescript/cli/src/utils/chains.ts index 8b2470878d..c3a07a7eeb 100644 --- a/typescript/cli/src/utils/chains.ts +++ b/typescript/cli/src/utils/chains.ts @@ -9,7 +9,7 @@ import { testnetChainsMetadata, } from '@hyperlane-xyz/sdk'; -import { log, logBlue } from '../../logger.js'; +import { log, logBlue, logRed, logTip } from '../../logger.js'; // A special value marker to indicate user selected // a new chain in the list @@ -34,14 +34,17 @@ export async function runMultiChainSelectionStep( message = 'Select chains', ) { const choices = getChainChoices(customChains); - const chains = (await checkbox({ - message, - choices, - pageSize: 20, - })) as string[]; - handleNewChain(chains); - if (!chains?.length) throw new Error('No chains selected'); - return chains; + while (true) { + logTip('Use SPACE key to select chains, then press ENTER'); + const chains = (await checkbox({ + message, + choices, + pageSize: 20, + })) as string[]; + handleNewChain(chains); + if (chains?.length >= 2) return chains; + else logRed('Please select at least 2 chains'); + } } function getChainChoices(customChains: ChainMap) { diff --git a/typescript/cli/src/utils/files.ts b/typescript/cli/src/utils/files.ts index 7d57dec276..aa0cfd65f5 100644 --- a/typescript/cli/src/utils/files.ts +++ b/typescript/cli/src/utils/files.ts @@ -6,14 +6,24 @@ import { parse as yamlParse, stringify as yamlStringify } from 'yaml'; import { objMerge } from '@hyperlane-xyz/utils'; -import { logBlue } from '../../logger.js'; +import { log, logBlue } from '../../logger.js'; import { getTimestampForFilename } from './time.js'; export type FileFormat = 'yaml' | 'json'; +export function isFile(filepath: string) { + if (!filepath) return false; + try { + return fs.existsSync(filepath) && fs.lstatSync(filepath).isFile(); + } catch (error) { + log(`Error checking for file: ${filepath}`); + return false; + } +} + export function readFileAtPath(filepath: string) { - if (!fs.existsSync(filepath)) { + if (!isFile(filepath)) { throw Error(`File doesn't exist at ${filepath}`); } return fs.readFileSync(filepath, 'utf8'); @@ -21,7 +31,7 @@ export function readFileAtPath(filepath: string) { export function writeFileAtPath(filepath: string, value: string) { const dirname = path.dirname(filepath); - if (!fs.existsSync(dirname)) { + if (!isFile(dirname)) { fs.mkdirSync(dirname, { recursive: true }); } fs.writeFileSync(filepath, value); @@ -47,7 +57,7 @@ export function mergeJson>( filepath: string, obj: T, ) { - if (fs.existsSync(filepath)) { + if (isFile(filepath)) { const previous = readJson(filepath); writeJson(filepath, objMerge(previous, obj)); } else { @@ -75,7 +85,7 @@ export function mergeYaml>( filepath: string, obj: T, ) { - if (fs.existsSync(filepath)) { + if (isFile(filepath)) { const previous = readYaml(filepath); writeYaml(filepath, objMerge(previous, obj)); } else { diff --git a/typescript/cli/src/utils/time.test.ts b/typescript/cli/src/utils/time.test.ts new file mode 100644 index 0000000000..622ff0e1c3 --- /dev/null +++ b/typescript/cli/src/utils/time.test.ts @@ -0,0 +1,10 @@ +import { expect } from 'chai'; + +import { getTimestampForFilename } from './time.js'; + +describe('getTimestampForFilename', () => { + it('structures timestamp correctly', () => { + const filename = getTimestampForFilename(); + expect(filename).to.match(/\d{4}-\d{2}-\d{2}-\d{2}-\d{2}-\d{2}/); + }); +}); diff --git a/typescript/cli/src/utils/time.ts b/typescript/cli/src/utils/time.ts index a490684cc3..b8353577bd 100644 --- a/typescript/cli/src/utils/time.ts +++ b/typescript/cli/src/utils/time.ts @@ -1,6 +1,12 @@ export function getTimestampForFilename() { + const pad = (n: number) => + n.toLocaleString('en-US', { minimumIntegerDigits: 2, useGrouping: false }); const now = new Date(); - return `${now.getFullYear()}-${ - now.getMonth() + 1 - }-${now.getDate()}-${now.getHours()}-${now.getMinutes()}-${now.getSeconds()}`; + const year = now.getFullYear(); + const month = pad(now.getMonth() + 1); + const date = pad(now.getDate()); + const hours = pad(now.getHours()); + const minutes = pad(now.getMinutes()); + const seconds = pad(now.getSeconds()); + return `${year}-${month}-${date}-${hours}-${minutes}-${seconds}`; } diff --git a/typescript/helloworld/package.json b/typescript/helloworld/package.json index 4b3a541283..61a653448d 100644 --- a/typescript/helloworld/package.json +++ b/typescript/helloworld/package.json @@ -14,10 +14,9 @@ "@trivago/prettier-plugin-sort-imports": "^4.2.1", "@typechain/ethers-v5": "^10.0.0", "@typechain/hardhat": "^6.0.0", - "@types/mocha": "^9.1.0", "@typescript-eslint/eslint-plugin": "^5.62.0", "@typescript-eslint/parser": "^5.62.0", - "chai": "^4.3.0", + "chai": "^4.3.6", "eslint": "^8.43.0", "eslint-config-prettier": "^8.8.0", "ethereum-waffle": "^4.0.10", diff --git a/typescript/infra/package.json b/typescript/infra/package.json index b8302f1573..2a5d237464 100644 --- a/typescript/infra/package.json +++ b/typescript/infra/package.json @@ -29,12 +29,12 @@ "@nomiclabs/hardhat-ethers": "^2.2.1", "@nomiclabs/hardhat-waffle": "^2.0.6", "@types/chai": "^4.2.21", - "@types/mocha": "^9.1.0", + "@types/mocha": "^10.0.1", "@types/node": "^16.9.1", "@types/prompts": "^2.0.14", "@types/sinon-chai": "^3.2.12", "@types/yargs": "^17.0.24", - "chai": "^4.3.4", + "chai": "^4.3.6", "ethereum-waffle": "^4.0.10", "ethers": "^5.7.2", "hardhat": "^2.19.0", diff --git a/typescript/sdk/package.json b/typescript/sdk/package.json index 3894d62cae..b0b156b5c7 100644 --- a/typescript/sdk/package.json +++ b/typescript/sdk/package.json @@ -24,6 +24,7 @@ "devDependencies": { "@nomiclabs/hardhat-ethers": "^2.2.1", "@nomiclabs/hardhat-waffle": "^2.0.6", + "@types/mocha": "^10.0.1", "@types/node": "^16.9.1", "@types/sinon": "^17.0.1", "@types/sinon-chai": "^3.2.12", @@ -33,7 +34,7 @@ "eslint": "^8.43.0", "ethereum-waffle": "^4.0.10", "hardhat": "^2.19.0", - "mocha": "^9.2.2", + "mocha": "^10.2.0", "prettier": "^2.8.8", "sinon": "^13.0.2", "ts-node": "^10.8.0", diff --git a/typescript/utils/package.json b/typescript/utils/package.json index a8bcee7f1b..0d4f03ba97 100644 --- a/typescript/utils/package.json +++ b/typescript/utils/package.json @@ -6,11 +6,12 @@ "@cosmjs/encoding": "^0.31.3", "@solana/web3.js": "^1.78.0", "bignumber.js": "^9.1.1", - "ethers": "^5.7.2", - "mocha": "^10.2.0" + "ethers": "^5.7.2" }, "devDependencies": { - "chai": "^4.3.0", + "@types/mocha": "^10.0.1", + "chai": "^4.3.6", + "mocha": "^10.2.0", "prettier": "^2.8.8", "typescript": "5.1.6" }, diff --git a/yarn.lock b/yarn.lock index 825a640ddc..7bbdab0454 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4233,16 +4233,20 @@ __metadata: resolution: "@hyperlane-xyz/cli@workspace:typescript/cli" dependencies: "@hyperlane-xyz/sdk": "npm:3.1.7" + "@hyperlane-xyz/utils": "npm:3.1.7" "@inquirer/prompts": "npm:^3.0.0" + "@types/mocha": "npm:^10.0.1" "@types/node": "npm:^18.14.5" "@types/yargs": "npm:^17.0.24" "@typescript-eslint/eslint-plugin": "npm:^5.62.0" "@typescript-eslint/parser": "npm:^5.62.0" bignumber.js: "npm:^9.1.1" + chai: "npm:^4.3.6" chalk: "npm:^5.3.0" eslint: "npm:^8.43.0" eslint-config-prettier: "npm:^8.8.0" ethers: "npm:^5.7.2" + mocha: "npm:^10.2.0" prettier: "npm:^2.8.8" terminal-link: "npm:^3.0.0" typescript: "npm:^5.1.6" @@ -4266,7 +4270,7 @@ __metadata: "@openzeppelin/contracts-upgradeable": "npm:^v4.9.3" "@typechain/ethers-v5": "npm:^10.0.0" "@typechain/hardhat": "npm:^6.0.0" - chai: "npm:^4.3.0" + chai: "npm:^4.3.6" ethereum-waffle: "npm:^4.0.10" ethers: "npm:^5.7.2" hardhat: "npm:^2.19.0" @@ -4298,10 +4302,9 @@ __metadata: "@trivago/prettier-plugin-sort-imports": "npm:^4.2.1" "@typechain/ethers-v5": "npm:^10.0.0" "@typechain/hardhat": "npm:^6.0.0" - "@types/mocha": "npm:^9.1.0" "@typescript-eslint/eslint-plugin": "npm:^5.62.0" "@typescript-eslint/parser": "npm:^5.62.0" - chai: "npm:^4.3.0" + chai: "npm:^4.3.6" eslint: "npm:^8.43.0" eslint-config-prettier: "npm:^8.8.0" ethereum-waffle: "npm:^4.0.10" @@ -4346,14 +4349,14 @@ __metadata: "@safe-global/protocol-kit": "npm:^1.2.0" "@solana/web3.js": "npm:^1.78.0" "@types/chai": "npm:^4.2.21" - "@types/mocha": "npm:^9.1.0" + "@types/mocha": "npm:^10.0.1" "@types/node": "npm:^16.9.1" "@types/prompts": "npm:^2.0.14" "@types/sinon-chai": "npm:^3.2.12" "@types/yargs": "npm:^17.0.24" asn1.js: "npm:5.4.1" aws-kms-ethers-signer: "npm:^0.1.3" - chai: "npm:^4.3.4" + chai: "npm:^4.3.6" dotenv: "npm:^10.0.0" ethereum-waffle: "npm:^4.0.10" ethers: "npm:^5.7.2" @@ -4400,6 +4403,7 @@ __metadata: "@solana/web3.js": "npm:^1.78.0" "@types/coingecko-api": "npm:^1.0.10" "@types/debug": "npm:^4.1.7" + "@types/mocha": "npm:^10.0.1" "@types/node": "npm:^16.9.1" "@types/sinon": "npm:^17.0.1" "@types/sinon-chai": "npm:^3.2.12" @@ -4416,7 +4420,7 @@ __metadata: ethereum-waffle: "npm:^4.0.10" ethers: "npm:^5.7.2" hardhat: "npm:^2.19.0" - mocha: "npm:^9.2.2" + mocha: "npm:^10.2.0" prettier: "npm:^2.8.8" sinon: "npm:^13.0.2" ts-node: "npm:^10.8.0" @@ -4435,8 +4439,9 @@ __metadata: dependencies: "@cosmjs/encoding": "npm:^0.31.3" "@solana/web3.js": "npm:^1.78.0" + "@types/mocha": "npm:^10.0.1" bignumber.js: "npm:^9.1.1" - chai: "npm:^4.3.0" + chai: "npm:^4.3.6" ethers: "npm:^5.7.2" mocha: "npm:^10.2.0" prettier: "npm:^2.8.8" @@ -6209,10 +6214,10 @@ __metadata: languageName: node linkType: hard -"@types/mocha@npm:^9.1.0": - version: 9.1.1 - resolution: "@types/mocha@npm:9.1.1" - checksum: cf8283e253f62b613d4cbac0d37fe4b88bc0aca72f3da4177cadeb86c989167613e2a23186ca1eba6bf17ce1e47b673875c4bd5a6fd0d3729a71d53f95e517f3 +"@types/mocha@npm:^10.0.1": + version: 10.0.5 + resolution: "@types/mocha@npm:10.0.5" + checksum: 522bef34c56d10957f396cf08838cc04eabfe8e77e6229bd668a1b7b61602bcedcab71ccb02cb9e10f42644de6c3fd51cdcf3f2817abcf9cc5f31e47647adc3c languageName: node linkType: hard @@ -6599,13 +6604,6 @@ __metadata: languageName: node linkType: hard -"@ungap/promise-all-settled@npm:1.1.2": - version: 1.1.2 - resolution: "@ungap/promise-all-settled@npm:1.1.2" - checksum: ee8fe811becd830f5e276ec63469ec66c22503eb140064580e712c9fccadfd54157c462188640ba6765d5c21f829e7120eb37afb5ead512684b9a1ab86d2db66 - languageName: node - linkType: hard - "@wagmi/chains@npm:1.6.0": version: 1.6.0 resolution: "@wagmi/chains@npm:1.6.0" @@ -7878,7 +7876,7 @@ __metadata: languageName: node linkType: hard -"chai@npm:^4.3.0, chai@npm:^4.3.4, chai@npm:^4.3.6": +"chai@npm:^4.3.4, chai@npm:^4.3.6": version: 4.3.6 resolution: "chai@npm:4.3.6" dependencies: @@ -8646,18 +8644,6 @@ __metadata: languageName: node linkType: hard -"debug@npm:4.3.3": - version: 4.3.3 - resolution: "debug@npm:4.3.3" - dependencies: - ms: "npm:2.1.2" - peerDependenciesMeta: - supports-color: - optional: true - checksum: 723a9570dcd15d146ea4992f0dca12467d1b00f534abb42473df166d36826fcae8bab045aef59ac2f407b47a23266110bc0e646df8ac82f7800c11384f82050e - languageName: node - linkType: hard - "debug@npm:^3.1.0": version: 3.2.7 resolution: "debug@npm:3.2.7" @@ -13065,15 +13051,6 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:4.2.1": - version: 4.2.1 - resolution: "minimatch@npm:4.2.1" - dependencies: - brace-expansion: "npm:^1.1.7" - checksum: 27e49fb720116face9588c29634404edc0c6677e5448ba01b4ec6179002461cc4fabc842497a0537edc5aa87bc93e65cfb0fe6dc32b850563429a64836dd1d54 - languageName: node - linkType: hard - "minimatch@npm:5.0.1": version: 5.0.1 resolution: "minimatch@npm:5.0.1" @@ -13364,41 +13341,6 @@ __metadata: languageName: node linkType: hard -"mocha@npm:^9.2.2": - version: 9.2.2 - resolution: "mocha@npm:9.2.2" - dependencies: - "@ungap/promise-all-settled": "npm:1.1.2" - ansi-colors: "npm:4.1.1" - browser-stdout: "npm:1.3.1" - chokidar: "npm:3.5.3" - debug: "npm:4.3.3" - diff: "npm:5.0.0" - escape-string-regexp: "npm:4.0.0" - find-up: "npm:5.0.0" - glob: "npm:7.2.0" - growl: "npm:1.10.5" - he: "npm:1.2.0" - js-yaml: "npm:4.1.0" - log-symbols: "npm:4.1.0" - minimatch: "npm:4.2.1" - ms: "npm:2.1.3" - nanoid: "npm:3.3.1" - serialize-javascript: "npm:6.0.0" - strip-json-comments: "npm:3.1.1" - supports-color: "npm:8.1.1" - which: "npm:2.0.2" - workerpool: "npm:6.2.0" - yargs: "npm:16.2.0" - yargs-parser: "npm:20.2.4" - yargs-unparser: "npm:2.0.0" - bin: - _mocha: bin/_mocha - mocha: bin/mocha - checksum: 8ee58bff8694ad4013fc0fbb5670c5ec6d8404c601df2d4ae798fad01dd03b5f9395347cf59167006b315a14813a6f839290d60dcbdee8ef4246afe43609d2dc - languageName: node - linkType: hard - "mock-fs@npm:^4.1.0": version: 4.14.0 resolution: "mock-fs@npm:4.14.0" @@ -13514,15 +13456,6 @@ __metadata: languageName: node linkType: hard -"nanoid@npm:3.3.1": - version: 3.3.1 - resolution: "nanoid@npm:3.3.1" - bin: - nanoid: bin/nanoid.cjs - checksum: 306f2cb9e4dcfb94738b09de9dc63839a37db33626f66b24dbcc8f66d4b91784645794a7c4f250d629e4d66f5385164c6748c58ac5b7c95217e9e048590efbe4 - languageName: node - linkType: hard - "nanoid@npm:3.3.3": version: 3.3.3 resolution: "nanoid@npm:3.3.3" @@ -17877,7 +17810,7 @@ __metadata: languageName: node linkType: hard -"which@npm:2.0.2, which@npm:^2.0.1, which@npm:^2.0.2": +"which@npm:^2.0.1, which@npm:^2.0.2": version: 2.0.2 resolution: "which@npm:2.0.2" dependencies: @@ -17930,13 +17863,6 @@ __metadata: languageName: node linkType: hard -"workerpool@npm:6.2.0": - version: 6.2.0 - resolution: "workerpool@npm:6.2.0" - checksum: c7dce6eae02098d70fe9924503bd95688564a1316cbb96fe55600f7ede0e66f1f2fea4d18aaec71fcee32373d17eda0bf87ac4dac8e5823e90ca1524aac90bdc - languageName: node - linkType: hard - "workerpool@npm:6.2.1": version: 6.2.1 resolution: "workerpool@npm:6.2.1"