diff --git a/.changeset/five-birds-invite.md b/.changeset/five-birds-invite.md new file mode 100644 index 0000000000..75af7c20a3 --- /dev/null +++ b/.changeset/five-birds-invite.md @@ -0,0 +1,6 @@ +--- +"hardhat": patch +--- + +Upgraded EDR to (https://github.com/NomicFoundation/edr/releases/tag/%40nomicfoundation%2Fedr%400.11.0): +- Replaced const enums with non-const enums in \*.d.ts files diff --git a/.changeset/lazy-hornets-clap.md b/.changeset/lazy-hornets-clap.md deleted file mode 100644 index 61606d5fb9..0000000000 --- a/.changeset/lazy-hornets-clap.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nomicfoundation/hardhat-chai-matchers": patch ---- - -Fixed a problem when `.withArgs` was used with arrays with different length diff --git a/.changeset/lucky-items-peel.md b/.changeset/lucky-items-peel.md new file mode 100644 index 0000000000..91a944e213 --- /dev/null +++ b/.changeset/lucky-items-peel.md @@ -0,0 +1,5 @@ +--- + +--- + +Patch 4 diff --git a/.changeset/polite-mugs-cry.m b/.changeset/polite-mugs-cry.m deleted file mode 100644 index b03cb1f534..0000000000 --- a/.changeset/polite-mugs-cry.m +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@nomiclabs/hardhat-etherscan": patch ---- - -Fix URLs for the Aurora networks (thanks @zZoMROT!) diff --git a/.changeset/thin-peaches-taste.md b/.changeset/thin-peaches-taste.md new file mode 100644 index 0000000000..57044cfe19 --- /dev/null +++ b/.changeset/thin-peaches-taste.md @@ -0,0 +1,5 @@ +--- +"hardhat": patch +--- + +feat: support chainId values above 2^32 - 1 for local account transac… diff --git a/.changeset/tricky-points-wash.md b/.changeset/tricky-points-wash.md new file mode 100644 index 0000000000..91a944e213 --- /dev/null +++ b/.changeset/tricky-points-wash.md @@ -0,0 +1,5 @@ +--- + +--- + +Patch 4 diff --git a/.changeset/weak-frogs-care.md b/.changeset/weak-frogs-care.md new file mode 100644 index 0000000000..b19f6e7db9 --- /dev/null +++ b/.changeset/weak-frogs-care.md @@ -0,0 +1,5 @@ +--- +"hardhat": patch +--- + +Support chainId values above 2^32 - 1 for local account transactions diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000000..058cb8e06f --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,22 @@ +{ + "name": "Hardhat", + "image": "mcr.microsoft.com/devcontainers/base:bullseye", + "features": { + "ghcr.io/devcontainers/features/node:1": { + "version": "18" + } + }, + "postCreateCommand": "scripts/setup.sh", + "containerEnv": { + "ALCHEMY_URL": "${localEnv:ALCHEMY_URL}", + "INFURA_URL": "${localEnv:INFURA_URL}" + }, + "customizations": { + "vscode": { + "extensions": [ + "esbenp.prettier-vscode", + "NomicFoundation.hardhat-solidity" + ] + } + } +} diff --git a/.gitattributes b/.gitattributes index 4583bf4050..6428757b1a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,6 @@ *.sol linguist-language=Solidity # prevent github actions to checkout files with crlf line endings -* -text +* text=auto + +*.sol text eol=lf +*.d.ts text eol=lf diff --git a/.github/ISSUE_TEMPLATE/hardhat-3-alpha.yml b/.github/ISSUE_TEMPLATE/hardhat-3-alpha.yml new file mode 100644 index 0000000000..b3345f957b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/hardhat-3-alpha.yml @@ -0,0 +1,8 @@ +name: Hardhat 3 Alpha feedback +description: Give feedback about the Hardhat 3 Alpha. +labels: hardhat-3-alpha +body: + - type: textarea + attributes: + label: "Feedback" + placeholder: "Your feedback" diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index ccb3f96bcc..1ae7e34d85 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,6 +7,15 @@ Please: - consider the checklist items below - keep the ones that make sense for your PR, and - DELETE the items that DON'T make sense for your PR. + +## Note about small PRs and airdrop farming + +We generally really appreciate external contributions, and strongly encourage meaningful additions and fixes! However, due to a recent increase in small PRs potentially created to farm airdrops, we might need to close a PR without explanation if any of the following apply: + +- It is a change of very minor value that still requires additional review time/fixes (e.g. PRs fixing trivial spelling errors that can’t be merged in less than a couple of minutes due to incorrect suggestions) +- It introduces inconsequential changes (e.g. rewording phrases) +- The author of the PR does not respond in a timely manner +- We suspect the Github account of the author was created for airdrop farming --> - [ ] Because this PR includes a **bug fix**, relevant tests have been included. diff --git a/.github/actions/setup-env/action.yml b/.github/actions/setup-env/action.yml new file mode 100644 index 0000000000..4a1d77f36b --- /dev/null +++ b/.github/actions/setup-env/action.yml @@ -0,0 +1,43 @@ +name: Setup env +description: Sets up node and pnpm + +inputs: + pnpm-version: + description: Version of pnpm to install + required: false + default: "9" + node-version: + description: Version of node to install + required: false + default: "18" + cache-save: + description: Whether to save the pnpm cache + required: false + default: "false" +outputs: + cache-hit: + description: Whether the cache was restored + value: ${{ steps.setup-node.outputs.cache-hit || steps.cache-restore.outputs.cache-hit }} + +runs: + using: composite + steps: + - uses: pnpm/action-setup@v4 + with: + version: ${{ inputs.pnpm-version }} + - uses: actions/setup-node@v4 + id: setup-node + with: + node-version: ${{ inputs.node-version }} + cache: ${{ inputs.cache-save == 'true' && 'pnpm' || '' }} + cache-dependency-path: "**/pnpm-lock.yaml" + - id: pnpm + if: inputs.cache-save == 'false' + run: pnpm store path --silent | xargs -I {} -0 echo "path={}" | tee -a $GITHUB_OUTPUT + shell: bash + - uses: actions/cache/restore@v4 + id: cache-restore + if: inputs.cache-save == 'false' + with: + path: ${{ steps.pnpm.outputs.path }} + key: node-cache-${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }} diff --git a/.github/config/regression-tests.yml b/.github/config/regression-tests.yml new file mode 100644 index 0000000000..d5b63616eb --- /dev/null +++ b/.github/config/regression-tests.yml @@ -0,0 +1,806 @@ +repositories: + Elytro-eth/soul-wallet-contract: + forge-version: v0.3.0 + hardhat-config: | + export default { + "paths": { + "sources": "contracts", + "tests": { + "solidity": "test" + } + }, + "solidity": { + "version": "0.8.24", + "remappings": [ + "@soulwallet-core/=lib/soulwallet-core/", + "@source/=contracts/", + "@arbitrum/nitro-contracts=lib/nitro-contracts/", + "@solady=lib/solady/", + "@solenv=lib/solenv/src/", + "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", + "@account-abstraction/=lib/account-abstraction/", + "@crypto-lib/=lib/crypto-lib/src/", + "forge-std/=lib/forge-std/src/", + "@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/" + ], + "settings": { + "viaIR": true, + "optimizer": { + "enabled": true, + "runs": 100000 + }, + "evmVersion": "cancun", + "metadata": { + "bytecodeHash": "none", + "appendCBOR": false + } + } + }, + "solidityTest": { + "testFail": true, + "rpcEndpoints": { + "goerli": "${GOERLI_RPC_URL}", + "arbitrumgoerli": "${ARBITRUM_GOERLI_RPC_URL}", + "optimismgoerli": "${OPTIMISM_GOERLI_RPC_URL}", + "etherum": "${ETHERUM_RPC_URL}", + "arbitrum": "${ARBITRUM_RPC_URL}", + "optimism": "${OPTIMISM_RPC_URL}", + "scrollsepolia": "${SCROLL_SEPOLIA_RPC_URL}", + "basesepolia": "${BASE_SEPOLIA_RPC_URL}" + } + } + }; + ignore: | + # unknown cheatcode with selector 0xce817d47 (startBroadcast(uint256)) + test/hooks/2fa/Crypto2FAHook.t.sol + test/automation/ClaimInterest.t.sol + test/modules/socialRecovery/SocialRecoveryModule.t.sol + + # unknown cheatcode with selector 0xf0259e92 (breakpoint(string)) + test/paymaster/ERC20Paymaster.t.sol + ref: fc7cc084563ad1bda870df841b77caa9ee3a3661 + PaulRBerg/prb-math: + forge-version: v0.3.0 + hardhat-config: | + export default { + "paths": { + "sources": "src", + "tests": { + "solidity": "test" + } + }, + "solidity": { + "version": "0.8.26", + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000000 + }, + "evmVersion": "shanghai" + } + }, + "solidityTest": { + "fuzz": { + "runs": 256 + } + } + }; + ref: 93be53541f39a0c1e80818a9183b2acb3908ae74 + PaulRBerg/prb-proxy: + forge-version: v0.3.0 + hardhat-config: | + export default { + "paths": { + "sources": "src", + "tests": { + "solidity": "test" + } + }, + "solidity": { + "version": "0.8.23", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + }, + "evmVersion": "paris", + "metadata": { + "bytecodeHash": "none", + "appendCBOR": false + } + } + }, + "solidityTest": { + "fuzz": { + "runs": 1000, + "maxTestRejects": 1000000 + }, + "fsPermissions": { + "read": [ + "./out-optimized" + ] + }, + "rpcEndpoints": { + "arbitrum": "https://arbitrum-mainnet.infura.io/v3/${API_KEY_INFURA}", + "avalanche": "https://avalanche-mainnet.infura.io/v3/${API_KEY_INFURA}", + "bnb_smart_chain": "https://bsc-dataseed.binance.org", + "gnosis_chain": "https://rpc.gnosischain.com", + "goerli": "https://goerli.infura.io/v3/${API_KEY_INFURA}", + "localhost": "http://localhost:8545", + "mainnet": "https://eth-mainnet.g.alchemy.com/v2/${API_KEY_ALCHEMY}", + "optimism": "https://optimism-mainnet.infura.io/v3/${API_KEY_INFURA}", + "polygon": "https://polygon-mainnet.infura.io/v3/${API_KEY_INFURA}", + "sepolia": "https://sepolia.infura.io/v3/${API_KEY_INFURA}" + } + } + }; + ref: e45f5325d4b6003227a6c4bdaefac9453f89de2e + PaulRBerg/prb-test: + forge-version: v0.3.0 + hardhat-config: | + export default { + "paths": { + "sources": "src", + "tests": { + "solidity": "test" + } + }, + "solidity": { + "version": "0.8.26", + "settings": { + "optimizer": { + "enabled": false + }, + "evmVersion": "shanghai" + } + }, + "solidityTest": { + "fuzz": { + "runs": 100, + "maxTestRejects": 100000 + } + } + }; + ref: cd07166bdd12c7c4a899cb53951653b53939a644 + ProjectOpenSea/seaport: + forge-version: v0.3.0 + hardhat-config: | + export default { + "paths": { + "sources": "contracts", + "tests": { + "solidity": "test/foundry" + } + }, + "solidity": { + "version": "0.8.24", + "remappings": [ + "@rari-capital/solmate/=lib/solmate/", + "ds-test/=lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "murky/=lib/murky/src/", + "@openzeppelin/=lib/openzeppelin-contracts/", + "solarray/=lib/solarray/src/", + "solady/=lib/solady/", + "seaport-sol/=lib/seaport-sol/", + "seaport-types/=lib/seaport-types/", + "seaport-core/=lib/seaport-core/", + "seaport/=contracts/" + ], + "settings": { + "evmVersion": "cancun", + "optimizer": { + "runs": 4294967292 + } + } + }, + "solidityTest": { + "fuzz": { + "runs": 1000 + }, + "fsPermissions": { + "read": [ + "./optimized-out", + "./reference-out" + ], + "write": [ + "./call-metrics.txt", + "./mutation-metrics.txt", + "./assume-metrics.txt", + "./fuzz_debug.json" + ] + } + } + }; + ignore: | + # Invalid hex bytecode for contract (this is caused by the lack of support for dynamic linking) + test/foundry + ref: 585b2ef8376dd979171522027bbdb048c2a4999c + Uniswap/UniswapX: + forge-version: v0.3.0 + hardhat-config: | + export default { + "paths": { + "sources": "src", + "tests": { + "solidity": "test" + } + }, + "solidity": { + "version": "0.8.24", + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-gas-snapshot/=lib/forge-gas-snapshot/src/", + "forge-std/=lib/forge-std/src/", + "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/", + "permit2/=lib/permit2/", + "solmate/=lib/solmate/", + "solarray/=lib/solarray/src/" + ], + "settings": { + "optimizer": { + "runs": 1000000 + } + } + }, + "solidityTest": { + "ffi": true, + "fsPermissions": { + "readWrite": [ + ".forge-snapshots/" + ] + } + } + }; + ignore: | + */integration/* + + # unknown cheatcode with selector 0x7fb5297f (startBroadcast()) + test/script/DeployDutch.t.sol + test/script/DeployExclusiveDutch.t.sol + test/script/DeployPriorityOrderReactor.t.sol + + # unknown cheatcode with selector 0x3cad9d7b (startSnapshotGas(string)) + test/base/EthOutput.t.sol + test/validation-contracts/ExclusiveFillerValidation.t.sol + test/lib/NonLinearDutchDecayLib.t.sol + test/base/ProtocolFees.t.sol + test/fill-macros/DirectTakerFillMacro.t.sol + test/executors/SwapRouter02Executor.t.sol + + # unknown cheatcode with selector 0xdd9fca12 (snapshotGasLastCall(string)) + test/base/BaseReactor.t.sol + test/reactors/PriorityOrderReactor.t.sol + test/reactors/V3DutchOrderReactor.t.sol + test/reactors/V2DutchOrderReactor.t.sol + test/reactors/LimitOrderReactor.t.sol + test/reactors/BaseDutchOrderReactor.t.sol + test/reactors/ExclusiveDutchOrderReactor.t.sol + test/reactors/DutchOrderReactor.t.sol + ref: 4013dfa4bc53b823b406b035a9b5eb579607eb99 + Vectorized/solady: + forge-version: v0.3.0 + hardhat-config: | + export default { + "paths": { + "sources": "src", + "tests": { + "solidity": "test" + } + }, + "solidity": { + "version": "0.8.28", + "remappings": [ + "forge-std=test/utils/forge-std/" + ], + "settings": { + "optimizer": { + "enabled": true, + "runs": 1000 + }, + "evmVersion": "cancun" + } + }, + "solidityTest": { + "blockGasLimit": BigInt(100000000), + "fsPermissions": { + "read": [ + "./test/data" + ] + }, + "fuzz": { + "runs": 256 + }, + "invariant": { + "depth": 15, + "runs": 10 + } + } + }; + ignore: | + */*7702* + */*Transient* + */ext/ithaca/* + */ext/zksync/* + + # testP256Normalized(uint256,bytes32): unknown cheatcode with selector 0xc453949e (publicKeyP256(uint256)) + test/P256.t.sol + test/WebAuthn.t.sol + + # https://github.com/NomicFoundation/hardhat/issues/6509 + # testBumpSlot(bytes32,uint256): Unknown error + test/LibStorage.t.sol + + # https://github.com/NomicFoundation/hardhat/issues/6509 + # testTargetGenerate(): Transaction reverted: contract call run out of gas and made the transaction revert + test/DeploylessPredeployQueryer.t.sol + ref: c9e079c0ca836dcc52777a1fa7227ef28e3537b3 + foundry-rs/forge-std: + forge-version: v0.3.0 + hardhat-config: | + export default { + "paths": { + "sources": "src", + "tests": { + "solidity": "test" + } + }, + "solidity": { + "version": "0.8.26", + "settings": { + "optimizer": { + "enabled": true, + "runs": 200 + } + } + }, + "solidityTest": { + "fsPermissions": { + "readWrite": [ + "./" + ] + }, + "rpcEndpoints": { + "mainnet": "https://eth-mainnet.alchemyapi.io/v2/WV407BEiBmjNJfKo9Uo_55u0z0ITyCOX", + "optimism_sepolia": "https://sepolia.optimism.io/", + "arbitrum_one_sepolia": "https://sepolia-rollup.arbitrum.io/rpc/", + "needs_undefined_env_var": "${UNDEFINED_RPC_URL_PLACEHOLDER}" + } + } + }; + ignore: | + # test_DeriveRememberKey(): unknown cheatcode with selector 0x6229498b (deriveKey(string,uint32)) + test/StdCheats.t.sol + + # StdUtilsForkTest.setUp(): Could not instantiate forked environment. Fork host: 'eth-mainnet.alchemyapi.io' (this is caused by using an invalid mainnet rpc endpoint) + test/StdUtils.t.sol + + # test_RevertIf_ChainBubbleUp(): call did not revert as expected (this is caused by using an invalid mainnet rpc endpoint) + # test_ChainRpcInitialization(): assertion failed: https://eth-mainnet.alchemyapi.io/v2/WV407BEiBmjNJfKo9Uo_55u0z0ITyCOX != https://eth.merkle.io + test/StdChains.t.sol + ref: 8ba9031ffcbe25aa0d1224d3ca263a995026e477 + kalidao/keep: + forge-version: v0.3.0 + hardhat-config: | + export default { + "paths": { + "sources": "contracts", + "tests": { + "solidity": "test" + } + }, + "solidity": { + "version": "0.8.18", + "remappings": [ + "@std/=lib/forge-std/src/", + "@solady/=lib/solady/", + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/" + ], + "settings": { + "optimizer": { + "runs": 9999999 + } + } + }, + "solidityTest": { + "testFail": true + } + }; + ref: 21213d34042b8a5a68afeb590f43018f08c81a58 + mds1/multicall: + forge-version: v0.3.0 + hardhat-config: | + export default { + "paths": { + "sources": "src", + "tests": { + "solidity": "src/test" + } + }, + "solidity": { + "version": "0.8.12", + "settings": { + "optimizer": { + "enabled": true, + "runs": 10000000 + } + }, + "remappings": [ + "forge-std/=lib/forge-std/src/", + "ds-test/=lib/forge-std/lib/ds-test/src/" + ] + }, + "solidityTest": { + "fuzz": { + "runs": 1000 + } + } + }; + ref: 19da7a56668b7b284901ef0551edb23905c6cd53 + pancakeswap/infinity-core: + forge-version: v0.3.0 + hardhat-config: | + export default { + "paths": { + "sources": "src", + "tests": { + "solidity": "test" + } + }, + "solidity": { + "version": "0.8.26", + "remappings": [ + "ds-test/=lib/forge-std/lib/ds-test/src/", + "forge-std/=lib/forge-std/src/", + "@openzeppelin/=lib/openzeppelin-contracts/", + "solmate/=lib/solmate/", + "forge-gas-snapshot/=lib/forge-gas-snapshot/src/" + ], + "settings": { + "viaIR": true, + "optimizer": { + "runs": 25666 + }, + "evmVersion": "cancun", + "metadata": { + "bytecodeHash": "none" + } + } + }, + "solidityTest": { + "testFail": true, + "ffi": true, + "fsPermissions": { + "readWrite": [ + ".forge-snapshots/" + ], + "read": [ + "./foundry-out", + "./script/config", + "./test/pool-cl/bin", + "./test/pool-bin/bin" + ] + }, + "blockGasLimit": BigInt(300000000), + "fuzz": { + "runs": 5 + } + } + }; + ignore: | + # https://github.com/NomicFoundation/hardhat/issues/6509 + # TokenLocker.setUp(): Transaction reverted without a reason string + test/vault/VaultReentrancy.t.sol + + # https://github.com/NomicFoundation/hardhat/issues/6509 + # The test is not safe to replay because it uses impure cheatcodes: function ffi(string[] calldata commandInput) external returns (bytes memory result); + # TickMathTestTest.test_getTickAtSqrtRatio_matchesJavascriptImplWithin1(): EvmError: Revert + # TickMathTestTest.test_getSqrtRatioAtTick_matchesJavaScriptImplByOneHundrethOfABip(): EvmError: Revert + test/pool-cl/libraries/TickMath.t.sol + + # unknown cheatcode with selector 0x3cad9d7b (startSnapshotGas(string)) + test/pool-cl/libraries/BitMath.t.sol + test/pool-cl/libraries/CLPosition.t.sol + test/pool-cl/libraries/LiquidityMath.t.sol + test/pool-cl/libraries/SqrtPriceMath.t.sol + test/pool-cl/libraries/SwapMath.t.sol + test/pool-cl/libraries/Tick.t.sol + + # unknown cheatcode with selector 0x51db805a (snapshotValue(string,uint256)) + test/pool-bin/BinPoolManager.t.sol + test/pool-cl/CLPoolManager.t.sol + test/vault/Vault.t.sol + + # unknown cheatcode with selector 0xdd9fca12 (snapshotGasLastCall(string)) + test/Extsload.t.sol + test/pool-bin/BinCustomCurveHook.t.sol + test/pool-bin/BinHook.t.sol + test/pool-bin/BinMintBurnFeeHook.t.sol + test/pool-bin/BinPoolManager.t.sol + test/pool-bin/libraries/BinPoolSwap.t.sol + test/pool-cl/CLCustomCurveHook.t.sol + test/pool-cl/CLMintBurnFeeHook.t.sol + test/pool-cl/libraries/TickBitmap.t.sol + ref: 9a050c44cdf801fd19753409e6a03a8026a1fd09 + pcaversaccio/createx: + forge-version: v0.3.0 + hardhat-config: | + export default { + "paths": { + "sources": "src", + "tests": { + "solidity": "test" + } + }, + "solidity": { + "version": "0.8.23", + "remappings": [ + "solady/=lib/solady/src/", + "forge-std/=lib/forge-std/src/", + "openzeppelin/=lib/openzeppelin-contracts/contracts/" + ], + "settings": { + "optimizer": { + "enabled": true, + "runs": 10000000 + }, + "viaIR": false, + "evmVersion": "paris", + "metadata": { + "bytecodeHash": "none" + } + } + }, + "solidityTest": { + "fuzz": { + "runs": 100 + }, + "fsPermissions": { + "readWrite": [ + "./" + ] + }, + "invariant": { + "runs": 256, + "depth": 15 + } + } + }; + ignore: | + # unknown cheatcode with selector 0x9cd23835 (snapshotState()) + test/public/CREATE2/CreateX.deployCreate2AndInit_4Args_CustomiseSalt.t.sol + test/public/CREATE2/CreateX.deployCreate2AndInit_4Args_CustomiseSalt.t.sol + test/public/CREATE2/CreateX.deployCreate2AndInit_5Args.t.sol + test/public/CREATE2/CreateX.deployCreate2AndInit_5Args.t.sol + test/public/CREATE2/CreateX.deployCreate2Clone_3Args.t.sol + test/public/CREATE3/CreateX.deployCreate3AndInit_4Args_CustomiseRefundAddress.t.sol + test/public/CREATE3/CreateX.deployCreate3AndInit_4Args_CustomiseRefundAddress.t.sol + test/public/CREATE2/CreateX.deployCreate2_2Args.t.sol + test/public/CREATE3/CreateX.deployCreate3AndInit_3Args.t.sol + test/public/CREATE3/CreateX.deployCreate3AndInit_3Args.t.sol + test/public/CREATE3/CreateX.deployCreate3_2Args.t.sol + test/public/CREATE3/CreateX.deployCreate3AndInit_5Args.t.sol + test/public/CREATE3/CreateX.deployCreate3AndInit_5Args.t.sol + test/public/CREATE3/CreateX.deployCreate3_1Arg.t.sol + test/public/CREATE3/CreateX.deployCreate3AndInit_4Args_CustomiseSalt.t.sol + test/public/CREATE3/CreateX.deployCreate3AndInit_4Args_CustomiseSalt.t.sol + test/internal/CreateX._generateSalt.t.sol + ref: ac7e49b93030145a646c6cffd62a81f447422309 + sablier-labs/lockup: + env: | + RPC_URL_MAINNET="https://eth-mainnet.g.alchemy.com/v2/" + forge-version: v0.3.0 + hardhat-config: | + export default { + "paths": { + "sources": "src", + "tests": { + "solidity": "tests" + } + }, + "solidity": { + "version": "0.8.26", + "remappings": [ + "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/", + "@prb/math/=node_modules/@prb/math/", + "forge-std/=node_modules/forge-std/", + "solady/=node_modules/solady/", + "solarray/=node_modules/solarray/" + ], + "settings": { + "optimizer": { + "enabled": true, + "runs": 570 + }, + "evmVersion": "shanghai", + "metadata": { + "bytecodeHash": "none" + } + } + }, + "solidityTest": { + "fsPermissions": { + "read": [ + "./out-optimized", + "package.json" + ], + "readWrite": [ + "./benchmark/results", + "./script/" + ] + }, + "blockGasLimit": BigInt(9223372036854775807), + "fuzz": { + "runs": 50, + "maxTestRejects": 1000000 + }, + "invariant": { + "runs": 20, + "depth": 20, + "failOnRevert": true, + "callOverride": false + }, + "sender": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "rpcEndpoints": { + "arbitrum": "${ARBITRUM_RPC_URL}", + "arbitrum_sepolia": "https://arbitrum-sepolia-rpc.publicnode.com", + "avalanche": "${AVALANCHE_RPC_URL}", + "base": "https://mainnet.base.org", + "base_sepolia": "https://sepolia.base.org", + "berachain_artio": "https://bartio.rpc.berachain.com/", + "blast": "https://rpc.blast.io", + "blast_sepolia": "https://sepolia.blast.io", + "bnb": "https://bsc-dataseed.binance.org", + "core_dao": "https://rpc.coredao.org", + "gnosis": "https://rpc.gnosischain.com", + "lightlink": "https://replicator.phoenix.lightlink.io/rpc/v1", + "linea": "https://rpc.linea.build", + "linea_sepolia": "https://rpc.sepolia.linea.build", + "localhost": "http://localhost:8545", + "mainnet": "${MAINNET_RPC_URL}", + "mode": "https://mainnet.mode.network/", + "mode_sepolia": "https://sepolia.mode.network/", + "morph": "https://rpc.morphl2.io", + "optimism": "${OPTIMISM_RPC_URL}", + "optimism_sepolia": "https://sepolia.optimism.io", + "polygon": "${POLYGON_RPC_URL}", + "scroll": "https://rpc.scroll.io/", + "sei": "https://evm-rpc.sei-apis.com", + "sei_testnet": "https://evm-rpc.arctic-1.seinetwork.io", + "sepolia": "${SEPOLIA_RPC_URL}", + "superseed": "https://mainnet.superseed.xyz", + "superseed_sepolia": "https://sepolia.superseed.xyz", + "taiko_hekla": "https://rpc.hekla.taiko.xyz", + "taiko_mainnet": "https://rpc.mainnet.taiko.xyz" + } + } + }; + ignore: | + # Invalid hex bytecode for contract (this is caused by the lack of support for dynamic linking) + tests + ref: a8528a6d0ca25f4f36eb9327fc87e08dc78ad0a6 + sablier-labs/v2-periphery: + env: | + RPC_URL_MAINNET="https://eth-mainnet.g.alchemy.com/v2/" + forge-version: v0.3.0 + hardhat-config: | + export default { + "paths": { + "sources": "src", + "tests": { + "solidity": "test" + } + }, + "solidity": { + "version": "0.8.26", + "remappings": [ + "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/", + "@prb/math/=node_modules/@prb/math/", + "@sablier/v2-core/=node_modules/@sablier/v2-core/", + "forge-std/=node_modules/forge-std/", + "solady/=node_modules/solady/" + ], + "settings": { + "optimizer": { + "enabled": true, + "runs": 10000 + }, + "evmVersion": "shanghai", + "metadata": { + "bytecodeHash": "none" + } + } + }, + "solidityTest": { + "blockTimestamp": BigInt(1714518000), + "fsPermissions": { + "read": [ + "./out-optimized", + "package.json" + ], + "readWrite": [ + "./benchmark/results", + "./cache" + ] + }, + "blockGasLimit": BigInt(9223372036854775807), + "sender": "0x1804c8AB1F12E6bbf3894d4083f33e07309d1f38", + "fuzz": { + "runs": 20, + "maxTestRejects": 1000000 + }, + "rpcEndpoints": { + "arbitrum": "${ARBITRUM_RPC_URL}", + "arbitrum_sepolia": "https://arbitrum-sepolia.blockpi.network/v1/rpc/public", + "avalanche": "${AVALANCHE_RPC_URL}", + "base": "https://mainnet.base.org", + "base_sepolia": "https://sepolia.base.org", + "bnb": "https://bsc-dataseed.binance.org", + "gnosis": "https://rpc.gnosischain.com", + "localhost": "http://localhost:8545", + "mainnet": "${MAINNET_RPC_URL}", + "optimism": "${OPTIMISM_RPC_URL}", + "optimism_sepolia": "https://sepolia.optimism.io", + "polygon": "${POLYGON_RPC_URL}", + "scroll": "https://rpc.scroll.io/", + "sepolia": "${SEPOLIA_RPC_URL}" + } + } + }; + ignore: | + # unknown cheatcode with selector 0x6229498b (deriveKey(string,uint32)) + test/utils/BaseScript.t.sol + + # Could not instantiate forked environment. Received invalid url. (this is caused by using an invalid url for one of the rpc endpoints) + test/fork/assets/USDC.t.sol + test/fork/assets/USDT.t.sol + ref: c3ea8d7f7aab4cb33c6b4517ba38d32ca35b1257 + transmissions11/solmate: + forge-version: v0.3.0 + hardhat-config: | + export default { + "paths": { + "sources": "src", + "tests": { + "solidity": "src/test" + } + }, + "solidity": { + "version": "0.8.15", + "remappings": [ + "ds-test/=lib/ds-test/src/" + ], + "settings": { + "optimizer": { + "runs": 1000000 + }, + "metadata": { + "bytecodeHash": "none" + } + } + }, + "solidityTest": { + "testFail": true + } + }; + ref: c93f7716c9909175d45f6ef80a34a650e2d24e56 + +runners: + ubuntu-latest: {} + windows-latest: {} + macos-latest: {} + +commands: + forge build: + pattern: 'Compiling (\d+) files with Solc \d+\.\d+' + template: "Compiled ${0} file(s)" + forge test: + pattern: 'Ran \d+ test suites in \d+\.\d+m?s \(\d+\.\d+m?s CPU time\): (\d+) tests passed, (\d+) failed, (\d+) skipped \((\d+) total tests\)' + template: "Ran ${3} tests (${0} passed, ${1} failed, ${2} skipped)" + hardhat compile: + pattern: 'Compiled (\d+) Solidity files with solc \d+\.\d+' + template: "Compiled ${0} file(s)" + hardhat test solidity: + pattern: 'Run (?:Failed|Passed): (\d+) tests, (\d+) passed, (\d+) failed, (\d+) skipped \(duration: \d+ ms\)' + template: "Ran ${0} tests (${1} passed, ${2} failed, ${3} skipped)" diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 165b1817af..0000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,12 +0,0 @@ -# Please see the documentation for all configuration options: -# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates - -version: 2 -updates: - - package-ecosystem: "npm" - directory: "/" - schedule: - interval: "daily" - allow: - - dependency-name: "@solidity-parser/parser" - versioning-strategy: increase diff --git a/.github/workflows/LATEST_DEPENDENCY_VERSIONS.yml b/.github/workflows/LATEST_DEPENDENCY_VERSIONS.yml index 8247aaffcf..fcdf19ce3a 100644 --- a/.github/workflows/LATEST_DEPENDENCY_VERSIONS.yml +++ b/.github/workflows/LATEST_DEPENDENCY_VERSIONS.yml @@ -6,31 +6,29 @@ on: workflow_dispatch: jobs: - test-without-yarn-lock: - name: Test without yarn.lock + test-without-pnpm-lock-yaml: + name: Test without pnpm-lock.yaml strategy: matrix: system: ["ubuntu-latest", "windows-latest"] runs-on: ${{ matrix.system }} steps: - - uses: actions/setup-node@v2 - with: - node-version: 14 - - uses: actions/checkout@v2 - - name: Delete yarn.lock - run: "rm yarn.lock" + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup-env + - name: Delete pnpm-lock.yaml + run: "rm pnpm-lock.yaml" - name: Install - run: yarn + run: pnpm install --no-frozen-lockfile - name: List dependencies - run: yarn list + run: pnpm list -r --depth 2 - name: Run tests env: DO_NOT_SET_THIS_ENV_VAR____IS_HARDHAT_CI: true FORCE_COLOR: 3 - run: yarn test || (echo "===== Retry =====" && yarn test) + run: pnpm test || (echo "===== Retry =====" && pnpm test) - name: Notify failures if: failure() - uses: slackapi/slack-github-action@v1.18.0 + uses: slackapi/slack-github-action@70cd7be8e40a46e8b0eced40b0de447bdb42f68e # v1.26.0 with: payload: | { diff --git a/.github/workflows/add-issue-to-project.yml b/.github/workflows/add-issue-to-project.yml index 5ab3e0b2db..566c37f177 100644 --- a/.github/workflows/add-issue-to-project.yml +++ b/.github/workflows/add-issue-to-project.yml @@ -10,7 +10,7 @@ jobs: add-to-project: runs-on: ubuntu-latest steps: - - uses: actions/add-to-project@v0.4.0 + - uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2 with: project-url: https://github.com/orgs/NomicFoundation/projects/4 github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} diff --git a/.github/workflows/add-label-to-new-issue.yml b/.github/workflows/add-label-to-new-issue.yml index c2c3426f02..2bd47099b5 100644 --- a/.github/workflows/add-label-to-new-issue.yml +++ b/.github/workflows/add-label-to-new-issue.yml @@ -13,7 +13,7 @@ jobs: issues: write pull-requests: write steps: - - uses: actions/github-script@v6 + - uses: actions/github-script@v7 with: script: | const issue = await github.rest.issues.get({ @@ -27,11 +27,15 @@ jobs: ); if (statusLabel === undefined) { + console.log("Author association:", issue.data.author_association); + const isCollaborator = ["OWNER", "MEMBER", "COLLABORATOR"].includes(issue.data.author_association) + const label = isCollaborator ? "status:ready" : "status:triaging" + await github.rest.issues.addLabels({ owner: context.issue.owner, repo: context.issue.repo, issue_number: context.issue.number, - labels: ["status:triaging"] + labels: [label] }); } else { console.log(`Issue already has a status: ${statusLabel.name}`); diff --git a/.github/workflows/autoassign-issues.yml b/.github/workflows/autoassign-issues.yml new file mode 100644 index 0000000000..f01bd00d64 --- /dev/null +++ b/.github/workflows/autoassign-issues.yml @@ -0,0 +1,61 @@ +name: Issue autoassignment + +on: + issues: + types: [opened] + +jobs: + assign-new-issue: + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - uses: actions/github-script@v7 + with: + script: | + // each user has a chance of (p - (previousP ?? 0)) to be assigned + const potentialAssignees = [ + ["kanej", 1/4], + ["schaable", 2/4], + ["galargh", 3/4], + ["ChristopherDedominici", 1.0], + ]; + + let assignee; + const r = Math.random(); + console.log("r:", r); + for (const [username, p] of potentialAssignees) { + if (r < p) { + assignee = username; + break; + } + } + + if (assignee === undefined) { + throw new Error("An assignee should've been set"); + } + + console.log("assignee:", assignee); + + console.log("Fetch issue", context.issue.number); + const issue = await github.rest.issues.get({ + owner: context.issue.owner, + repo: context.issue.repo, + issue_number: context.issue.number, + }); + + console.log("Author association:", issue.data.author_association); + const isCollaborator = ["OWNER", "MEMBER", "COLLABORATOR"].includes( + issue.data.author_association + ); + console.log("Is collaborator?", isCollaborator); + + // we only assign triage issues from external users + if (!isCollaborator) { + await github.rest.issues.addAssignees({ + owner: context.issue.owner, + repo: context.issue.repo, + issue_number: context.issue.number, + assignees: [assignee], + }); + } diff --git a/.github/workflows/autoassign-prs.yml b/.github/workflows/autoassign-prs.yml new file mode 100644 index 0000000000..f98c9f4f09 --- /dev/null +++ b/.github/workflows/autoassign-prs.yml @@ -0,0 +1,36 @@ +name: PR autoassignment + +on: + pull_request_target: + types: [opened] + +jobs: + assign-new-issue: + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: actions/github-script@v7 + with: + script: | + const externalPrTriager = "kanej"; + + // Within the Github API PRs are issue objects + const pr = await github.rest.issues.get({ + owner: context.issue.owner, + repo: context.issue.repo, + issue_number: context.issue.number + }); + + const isCollaborator = ["OWNER", "MEMBER", "COLLABORATOR"].includes(pr.data.author_association) + + if (isCollaborator) { + return + } + + await github.rest.issues.addAssignees({ + owner: context.issue.owner, + repo: context.issue.repo, + issue_number: context.issue.number, + assignees: [externalPrTriager], + }); diff --git a/.github/workflows/cache.yml b/.github/workflows/cache.yml new file mode 100644 index 0000000000..3e70415997 --- /dev/null +++ b/.github/workflows/cache.yml @@ -0,0 +1,48 @@ +name: Cache + +on: + push: + branches: + - main + - pre-release-testing-branch + - changeset-release/main + - v-next + paths: + - ".github/workflows/cache.yml" + - "**/pnpm-lock.yaml" + pull_request: + paths: + - ".github/workflows/cache.yml" + - "**/pnpm-lock.yaml" + workflow_dispatch: + +concurrency: + group: ${{github.workflow}}-${{github.ref}} + cancel-in-progress: true + +defaults: + run: + shell: bash + +jobs: + cache: + name: Cache + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + runner: ["ubuntu-latest", "macos-latest", "windows-latest"] + steps: + - uses: actions/checkout@v4 + - id: env + uses: ./.github/actions/setup-env + with: + cache-save: true + - name: Install + if: steps.env.outputs.cache-hit != 'true' + run: | + for lockfile in $(find "$(pwd)" -name pnpm-lock.yaml); do + pushd "$(dirname "$lockfile")" + pnpm install --frozen-lockfile --prefer-offline + popd + done diff --git a/.github/workflows/check-changeset-added.yml b/.github/workflows/check-changeset-added.yml index fd489d6891..143e1adb39 100644 --- a/.github/workflows/check-changeset-added.yml +++ b/.github/workflows/check-changeset-added.yml @@ -18,8 +18,10 @@ jobs: check-if-changeset: name: Check that PR has a changeset runs-on: ubuntu-latest + # don't run this check in the changesets PR + if: github.head_ref != 'changeset-release/main' steps: - - uses: actions/github-script@v6 + - uses: actions/github-script@v7 with: script: | const pullNumber = context.issue.number; diff --git a/.github/workflows/check-docs-site.yml b/.github/workflows/check-docs-site.yml deleted file mode 100644 index c2145f9e7c..0000000000 --- a/.github/workflows/check-docs-site.yml +++ /dev/null @@ -1,31 +0,0 @@ -name: Check Docs Site - -on: - push: - branches: - - "fr/**" - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - lint: - name: Lint - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 16 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Install Docs - run: cd docs && yarn - - name: lint - run: cd docs && yarn lint - - name: Build - run: cd docs && yarn build - - name: Storybook - run: cd docs && yarn build-storybook diff --git a/.github/workflows/close-stale-issues.yml b/.github/workflows/close-stale-issues.yml new file mode 100644 index 0000000000..1040604e94 --- /dev/null +++ b/.github/workflows/close-stale-issues.yml @@ -0,0 +1,20 @@ +name: Close Stale Issues + +on: + schedule: + - cron: "0 0 * * *" # Runs daily at midnight UTC + workflow_dispatch: + +jobs: + stale: + runs-on: ubuntu-latest + steps: + - name: Close stale issues + uses: actions/stale@v9 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: "This issue has been automatically closed due to inactivity. If you still need help, please reopen the issue and provide the requested information." + days-before-stale: 7 + days-before-close: 7 + only-labels: "status:needs-more-info" + exempt-issue-labels: "status:do-not-close" diff --git a/.github/workflows/comment-on-linter-error.yml b/.github/workflows/comment-on-linter-error.yml deleted file mode 100644 index 5b281a58b9..0000000000 --- a/.github/workflows/comment-on-linter-error.yml +++ /dev/null @@ -1,51 +0,0 @@ -name: Comment on lint failure - -on: - pull_request_target: - types: - - opened - branches: - - $default-branch - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - comment_on_lint_failure: - name: Comment on lint failure - runs-on: ubuntu-latest - steps: - - name: Checkout repo - uses: actions/checkout@v2 - with: - ref: "refs/pull/${{ github.event.number }}/merge" - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: lint - run: yarn lint - - name: Check dependency versions - run: node scripts/check-dependencies.js - - name: Install website - working-directory: docs/ - run: yarn - - name: Lint website - working-directory: docs/ - run: yarn lint - - uses: actions/github-script@v6 - name: Comment on failure - if: ${{ failure() }} - with: - script: | - github.rest.issues.createComment({ - issue_number: context.issue.number, - owner: context.repo.owner, - repo: context.repo.repo, - body: "Thanks for submitting this PR!\n\nUnfortunately, it has some linter errors, so we can't merge it yet. Can you please fix them?\n\nRunning yarn `lint:fix` in the root of the repository may fix them automatically." - }) diff --git a/.github/workflows/e2e-tests.yml b/.github/workflows/e2e-tests.yml new file mode 100644 index 0000000000..d45099b81a --- /dev/null +++ b/.github/workflows/e2e-tests.yml @@ -0,0 +1,44 @@ +name: E2E tests + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + run-e2e: + strategy: + matrix: + # Disabled windows because it's too slow + # See: https://github.com/NomicFoundation/hardhat/issues/5247 + os: [ubuntu-latest, macos-latest] + name: Run E2E tests on ${{ matrix.os }} + runs-on: ${{ matrix.os }} + env: + # TODO: the e2e tests fail on windows when pnpm is used, + # for what we think is a bug in pnpm. We set this env + # variable to skip that combination until we find a solution. + # + # The failure is caused by `pnpm hardhat init` executing + # `hardhat init` twice on windows, which results in the + # second execution failing because `hardhat init` cannot + # be run on an existing project. + IS_WINDOWS: ${{ matrix.os == 'windows-latest' }} + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup-env + - name: Run fixture-projects script + run: | + cd e2e + chmod +x run-fixture-projects.sh + ./run-fixture-projects.sh + shell: bash + - name: Run test-project-initialization script + run: | + cd e2e + chmod +x test-project-initialization.sh + ./test-project-initialization.sh + shell: bash diff --git a/.github/workflows/hardhat-chai-matchers-ci.yml b/.github/workflows/hardhat-chai-matchers-ci.yml deleted file mode 100644 index 35e720e80a..0000000000 --- a/.github/workflows/hardhat-chai-matchers-ci.yml +++ /dev/null @@ -1,84 +0,0 @@ -name: hardhat-chai-matchers CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-chai-matchers/**" - - "packages/hardhat-common/**" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-chai-matchers/**" - - "packages/hardhat-common/**" - - "config/**" - -defaults: - run: - working-directory: packages/hardhat-chai-matchers - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_on_windows: - name: Test hardhat-chai-matchers on Windows with Node 14 - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - env: - FORCE_COLOR: 3 - run: yarn test:ci - - test_on_macos: - name: Test hardhat-chai-matchers on MacOS with Node 14 - runs-on: macos-latest - # disable until actions/virtual-environments#4896 is fixed - if: ${{ false }} - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - env: - FORCE_COLOR: 3 - run: yarn test:ci - - test_on_linux: - name: Test hardhat-chai-matchers on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - env: - FORCE_COLOR: 3 - run: yarn test:ci diff --git a/.github/workflows/hardhat-ci.yml b/.github/workflows/hardhat-ci.yml new file mode 100644 index 0000000000..c4cec0a8cf --- /dev/null +++ b/.github/workflows/hardhat-ci.yml @@ -0,0 +1,110 @@ +name: CI + +on: + push: + branches: main + paths: + - ".github/workflows/hardhat-ci.yml" + - "packages/**" + - "config/**" + - "pnpm-lock.yaml" + pull_request: + paths: + - ".github/workflows/hardhat-ci.yml" + - "packages/**" + - "config/**" + - "pnpm-lock.yaml" + workflow_dispatch: + +concurrency: + group: ${{github.workflow}}-${{github.ref}} + cancel-in-progress: true + +jobs: + list-packages: + name: List packages + runs-on: ubuntu-latest + outputs: + packages: ${{ steps.filter.outputs.changes }} + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 18 + - run: yq -p yaml -o json pnpm-lock.yaml | tee pnpm-lock.json + - id: generate + env: + PACKAGE_IGNORE: | + [ + ".", + "v-next/", + "packages/common", + "packages/eslint-plugin-hardhat-internal-rules", + "packages/eslint-plugin-slow-imports", + "packages/hardhat-core" + ] + COMMON_FILTERS: | + [ + ".github/workflows/hardhat-ci.yml", + "config/**", + "packages/common/**", + "pnpm-lock.yaml" + ] + run: | + echo "filters<> $GITHUB_OUTPUT + node scripts/generate-filters.js | + yq -Po yaml 'with_entries(.key |= sub("^packages/", ""))' | + tee -a $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + - id: filter + uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2 + with: + filters: ${{ steps.generate.outputs.filters }} + + ci: + needs: list-packages + + if: needs.list-packages.outputs.packages != '[]' + + strategy: + fail-fast: false + matrix: + package: ${{ fromJson(needs.list-packages.outputs.packages) }} + os: [ubuntu-latest, macos-latest, windows-latest] + node: [18, 20, 22] + exclude: + - package: hardhat-vyper + os: windows-latest + - package: hardhat-vyper + os: macos-latest + - os: windows-latest + node: 20 + - os: macos-latest + node: 20 + - os: windows-latest + node: 22 + - os: macos-latest + node: 22 + + name: "[${{ matrix.package }}] ci on ${{ matrix.os }} (Node ${{ matrix.node }})" + runs-on: ${{ matrix.os }} + defaults: + run: + working-directory: packages/${{ matrix.package }} + + steps: + - uses: actions/checkout@v4 + - name: Install pnpm + uses: pnpm/action-setup@v3 + with: + version: 9 + - uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node }} + cache: "pnpm" + - name: Install dependencies + run: pnpm install --frozen-lockfile --prefer-offline + - name: Build + run: pnpm build + - name: Run tests + run: pnpm run ${{ matrix.package == 'hardhat-chai-matchers' && 'test:ci' || 'test' }} diff --git a/.github/workflows/hardhat-core-ci.yml b/.github/workflows/hardhat-core-ci.yml index 75a5c3ef26..7a645344e3 100644 --- a/.github/workflows/hardhat-core-ci.yml +++ b/.github/workflows/hardhat-core-ci.yml @@ -1,19 +1,28 @@ name: hardhat-core CI +# Note: this workflow uses `macos-13` to use x86 + on: push: - branches: [$default-branch] + branches: + - main paths: + - ".github/workflows/hardhat-core-ci.yml" + - "config/**" - "packages/hardhat-core/**" - "packages/hardhat-common/**" - - "config/**" pull_request: - branches: - - "**" paths: + - ".github/workflows/hardhat-core-ci.yml" + - "config/**" - "packages/hardhat-core/**" - "packages/hardhat-common/**" - - "config/**" + workflow_dispatch: + inputs: + test-all-solc-versions: + description: Test all solc versions + required: false + default: "false" defaults: run: @@ -24,64 +33,101 @@ concurrency: cancel-in-progress: true jobs: - test_on_windows: - name: Test hardhat-core on Windows with Node 14 - runs-on: windows-latest + test-core: + name: Test core (${{ matrix.os }}, Node ${{ matrix.node }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + node: [18.15] + os: ["macos-13", "ubuntu-latest", "windows-latest"] steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 + - uses: actions/checkout@v4 + + - uses: ./.github/actions/setup-env with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile + node-version: ${{ matrix.node }} + + - name: Install package + run: pnpm install --frozen-lockfile --prefer-offline + + - name: Cache stack trace artifacts + uses: actions/cache@v4 + with: + path: | + packages/hardhat-core/test/internal/hardhat-network/stack-traces/test-files/artifacts + key: hardhat-network-stack-traces-tests-${{ hashFiles('packages/hardhat-core/test/internal/hardhat-network/stack-traces/test-files/**/*.sol') }}-${{ hashFiles('packages/hardhat-core/test/internal/hardhat-network/stack-traces/test-files/**/test.json') }}-${{ hashFiles('packages/hardhat-core/test/internal/hardhat-network/stack-traces/**/*.ts') }}-v4 + - name: Build - run: yarn build + run: pnpm build + - name: Run tests env: + INFURA_URL: ${{ secrets.INFURA_URL }} + ALCHEMY_URL: ${{ secrets.ALCHEMY_URL }} DO_NOT_SET_THIS_ENV_VAR____IS_HARDHAT_CI: true FORCE_COLOR: 3 - run: yarn test:except-tracing + NODE_OPTIONS: --max-old-space-size=4096 + HARDHAT_TESTS_ALL_SOLC_VERSIONS: ${{ github.event.inputs.test-all-solc-versions}} + run: pnpm test:except-provider - test_on_macos: - name: Test hardhat-core on MacOS with Node 14 - runs-on: macos-latest - # disable until actions/virtual-environments#4896 is fixed - if: ${{ false }} + test-provider: + name: Test provider (${{ matrix.os }}, Node ${{ matrix.node }}) + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + node: [18.15] + os: ["macos-13", "ubuntu-latest", "windows-latest"] steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 + - uses: actions/checkout@v4 + + - uses: ./.github/actions/setup-env with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile + node-version: ${{ matrix.node }} + + - name: Install package + run: pnpm install --frozen-lockfile --prefer-offline + + - name: Cache EDR RPC cache + uses: actions/cache@v4 + with: + path: | + packages/hardhat-core/test/internal/hardhat-network/edr-cache + key: hardhat-network-edr-cache-v2 + - name: Build - run: yarn build + run: pnpm build + - name: Run tests env: + INFURA_URL: ${{ secrets.INFURA_URL }} + ALCHEMY_URL: ${{ secrets.ALCHEMY_URL }} DO_NOT_SET_THIS_ENV_VAR____IS_HARDHAT_CI: true FORCE_COLOR: 3 - run: yarn test:except-tracing + run: pnpm test:provider - test_on_linux: - name: Test hardhat-core on Ubuntu with Node ${{ matrix.node }} + test_types_node: + name: Test different versions of @types/node runs-on: ubuntu-latest strategy: matrix: - node: [14, 16, 18] + # TODO: Currently there is no @types/node for Node 22, + # include it when it is available. + node: [18, 20] steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup-env with: node-version: ${{ matrix.node }} - cache: yarn - name: Install - run: yarn --frozen-lockfile + run: pnpm install --frozen-lockfile --prefer-offline + - name: Install @types/node + run: pnpm add --save-dev @types/node@${{ matrix.node }} - name: Build - run: yarn build + run: pnpm build - name: Run tests env: DO_NOT_SET_THIS_ENV_VAR____IS_HARDHAT_CI: true FORCE_COLOR: 3 - run: yarn test:except-tracing + run: pnpm test:except-tracing diff --git a/.github/workflows/hardhat-ethers-ci.yml b/.github/workflows/hardhat-ethers-ci.yml deleted file mode 100644 index 457743ec24..0000000000 --- a/.github/workflows/hardhat-ethers-ci.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: hardhat-ethers CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-ethers/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-ethers/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - -defaults: - run: - working-directory: packages/hardhat-ethers - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_on_windows: - name: Test hardhat-ethers on Windows with Node 14 - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_macos: - name: Test hardhat-ethers on MacOS with Node 14 - runs-on: macos-latest - # disable until actions/virtual-environments#4896 is fixed - if: ${{ false }} - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_linux: - name: Test hardhat-ethers on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test diff --git a/.github/workflows/hardhat-foundry-ci.yml b/.github/workflows/hardhat-foundry-ci.yml deleted file mode 100644 index f52e14fc2b..0000000000 --- a/.github/workflows/hardhat-foundry-ci.yml +++ /dev/null @@ -1,84 +0,0 @@ -name: hardhat-foundry CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-foundry/**" - - "packages/hardhat-common/**" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-foundry/**" - - "packages/hardhat-common/**" - - "config/**" - -defaults: - run: - working-directory: packages/hardhat-foundry - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_on_windows: - name: Test hardhat-foundry on Windows with Node 14 - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - env: - FORCE_COLOR: 3 - run: yarn test - - test_on_macos: - name: Test hardhat-foundry on MacOS with Node 14 - runs-on: macos-latest - # disable until actions/virtual-environments#4896 is fixed - if: ${{ false }} - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - env: - FORCE_COLOR: 3 - run: yarn test - - test_on_linux: - name: Test hardhat-foundry on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - env: - FORCE_COLOR: 3 - run: yarn test diff --git a/.github/workflows/hardhat-network-forking-ci.yml b/.github/workflows/hardhat-network-forking-ci.yml deleted file mode 100644 index 6b6b96064b..0000000000 --- a/.github/workflows/hardhat-network-forking-ci.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: Hardhat Network Forking Functionality CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - -defaults: - run: - working-directory: packages/hardhat-core - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - # We should run this tests with multiple configurations - # but somehow the requests to Alchemy take much longer when doing that. - # As a temporary workaround, we run them with a single config. - # - # Once we properly refactor Hardhat Network's tests we should - # add more configurations (different OS and node versions). - # - # We should also understand what's going on before blindly refactoring them. - test_fork: - name: Test Hardhat Network's forking functionality - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Cache network requests - uses: actions/cache@v2 - with: - path: | - packages/hardhat-core/test/internal/hardhat-network/provider/.hardhat_node_test_cache - key: hardhat-network-forking-tests-${{ hashFiles('yarn.lock') }}-${{ hashFiles('packages/hardhat-core/test/internal/hardhat-network/provider/node.ts') }} - - name: Run tests - env: - INFURA_URL: ${{ secrets.INFURA_URL }} - ALCHEMY_URL: ${{ secrets.ALCHEMY_URL }} - DO_NOT_SET_THIS_ENV_VAR____IS_HARDHAT_CI: true - FORCE_COLOR: 3 - run: | - yarn build - yarn test:forking diff --git a/.github/workflows/hardhat-network-helpers-ci.yml b/.github/workflows/hardhat-network-helpers-ci.yml deleted file mode 100644 index c2bc454b93..0000000000 --- a/.github/workflows/hardhat-network-helpers-ci.yml +++ /dev/null @@ -1,84 +0,0 @@ -name: hardhat-network-helpers CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-network-helpers/**" - - "packages/hardhat-common/**" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-network-helpers/**" - - "packages/hardhat-common/**" - - "config/**" - -defaults: - run: - working-directory: packages/hardhat-network-helpers - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_on_windows: - name: Test hardhat-network-helpers on Windows with Node 14 - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - env: - FORCE_COLOR: 3 - run: yarn test - - test_on_macos: - name: Test hardhat-network-helpers on MacOS with Node 14 - runs-on: macos-latest - # disable until actions/virtual-environments#4896 is fixed - if: ${{ false }} - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - env: - FORCE_COLOR: 3 - run: yarn test - - test_on_linux: - name: Test hardhat-network-helpers on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - env: - FORCE_COLOR: 3 - run: yarn test diff --git a/.github/workflows/hardhat-network-tracing-all-solc-versions.yml b/.github/workflows/hardhat-network-tracing-all-solc-versions.yml deleted file mode 100644 index 0704096987..0000000000 --- a/.github/workflows/hardhat-network-tracing-all-solc-versions.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Hardhat Network Tracing Capabilities, scheduled runs for all solc versions - -on: - schedule: - - cron: "0 0 * * *" # every day at midnight - workflow_dispatch: - -defaults: - run: - working-directory: packages/hardhat-core - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_tracing: - name: Test tracing capabilities on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Cache artifacts - uses: actions/cache@v2 - with: - path: | - packages/hardhat-core/test/internal/hardhat-network/stack-traces/test-files/artifacts - key: hardhat-network-stack-traces-tests-${{ hashFiles('yarn.lock') }}-${{ hashFiles('packages/hardhat-core/test/internal/hardhat-network/stack-traces/test-files/**/*.sol') }}-${{ hashFiles('packages/hardhat-core/test/internal/hardhat-network/stack-traces/test-files/**/test.json') }}-${{ hashFiles('packages/hardhat-core/test/internal/hardhat-network/stack-traces/**/*.ts') }} - - name: Run tests - env: - DO_NOT_SET_THIS_ENV_VAR____IS_HARDHAT_CI: true - FORCE_COLOR: 3 - NODE_OPTIONS: "--max-old-space-size=4096" - HARDHAT_TESTS_ALL_SOLC_VERSIONS: true - run: yarn test:tracing diff --git a/.github/workflows/hardhat-network-tracing-ci.yml b/.github/workflows/hardhat-network-tracing-ci.yml deleted file mode 100644 index c5c8f07963..0000000000 --- a/.github/workflows/hardhat-network-tracing-ci.yml +++ /dev/null @@ -1,55 +0,0 @@ -name: Hardhat Network Tracing Capabilities CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - workflow_dispatch: - -defaults: - run: - working-directory: packages/hardhat-core - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_tracing: - name: Test tracing capabilities on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Cache artifacts - uses: actions/cache@v2 - with: - path: | - packages/hardhat-core/test/internal/hardhat-network/stack-traces/test-files/artifacts - key: hardhat-network-stack-traces-tests-${{ hashFiles('packages/hardhat-core/test/internal/hardhat-network/stack-traces/test-files/**/*.sol') }}-${{ hashFiles('packages/hardhat-core/test/internal/hardhat-network/stack-traces/test-files/**/test.json') }}-${{ hashFiles('packages/hardhat-core/test/internal/hardhat-network/stack-traces/**/*.ts') }} - - name: Run tests - env: - DO_NOT_SET_THIS_ENV_VAR____IS_HARDHAT_CI: true - FORCE_COLOR: 3 - NODE_OPTIONS: "--max-old-space-size=4096" - run: yarn test:tracing diff --git a/.github/workflows/hardhat-shorthand-ci.yml b/.github/workflows/hardhat-shorthand-ci.yml deleted file mode 100644 index f07472ab0a..0000000000 --- a/.github/workflows/hardhat-shorthand-ci.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: hardhat-shorthand CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-shorthand/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-shorthand/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - -defaults: - run: - working-directory: packages/hardhat-shorthand - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_on_windows: - name: Test hardhat-shorthand on Windows with Node 14 - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_macos: - name: Test hardhat-shorthand on MacOS with Node 14 - runs-on: macos-latest - # disable until actions/virtual-environments#4896 is fixed - if: ${{ false }} - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_linux: - name: Test hardhat-shorthand on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test diff --git a/.github/workflows/hardhat-solhint-ci.yml b/.github/workflows/hardhat-solhint-ci.yml deleted file mode 100644 index b548aae14e..0000000000 --- a/.github/workflows/hardhat-solhint-ci.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: hardhat-solhint CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-solhint/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-solhint/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - -defaults: - run: - working-directory: packages/hardhat-solhint - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_on_windows: - name: Test hardhat-solhint on Windows with Node 14 - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_macos: - name: Test hardhat-solhint on MacOS with Node 14 - runs-on: macos-latest - # disable until actions/virtual-environments#4896 is fixed - if: ${{ false }} - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_linux: - name: Test hardhat-solhint on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test diff --git a/.github/workflows/hardhat-solpp-ci.yml b/.github/workflows/hardhat-solpp-ci.yml deleted file mode 100644 index ac5f545700..0000000000 --- a/.github/workflows/hardhat-solpp-ci.yml +++ /dev/null @@ -1,64 +0,0 @@ -name: hardhat-solpp CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-solpp/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-solpp/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - -defaults: - run: - working-directory: packages/hardhat-solpp - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_on_macos: - name: Test hardhat-solpp on MacOS with Node 14 - runs-on: macos-latest - # disable until actions/virtual-environments#4896 is fixed - if: ${{ false }} - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_linux: - name: Test hardhat-solpp on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test diff --git a/.github/workflows/hardhat-toolbox-ci.yml b/.github/workflows/hardhat-toolbox-ci.yml deleted file mode 100644 index d10cddefc0..0000000000 --- a/.github/workflows/hardhat-toolbox-ci.yml +++ /dev/null @@ -1,88 +0,0 @@ -name: hardhat-toolbox CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-toolbox/**" - - "packages/hardhat-core/**" - - "packages/hardhat-chai-matchers/**" - - "packages/hardhat-network-helpers/**" - - "packages/hardhat-ethers/**" - - "packages/hardhat-etherscan/**" - - "packages/hardhat-common/**" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-toolbox/**" - - "packages/hardhat-core/**" - - "packages/hardhat-chai-matchers/**" - - "packages/hardhat-network-helpers/**" - - "packages/hardhat-ethers/**" - - "packages/hardhat-etherscan/**" - - "packages/hardhat-common/**" - - "config/**" - -defaults: - run: - working-directory: packages/hardhat-toolbox - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_on_windows: - name: Test hardhat-toolbox on Windows with Node 14 - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_macos: - name: Test hardhat-toolbox on MacOS with Node 14 - runs-on: macos-latest - # disable until actions/virtual-environments#4896 is fixed - if: ${{ false }} - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_linux: - name: Test hardhat-toolbox on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test diff --git a/.github/workflows/hardhat-truffle4-ci.yml b/.github/workflows/hardhat-truffle4-ci.yml deleted file mode 100644 index 46b7d5d003..0000000000 --- a/.github/workflows/hardhat-truffle4-ci.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: hardhat-truffle4 CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-truffle4/**" - - "packages/hardhat-web3-legacy/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-truffle4/**" - - "packages/hardhat-web3-legacy/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - -defaults: - run: - working-directory: packages/hardhat-truffle4 - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_on_windows: - name: Test hardhat-truffle4 on Windows with Node 14 - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_macos: - name: Test hardhat-truffle4 on MacOS with Node 14 - runs-on: macos-latest - # disable until actions/virtual-environments#4896 is fixed - if: ${{ false }} - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_linux: - name: Test hardhat-truffle4 on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test diff --git a/.github/workflows/hardhat-truffle5-ci.yml b/.github/workflows/hardhat-truffle5-ci.yml deleted file mode 100644 index 70e873cc04..0000000000 --- a/.github/workflows/hardhat-truffle5-ci.yml +++ /dev/null @@ -1,82 +0,0 @@ -name: hardhat-truffle5 CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-truffle5/**" - - "packages/hardhat-web3/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-truffle5/**" - - "packages/hardhat-web3/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - -defaults: - run: - working-directory: packages/hardhat-truffle5 - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_on_windows: - name: Test hardhat-truffle5 on Windows with Node 14 - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_macos: - name: Test hardhat-truffle5 on MacOS with Node 14 - runs-on: macos-latest - # disable until actions/virtual-environments#4896 is fixed - if: ${{ false }} - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_linux: - name: Test hardhat-truffle5 on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test diff --git a/.github/workflows/hardhat-verify-ci.yml b/.github/workflows/hardhat-verify-ci.yml deleted file mode 100644 index a16b39cdf1..0000000000 --- a/.github/workflows/hardhat-verify-ci.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: hardhat-verify CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-verify/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-verify/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - -defaults: - run: - working-directory: packages/hardhat-verify - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_on_windows: - name: Test hardhat-verify on Windows with Node 14 - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_macos: - name: Test hardhat-verify on MacOS with Node 14 - runs-on: macos-latest - # disable until actions/virtual-environments#4896 is fixed - if: ${{ false }} - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_linux: - name: Test hardhat-verify on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test diff --git a/.github/workflows/hardhat-vyper-ci.yml b/.github/workflows/hardhat-vyper-ci.yml deleted file mode 100644 index 528e027713..0000000000 --- a/.github/workflows/hardhat-vyper-ci.yml +++ /dev/null @@ -1,46 +0,0 @@ -name: hardhat-vyper CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-vyper/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-vyper/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - -defaults: - run: - working-directory: packages/hardhat-vyper - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_on_linux: - name: Test hardhat-vyper on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test diff --git a/.github/workflows/hardhat-web3-ci.yml b/.github/workflows/hardhat-web3-ci.yml deleted file mode 100644 index 33a8ead269..0000000000 --- a/.github/workflows/hardhat-web3-ci.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: hardhat-web3 CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-web3/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-web3/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - -defaults: - run: - working-directory: packages/hardhat-web3 - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_on_windows: - name: Test hardhat-web3 on Windows with Node 14 - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_macos: - name: Test hardhat-web3 on MacOS with Node 14 - runs-on: macos-latest - # disable until actions/virtual-environments#4896 is fixed - if: ${{ false }} - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_linux: - name: Test hardhat-web3 on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test diff --git a/.github/workflows/hardhat-web3-legacy-ci.yml b/.github/workflows/hardhat-web3-legacy-ci.yml deleted file mode 100644 index 221110aa34..0000000000 --- a/.github/workflows/hardhat-web3-legacy-ci.yml +++ /dev/null @@ -1,80 +0,0 @@ -name: hardhat-web3-legacy CI - -on: - push: - branches: [$default-branch] - paths: - - "packages/hardhat-web3-legacy/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**/*" - - "config/**" - pull_request: - branches: - - "**" - paths: - - "packages/hardhat-web3-legacy/**" - - "packages/hardhat-core/**" - - "packages/hardhat-common/**" - - "config/**" - -defaults: - run: - working-directory: packages/hardhat-web3-legacy - -concurrency: - group: ${{github.workflow}}-${{github.ref}} - cancel-in-progress: true - -jobs: - test_on_windows: - name: Test hardhat-web3-legacy on Windows with Node 14 - runs-on: windows-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_macos: - name: Test hardhat-web3-legacy on MacOS with Node 14 - runs-on: macos-latest - # disable until actions/virtual-environments#4896 is fixed - if: ${{ false }} - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test - - test_on_linux: - name: Test hardhat-web3-legacy on Ubuntu with Node ${{ matrix.node }} - runs-on: ubuntu-latest - strategy: - matrix: - node: [14, 16, 18] - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: ${{ matrix.node }} - cache: yarn - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run tests - run: yarn test diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 2c37c9bb8a..aa985c2a4c 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -2,10 +2,16 @@ name: Lint on: push: - branches: [$default-branch] - pull_request: branches: - - "**" + - main + paths: + - ".github/workflows/lint.yml" + - "packages/**" + pull_request: + paths: + - ".github/workflows/lint.yml" + - "packages/**" + workflow_dispatch: concurrency: group: ${{github.workflow}}-${{github.ref}} @@ -15,26 +21,48 @@ jobs: lint: name: Lint runs-on: ubuntu-latest + permissions: + contents: read steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 + # NOTE: When running on a pull_request_target, we're checking out the repo + # twice. The first checkout is for the base branch of the PR. The second, + # for the merge commit. We do this to be able to use the `setup-env` + # action that's on the base branch. + - uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: actions/checkout@v4 + if: github.event_name == 'pull_request_target' with: - node-version: 14 - cache: yarn - cache-dependency-path: | - yarn.lock - docs/yarn.lock + ref: "refs/pull/${{ github.event.number }}/merge" + persist-credentials: false + - if: github.event_name == 'pull_request_target' + name: Check out setup-env action from the base branch + run: git checkout --no-overlay $GITHUB_SHA -- .github/actions/setup-env + - uses: ./.github/actions/setup-env - name: Install - run: yarn --frozen-lockfile + run: pnpm install --frozen-lockfile --prefer-offline - name: Build - run: yarn build + run: pnpm build - name: lint - run: yarn lint + run: pnpm lint - name: Check dependency versions run: node scripts/check-dependencies.js - - name: Install website - working-directory: docs/ - run: yarn - - name: Lint website - working-directory: docs/ - run: yarn lint + comment: + needs: [lint] + if: failure() && github.event_name == 'pull_request_target' && needs.lint.result == 'failure' + name: Comment + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: actions/github-script@v7 + name: Comment on failure + with: + script: | + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: "Thanks for submitting this PR!\n\nUnfortunately, it has some linter errors, so we can't merge it yet. Can you please fix them?\n\nRunning pnpm lint:fix in the root of the repository may fix them automatically." + }) diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml index 113315dfc2..1b90eae439 100644 --- a/.github/workflows/lock.yml +++ b/.github/workflows/lock.yml @@ -16,7 +16,8 @@ jobs: action: runs-on: ubuntu-latest steps: - - uses: dessant/lock-threads@e460dfeb36e731f3aeb214be6b0c9a9d9a67eda6 + - uses: dessant/lock-threads@1bf7ec25051fe7c00bdd17e6a7cf3d7bfb7dc771 # v5.0.1 with: issue-inactive-days: "90" pr-inactive-days: "90" + process-only: "issues, prs" diff --git a/.github/workflows/pre-release.yml b/.github/workflows/pre-release.yml index eead734896..345d54c747 100644 --- a/.github/workflows/pre-release.yml +++ b/.github/workflows/pre-release.yml @@ -2,7 +2,9 @@ name: Pre-release tests on: push: - branches: [pre-release-testing-branch] + branches: + - pre-release-testing-branch + - changeset-release/main workflow_dispatch: concurrency: @@ -14,19 +16,16 @@ jobs: name: Pre-release checks runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup-env - name: Install - run: yarn --frozen-lockfile + run: pnpm install --frozen-lockfile --prefer-offline - name: Build - run: yarn build + run: pnpm build - name: lint - run: yarn lint + run: pnpm lint - name: Cache artifacts - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: | packages/hardhat-core/test/internal/hardhat-network/stack-traces/test-files/artifacts @@ -36,7 +35,7 @@ jobs: DO_NOT_SET_THIS_ENV_VAR____IS_HARDHAT_CI: true FORCE_COLOR: 3 NODE_OPTIONS: "--max-old-space-size=4096" - run: yarn test + run: pnpm test - name: Check dependency versions run: node scripts/check-dependencies.js test_fork: @@ -46,19 +45,16 @@ jobs: run: working-directory: packages/hardhat-core steps: - - uses: actions/checkout@v2 - - uses: actions/setup-node@v2 - with: - node-version: 14 - cache: yarn + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup-env - name: Install - run: yarn --frozen-lockfile + run: pnpm install --frozen-lockfile --prefer-offline - name: Cache network requests - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: | packages/hardhat-core/test/internal/hardhat-network/provider/.hardhat_node_test_cache - key: hardhat-network-forking-tests-${{ hashFiles('yarn.lock') }}-${{ hashFiles('packages/hardhat-core/test/internal/hardhat-network/provider/node.ts') }} + key: hardhat-network-forking-tests-${{ hashFiles('pnpm-lock.yaml') }}-${{ hashFiles('packages/hardhat-core/test/internal/hardhat-network/provider/node.ts') }} - name: Run tests env: INFURA_URL: ${{ secrets.INFURA_URL }} @@ -67,5 +63,5 @@ jobs: FORCE_COLOR: 3 NODE_OPTIONS: "--max-old-space-size=4096" run: | - yarn build - yarn test:forking + pnpm build + pnpm test:except-tracing diff --git a/.github/workflows/regression-tests.yml b/.github/workflows/regression-tests.yml new file mode 100644 index 0000000000..030b4111c0 --- /dev/null +++ b/.github/workflows/regression-tests.yml @@ -0,0 +1,473 @@ +name: Regression Tests + +on: + # TODO: Add a workflow_call trigger to allow running this workflow from EDR + workflow_dispatch: + inputs: + hardhat-ref: + required: true + type: string + default: "v-next" + edr-ref: + required: false + type: string + default: "" + repositories: + required: false + type: string + default: '["Elytro-eth/soul-wallet-contract", "foundry-rs/forge-std", "kalidao/keep", "mds1/multicall", "pancakeswap/infinity-core", "PaulRBerg/prb-math", "PaulRBerg/prb-proxy", "PaulRBerg/prb-test", "pcaversaccio/createx", "ProjectOpenSea/seaport", "sablier-labs/lockup", "sablier-labs/v2-periphery", "transmissions11/solmate", "Uniswap/UniswapX", "Vectorized/solady"]' + runners: + required: false + type: string + default: '["ubuntu-latest"]' + commands: + required: false + type: string + default: '["hardhat compile", "hardhat test solidity"]' + +defaults: + run: + shell: bash + +jobs: + build-edr: + name: Build EDR + if: inputs.edr-ref + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + runner: ${{ fromJSON(inputs.runners) }} + defaults: + run: + shell: bash + working-directory: crates/edr_napi + steps: + - uses: actions/checkout@v4 + with: + repository: NomicFoundation/edr + ref: ${{ inputs.edr-ref }} + - id: target + env: + RUNNER: ${{ matrix.runner }} + run: | + if [[ "$RUNNER" == "ubuntu-latest" ]]; then + echo "target=x86_64-unknown-linux-gnu" >> $GITHUB_OUTPUT + elif [[ "$RUNNER" == "macos-latest" ]]; then + echo "target=aarch64-apple-darwin" >> $GITHUB_OUTPUT + elif [[ "$RUNNER" == "windows-latest" ]]; then + echo "target=x86_64-pc-windows-msvc" >> $GITHUB_OUTPUT + else + exit 1 + fi + - uses: ./.github/actions/setup-node + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + - name: Add Rust cross-compilation target + run: rustup target add ${{ steps.target.outputs.target }} + - name: Install dependencies + run: pnpm install --frozen-lockfile --prefer-offline + - name: Build + run: pnpm build --target ${{ steps.target.outputs.target }} + - name: Remove symbols + if: runner.os != 'MacOS' + run: strip *.node + - name: Remove symbols (macOS) + if: runner.os == 'MacOS' + run: strip -x *.node + - name: Upload artifact + uses: actions/upload-artifact@v4 + with: + name: edr-${{ matrix.runner }} + path: crates/edr_napi/edr.*.node + if-no-files-found: error + + publish-edr: + name: Publish EDR + needs: [build-edr] + runs-on: ubuntu-latest + defaults: + run: + shell: bash + working-directory: crates/edr_napi + steps: + - uses: actions/checkout@v4 + with: + repository: NomicFoundation/edr + ref: ${{ inputs.edr-ref }} + - uses: ./.github/actions/setup-node + - name: Install dependencies + run: pnpm install --frozen-lockfile --prefer-offline + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: crates/edr_napi/artifacts + - name: Install sponge + run: | + sudo apt-get update + sudo apt-get install -y moreutils + - name: Move artifacts + run: pnpm artifacts + - name: Install artifacts + run: | + for artifact in npm/*/*.node; do + pnpm install --save "./$(dirname $artifact)" + done + - name: Modify package.json + env: + JSON: | + { + "bundleDependencies": true + } + run: jq --argjson json "$JSON" '. + $json' package.json > package.json.tmp && mv package.json.tmp package.json + - name: Create the package + run: pnpm pack --config.node-linker=hoisted + - name: Upload the package + uses: actions/upload-artifact@v4 + with: + name: edr + path: crates/edr_napi/*.tgz + if-no-files-found: error + + build-and-publish-hardhat: + name: Build and publish Hardhat + needs: [publish-edr] + if: (!cancelled() && inputs.hardhat-ref != 'next' && !startsWith(inputs.hardhat-ref, '3') && inputs.edr-ref == '' || needs.publish-edr.result == 'success') + runs-on: ubuntu-latest + defaults: + run: + shell: bash + working-directory: v-next/hardhat + steps: + - uses: actions/checkout@v4 + with: + repository: NomicFoundation/hardhat + ref: ${{ inputs.hardhat-ref }} + - uses: ./.github/actions/setup-env + - name: Install dependencies + run: | + pnpm install --frozen-lockfile --prefer-offline + - name: Download EDR + if: inputs.edr-ref != '' + uses: actions/download-artifact@v4 + with: + name: edr + path: v-next/hardhat + - name: Install EDR + if: inputs.edr-ref != '' + run: pnpm install ./*.tgz + - name: Build + run: pnpm build + - name: Modify package.json + env: + JSON: | + { + "bundleDependencies": true + } + run: jq --argjson json "$JSON" '. + $json' package.json > package.json.tmp && mv package.json.tmp package.json + - name: Modify top-level package.json + env: + JSON: | + { + "pnpm": { + "supportedArchitectures": { + "os": ["win32", "darwin", "linux"], + "cpu": ["x64", "arm64"] + } + } + } + run: jq --argjson json "$JSON" '. + $json' package.json > package.json.tmp && mv package.json.tmp package.json + working-directory: ${{ github.workspace }} + - name: Deploy + run: | + pnpm deploy --config.node-linker=hoisted --filter=hardhat --prod bundle.tmp + rsync -a --copy-links bundle.tmp/ bundle + rm -rf **/bundle.tmp + working-directory: ${{ github.workspace }} + - name: Pack + run: npm pack + working-directory: bundle + - uses: actions/upload-artifact@v4 + with: + name: hardhat + path: bundle/hardhat-*.tgz + if-no-files-found: error + + test: + name: Run the test command + needs: [build-and-publish-hardhat] + if: (!cancelled() && (inputs.hardhat-ref == 'next' || startsWith(inputs.hardhat-ref, '3')) || needs.build-and-publish-hardhat.result == 'success') + runs-on: ${{ matrix.runner }} + strategy: + fail-fast: false + matrix: + repository: ${{ fromJSON(inputs.repositories) }} + runner: ${{ fromJSON(inputs.runners) }} + command: ${{ fromJSON(inputs.commands) }} + steps: + - uses: actions/checkout@v4 + with: + path: ${{ github.repository }} + - if: runner.os == 'Windows' + run: choco install yq + - id: workflow + run: | + echo "config<> $GITHUB_OUTPUT + yq -o json . .github/config/regression-tests.yml >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + working-directory: ${{ github.repository }} + - id: config + env: + REPOSITORY: ${{ matrix.repository }} + RUNNER: ${{ matrix.runner }} + COMMAND: ${{ matrix.command }} + CONFIG: ${{ toJSON(fromJSON(steps.workflow.outputs.config)) }} + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const config = JSON.parse(process.env.CONFIG); + const repositoryConfig = config.repositories[process.env.REPOSITORY]; + const runnerConfig = config.runners[process.env.RUNNER]; + const commandConfig = config.commands[process.env.COMMAND]; + if (!repositoryConfig) { + core.setFailed(`Unsupported repository: ${process.env.REPOSITORY}`); + } + if (!runnerConfig) { + core.setFailed(`Unsupported runner: ${process.env.RUNNER}`); + } + if (!commandConfig) { + core.setFailed(`Unsupported command: ${process.env.COMMAND}`); + } + core.setOutput('repository', JSON.stringify(repositoryConfig)); + core.setOutput('runner', JSON.stringify(runnerConfig)); + core.setOutput('command', JSON.stringify(commandConfig)); + console.log({ + repository: repositoryConfig, + runner: runnerConfig, + command: commandConfig, + }); + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: 22 + - name: Download Hardhat + if: (startsWith(matrix.command, 'hardhat') && inputs.hardhat-ref != 'next' && !startsWith(inputs.hardhat-ref, '3')) + uses: actions/download-artifact@v4 + with: + name: hardhat + - name: Fix Hardhat on Windows + if: (startsWith(matrix.command, 'hardhat') && inputs.hardhat-ref != 'next' && !startsWith(inputs.hardhat-ref, '3')) && matrix.runner == 'windows-latest' + run: | + npm init -y + npm install esbuild + rm package.json package-lock.json + tar -xzf hardhat-*.tgz + rm -rf package/node_modules/esbuild package/node_modules/@esbuild + mv node_modules/esbuild package/node_modules + mv node_modules/@esbuild package/node_modules + tar -czf hardhat-*.tgz package + rm -rf package + - name: Install Hardhat from source + if: (startsWith(matrix.command, 'hardhat') && inputs.hardhat-ref != 'next' && !startsWith(inputs.hardhat-ref, '3')) + run: | + npm install -g hardhat-*.tgz + rm hardhat-*.tgz + - name: Install Hardhat + if: (startsWith(matrix.command, 'hardhat') && (inputs.hardhat-ref == 'next' || startsWith(inputs.hardhat-ref, '3'))) + run: | + npm install -g hardhat@${{ inputs.hardhat-ref }} + hardhat --version + - name: Install Forge + if: startsWith(matrix.command, 'forge') + uses: foundry-rs/foundry-toolchain@de808b1eea699e761c404bda44ba8f21aba30b2c + with: + version: ${{ fromJSON(steps.config.outputs.repository).forge-version }} + cache: false + - name: Checkout the repository + uses: actions/checkout@v4 + with: + submodules: recursive + repository: ${{ matrix.repository }} + ref: ${{ fromJSON(steps.config.outputs.repository).ref }} + - name: Update the .gitignore + if: fromJSON(steps.config.outputs.repository).ignore != '' + env: + IGNORE: ${{ fromJSON(steps.config.outputs.repository).ignore }} + run: | + echo "$IGNORE" >> .gitignore + git rm --cached -r $(git ls-files -i -c --exclude-from=.gitignore) + git clean -fdX + - name: Configure Hardhat + if: startsWith(matrix.command, 'hardhat') + env: + CONFIG: ${{ fromJSON(steps.config.outputs.repository).hardhat-config }} + run: | + rm hardhat.config.* || true + echo "$CONFIG" > hardhat.config.js + - name: Initialize the package + if: startsWith(matrix.command, 'hardhat') + run: | + npm init -y + npm pkg set type="module" + - name: Install dependencies (npm) + if: hashFiles('package-lock.json') != '' + run: npm ci + - name: Install dependencies (pnpm) + if: hashFiles('pnpm-lock.yaml') != '' + run: | + npm install -g pnpm + pnpm install --frozen-lockfile --prefer-offline || pnpm install + - name: Install dependencies (yarn) + if: hashFiles('yarn.lock') != '' + run: | + npm install -g yarn + yarn install --immutable + - name: Install dependencies (bun) + if: hashFiles('bun.lockb') != '' + run: | + npm install -g bun + bun install --frozen-lockfile + - name: Run ${{ matrix.command }} + id: run + env: + DEBUG: ${{ runner.debug && '*' || '' }} + ENV_SOURCE: ${{ fromJSON(steps.config.outputs.repository).env }} + run: | + source <(echo "$ENV_SOURCE") + set +e + before=$(date +%s) + ${{ matrix.command }} 2>&1 | tee -a run.output + status=${PIPESTATUS[0]} + after=$(date +%s) + set -e + echo '{"status": '"$status"', "time": '"$((after - before))"'}' > run.result + - name: Run the command post-hook + uses: actions/github-script@v7 + env: + PATTERN: ${{ fromJSON(steps.config.outputs.command).pattern }} + TEMPLATE: ${{ fromJSON(steps.config.outputs.command).template }} + with: + script: | + const fs = require('fs'); + const path = require('path'); + const output = fs.readFileSync('run.output').toString(); + const matches = output.matchAll(new RegExp(process.env.PATTERN, 'g')); + const sums = []; + for (const groups of matches) { + for (let i = 1; i < groups.length; i++) { + while (sums.length < i) { + sums.push(0); + } + sums[i - 1] += parseInt(groups[i]); + } + } + let details = process.env.TEMPLATE; + for (let i = 0; i < sums.length; i++) { + details = details.replaceAll(`\${${i}}`, sums[i]); + } + fs.writeFileSync('run.details', details); + - id: upload + env: + REPOSITORY: ${{ matrix.repository }} + CONTEXT: | + { + "repository": "${{ matrix.repository }}", + "runner": "${{ matrix.runner }}", + "command": "${{ matrix.command }}" + } + run: | + echo "repository=${REPOSITORY//\//_}" | tee -a $GITHUB_OUTPUT + echo "$CONTEXT" > run.context + - name: Upload the result + uses: actions/upload-artifact@v4 + with: + name: repository-${{ steps.upload.outputs.repository }};command-${{ matrix.command }};runner-${{ matrix.runner }} + path: | + run.context + run.output + run.result + run.details + + summarize: + name: Summarize the test results + if: (!cancelled()) + needs: [test] + runs-on: ubuntu-latest + steps: + - name: Download the results + uses: actions/download-artifact@v4 + with: + pattern: "repository-*;command-*;runner-*" + - name: Summarize the results + id: summary + env: + HARDHAT_REF: ${{ inputs.hardhat-ref }} + EDR_REF: ${{ inputs.edr-ref }} + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const path = require('path'); + const artifacts = fs.readdirSync(process.env.GITHUB_WORKSPACE); + const results = []; + for (const artifact of artifacts) { + const context = JSON.parse(fs.readFileSync(path.join(artifact, 'run.context')).toString()); + const result = JSON.parse(fs.readFileSync(path.join(artifact, 'run.result')).toString()); + const details = fs.readFileSync(path.join(artifact, 'run.details')).toString(); + results.push({ + repository: context.repository, + command: context.command, + runner: context.runner, + result: result.status, + time: result.time, + details, + }); + } + console.log(results); + const header = ['Repository 📦', 'Command 👾', 'Runner 💨', 'Result 🧪', 'Wall-clock Time ⏰', 'Details 🔎'].map(data => ({data, header: true})); + const rows = results.map(({repository, command, runner, result, time, details}) => ([ + repository, + (() => { + if (command.startsWith('hardhat')) { + return `👷 ${command}`; + } else if (command.startsWith('forge')) { + return `⚙️ ${command}`; + } else { + return command; + } + })(), + (() => { + switch (runner) { + case 'ubuntu-latest': + return '🐧 Ubuntu'; + case 'macos-latest': + return '🍎 macOS'; + case 'windows-latest': + return '🪟 Windows'; + } + })(), + (() => { + switch (result) { + case 0: + return '✅ Passed'; + case 1: + return '❌ Failed'; + default: + return `⚠️ Unknown (${result})`; + } + })(), + `${time} s`, + details, + ])); + console.log(header); + console.log(rows); + await core.summary + .addHeading('Test Results') + .addTable([ + header, + ...rows, + ]) + .write() diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6d196e0990..afc3d2560e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,21 +9,20 @@ jobs: release: name: Release runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write steps: - name: Checkout Repo - uses: actions/checkout@v2 + uses: actions/checkout@v4 with: # This makes Actions fetch all Git history so that Changesets can generate changelogs with the correct commits fetch-depth: 0 - - name: Setup Node.js 14.x - uses: actions/setup-node@v2 - with: - node-version: 14.x - cache: "yarn" + - uses: ./.github/actions/setup-env - name: Install Dependencies - run: yarn + run: pnpm install --frozen-lockfile --prefer-offline - name: Create Release Pull Request uses: changesets/action@v1 diff --git a/.github/workflows/test-recent-mainnet-block.yml b/.github/workflows/test-recent-mainnet-block.yml deleted file mode 100644 index 2d22215aea..0000000000 --- a/.github/workflows/test-recent-mainnet-block.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Run a recent full block in the Hardhat Network - -on: - schedule: - - cron: "0 0 * * *" - workflow_dispatch: - -defaults: - run: - working-directory: packages/hardhat-core - -jobs: - test-recent-mainnet-block: - name: Test recent mainnet block - runs-on: ubuntu-latest - steps: - - uses: actions/setup-node@v2 - with: - node-version: 14 - - uses: actions/checkout@v2 - - name: Install - run: yarn --frozen-lockfile - - name: Build - run: yarn build - - name: Run test - env: - INFURA_URL: ${{ secrets.INFURA_URL }} - run: yarn ts-node scripts/test-recent-mainnet-block.ts - - name: Notify failures - if: failure() - uses: slackapi/slack-github-action@v1.18.0 - with: - payload: | - { - "workflow_name": "${{ github.workflow }}", - "run_url": "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" - } - env: - SLACK_WEBHOOK_URL: ${{ secrets.GH_ACTION_NOTIFICATIONS_SLACK_WEBHOOK_URL }} diff --git a/.github/workflows/test-slow-imports-rule.yml b/.github/workflows/test-slow-imports-rule.yml new file mode 100644 index 0000000000..6846e721a0 --- /dev/null +++ b/.github/workflows/test-slow-imports-rule.yml @@ -0,0 +1,37 @@ +# This workflow checks that our slow-imports rule works correctly. +# This is done by intentionally breaking the rule, running the linter, and checking +# that we got a non-zero exit code. It's not a completely fault-proof strategy, +# but it's an useful smoke test. +name: Slow imports rule check + +on: + schedule: + - cron: "0 0 * * *" + workflow_dispatch: + push: + paths: + - ".github/workflows/test-slow-imports-rule.yml" + +defaults: + run: + working-directory: packages/hardhat-core + +jobs: + test-slow-imports-rule: + name: Check that the slow-imports rule works correctly + runs-on: "ubuntu-latest" + steps: + - uses: actions/checkout@v4 + - uses: ./.github/actions/setup-env + - name: Install + run: pnpm install --frozen-lockfile --prefer-offline + - name: Add slow import + run: echo 'import "lodash";' >> src/internal/core/config/config-resolution.ts + - name: Build + run: pnpm build + - name: Run eslint + id: run-linter + run: pnpm eslint + continue-on-error: true + - name: Check linter status code + run: test ${{ steps.run-linter.outcome }} != success diff --git a/.gitignore b/.gitignore index 8cd8dd3872..3feb9f4cca 100644 --- a/.gitignore +++ b/.gitignore @@ -16,10 +16,6 @@ workspace.code-workspace # Logs logs *.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json @@ -58,21 +54,15 @@ jspm_packages/ # TypeScript v1 declaration files typings/ -# Optional npm cache directory -.npm - # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history -# Output of 'npm pack' +# Output of 'pnpm pack' *.tgz -# Yarn Integrity file -.yarn-integrity - # parcel-bundler cache (https://parceljs.org/) .cache @@ -94,23 +84,25 @@ typings/ # DynamoDB Local files .dynamodb/ - docs/.env.example -# Generated by Cargo -# will have compiled files and executables -debug/ -target/ +# VSCode settings +.vscode/ -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock +# EDR remote node cache +edr-cache/ -# These are backup files generated by rustfmt -**/*.rs.bk +# Brew package manager. +# Lock file is not recommended to be commited: https://github.com/Homebrew/homebrew-bundle#versions-and-lockfiles +Brewfile.lock.json -# MSVC Windows builds of rustc generate these, which store debugging information -*.pdb +*.code-workspace -# VSCode settings -.vscode/ +# Performance profiling application +.clinic + +# Input to scripts/generate-filters.js; generated in CI +pnpm-lock.json + +# Hardhat bundle +bundle/ diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000..6c59086d86 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +enable-pre-post-scripts=true diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000000..3c032078a4 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +18 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..9005ebe57b --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +docs/.next diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 85b90bca8c..db4ca1cf36 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,17 +12,17 @@ We use a [GitHub project](https://github.com/orgs/NomicFoundation/projects/4/vie ## Project structure -This repository is a monorepo handled with [Yarn v1](https://classic.yarnpkg.com/lang/en/) and [Yarn workspaces](https://classic.yarnpkg.com/en/docs/workspaces/). +This repository is a monorepo handled with [pnpm](https://pnpm.io/) and [pnpm workspaces](https://pnpm.io/workspaces). There's a folder for each subproject in `packages/`. All of them are plugins, except for `/packages/hardhat-core` which is the main project (i.e. the one that's published as [hardhat](https://npmjs.com/package/hardhat) in npm). ## Installing -To install the project's dependencies, run `yarn` in the root directory of the repository. +To install the project's dependencies, run `pnpm i` in the root directory of the repository. ## Building the projects -Plugins require hardhat to be built or tested. Our recommendation is to run `yarn watch` from the root folder. This will keep everything compiled, and these problems will be avoided. +Plugins require hardhat to be built or tested. Our recommendation is to run `pnpm watch` from the root folder. This will keep everything compiled, and these problems will be avoided. ## Testing @@ -30,11 +30,11 @@ All tests are written using [mocha](https://mochajs.org) and [chai](https://www. ### Per-package -You can run a package's tests by executing `yarn test` inside its folder. +You can run a package's tests by executing `pnpm test` inside its folder. ### Entire project -You can run all the tests at once by running `yarn test` from the root folder. +You can run all the tests at once by running `pnpm test` from the root folder. ## Code formatting @@ -42,7 +42,7 @@ We use [Prettier](https://prettier.io/) to format all the code without any speci We also have [eslint](https://eslint.org/) installed in all the projects. It checks that you have run Prettier and forbids some dangerous patterns. -The linter is always run in the CI, so make sure it passes before pushing code. You can use `yarn lint` and `yarn lint:fix` inside the packages' folders. +The linter is always run in the CI, so make sure it passes before pushing code. You can use `pnpm lint` and `pnpm lint:fix` inside the packages' folders. ## Branching @@ -95,23 +95,17 @@ This is a list of the modules that always get loaded during startup: ## Developing locally -All these tips assume you are running `yarn watch` from the root directory. +All these tips assume you are running `pnpm watch` from the root directory. ### Linking -You can [link](https://classic.yarnpkg.com/en/docs/cli/link/) any package to test it locally. While the rest of the commands we run use `yarn`, we recommend you use `npm` for linking, since `yarn link` won't create the `hardhat` executable. For example, if you are working on `hardhat`, you can follow these steps: +You can [link](https://docs.npmjs.com/cli/v9/commands/npm-link/) any package to test it locally. While the rest of the commands we run use `pnpm`, we recommend you use `npm` for linking. For example, if you are working on `hardhat`, you can follow these steps: 1. Go to `packages/hardhat-core` and run `npm link` 2. Go to some hardhat project and run `npm link hardhat` Now any change you make in the code will be reflected in that project. -If you prefer to use `yarn link`, you need to work around the lack of an executable in `node_modules/.bin/hardhat`. We recommend having an alias like this: - -```bash -alias lhh='node --preserve-symlinks $(node -e "console.log(require.resolve(\"hardhat/internal/cli/cli.js\"))")' -``` - ### Yalc If for any reason linking doesn't work for you, you can use [`yalc`](https://github.com/whitecolor/yalc): @@ -121,12 +115,12 @@ If for any reason linking doesn't work for you, you can use [`yalc`](https://git Unlike linking, if you make a change in the code, you'll need to repeat the process. -### yarn pack +### pnpm pack -An even more realistic way of using your local changes in a project is to use [`yarn pack`](https://classic.yarnpkg.com/en/docs/cli/pack/): +An even more realistic way of using your local changes in a project is to use [`pnpm pack`](https://pnpm.io/cli/pack): -1. Go to `packages/hardhat-core` and run `yarn pack`. This will create a `nomiclabs-hardhat-x.y.z.tgz` file in that directory. -2. Go to some hardhat project and run `yarn add /path/to/hardhat/packages/hardhat/nomiclabs-hardhat-x.y.z.tgz`. +1. Go to `packages/hardhat-core` and run `pnpm pack`. This will create a `hardhat-x.y.z.tgz` file in that directory. +2. Go to some hardhat project and run `npm install /path/to/hardhat/packages/hardhat-core/hardhat-x.y.z.tgz`. Unlike linking, if you make a change in the code, you'll need to repeat the process. @@ -145,3 +139,12 @@ When tests are run, Hardhat gets initialized multiple times, and that means unlo This problem is normally not present if you are monkey-patching an object that you initialized, but it is when monkey-patching a class, its prototype, or a singleton object initialized by the library itself. For an example on how to do it properly, please take a look at the `hardhat-truffle5` plugin. + +## Note about small PRs and airdrop farming + +We generally really appreciate external contributions, and strongly encourage meaningful additions and fixes! However, due to a recent increase in small PRs potentially created to farm airdrops, we might need to close a PR without explanation if any of the following apply: + +- It is a change of very minor value that still requires additional review time/fixes (e.g. PRs fixing trivial spelling errors that can’t be merged in less than a couple of minutes due to incorrect suggestions) +- It introduces inconsequential changes (e.g. rewording phrases) +- The author of the PR does not respond in a timely manner +- We suspect the Github account of the author was created for airdrop farming diff --git a/FUNDING.json b/FUNDING.json new file mode 100644 index 0000000000..f6fef1dd59 --- /dev/null +++ b/FUNDING.json @@ -0,0 +1,10 @@ +{ + "drips": { + "ethereum": { + "ownedBy": "0xbF38a8Dac2AB41e72532c71fcF7Bd703432f3713" + } + }, + "opRetro": { + "projectId": "0x670a2982f6d7786b58a8399bcabc23246365b21e533a97945e055791fc235e64" + } +} diff --git a/banner-config.json b/banner-config.json new file mode 100644 index 0000000000..9d584acbba --- /dev/null +++ b/banner-config.json @@ -0,0 +1,6 @@ +{ + "enabled": false, + "formattedMessages": [], + "minSecondsBetweenDisplays": 0, + "minSecondsBetweenRequests": 0 +} diff --git a/config/eslint/constants.js b/config/eslint/constants.js new file mode 100644 index 0000000000..9b37675e7c --- /dev/null +++ b/config/eslint/constants.js @@ -0,0 +1,23 @@ +module.exports.slowImportsCommonIgnoredModules = [ + "picocolors", + "debug", + "find-up", + "fs-extra", + "semver", + "source-map-support/register", + "@nomicfoundation/hardhat-ethers", + "hardhat/common", + "hardhat/common/bigInt", + "hardhat/config", + "hardhat/plugins", + "hardhat/types", + "hardhat/types/artifacts", + "hardhat/types/config", + "hardhat/types/runtime", + "hardhat/builtin-tasks/task-names", + "hardhat/internal/core/errors", + "hardhat/internal/core/providers/util", + "hardhat/internal/util/fs-utils", + "hardhat/utils/contract-names", + "hardhat/utils/source-names", +]; diff --git a/config/eslint/eslintrc.js b/config/eslint/eslintrc.js index 0d563e5981..4e8460d036 100644 --- a/config/eslint/eslintrc.js +++ b/config/eslint/eslintrc.js @@ -4,13 +4,17 @@ module.exports = { es6: true, node: true, }, - extends: ["plugin:prettier/recommended"], + extends: [ + "plugin:prettier/recommended", + "plugin:@nomicfoundation/slow-imports/recommended", + ], parser: "@typescript-eslint/parser", plugins: [ - "@nomiclabs/eslint-plugin-hardhat-internal-rules", - "eslint-plugin-import", - "no-only-tests", + "@nomicfoundation/hardhat-internal-rules", + "import", + "mocha", "@typescript-eslint", + "@nomicfoundation/slow-imports", ], rules: { "@typescript-eslint/adjacent-overload-signatures": "error", @@ -79,6 +83,12 @@ module.exports = { format: ["camelCase", "UPPER_CASE"], leadingUnderscore: "allow", }, + { + selector: ["classProperty"], + modifiers: ["private"], + format: ["camelCase", "UPPER_CASE"], + leadingUnderscore: "require", + }, { selector: "enumMember", format: ["UPPER_CASE"], @@ -191,12 +201,11 @@ module.exports = { "no-cond-assign": "error", "no-debugger": "error", "no-duplicate-case": "error", - "no-duplicate-imports": "error", + "@typescript-eslint/no-duplicate-imports": "error", "no-eval": "error", "no-extra-bind": "error", "no-new-func": "error", "no-new-wrappers": "error", - "no-only-tests/no-only-tests": "error", "no-return-await": "off", "@typescript-eslint/return-await": "error", "no-sequences": "error", @@ -228,5 +237,7 @@ module.exports = { patterns: ["hardhat/src", "@nomiclabs/*/src"], }, ], + "mocha/no-exclusive-tests": "error", + "mocha/no-async-describe": "error", }, }; diff --git a/config/typescript/tsconfig.json b/config/typescript/tsconfig.json index fbbc0efe2c..52c240b20e 100644 --- a/config/typescript/tsconfig.json +++ b/config/typescript/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "target": "ES2020", + "target": "ES2021", "module": "commonjs", "declaration": true, "declarationMap": true, diff --git a/crates/rethnet_evm_napi/.gitignore b/crates/rethnet_evm_napi/.gitignore deleted file mode 100644 index 2e30f56130..0000000000 --- a/crates/rethnet_evm_napi/.gitignore +++ /dev/null @@ -1,112 +0,0 @@ -# node modules -/node_modules - -# vuepress -/docs/.vuepress/dist/ - -# Tests compilation output -/build-test/ - -# Code coverage artifacts -/coverage -/.nyc_output - -# TSC prod output. This has to be in sync with the to directories in ./src, and with npm script clean - -/*.js -/*.js.map -/*.d.ts -/*.d.ts.map -/*.node -/builtin-tasks -/common -/internal -/types -/utils - -test/internal/hardhat-network/provider/.hardhat_node_test_cache/ -!.eslintrc.js - -# Below is Github's node gitignore template, -# ignoring the node_modules part, as it'd ignore every node_modules, and we have some for testing - -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* - -# Diagnostic reports (https://nodejs.org/api/report.html) -report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json - -# Runtime data -pids -*.pid -*.seed -*.pid.lock - -# Directory for instrumented libs generated by jscoverage/JSCover -lib-cov - -# Coverage directory used by tools like istanbul -coverage - -# nyc test coverage -.nyc_output - -# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) -.grunt - -# Bower dependency directory (https://bower.io/) -bower_components - -# node-waf configuration -.lock-wscript - -# Compiled binary addons (https://nodejs.org/api/addons.html) -build/Release - -# Dependency directories -#node_modules/ -jspm_packages/ - -# TypeScript v1 declaration files -typings/ - -# Optional npm cache directory -.npm - -# Optional eslint cache -.eslintcache - -# Optional REPL history -.node_repl_history - -# Output of 'npm pack' -*.tgz - -# Yarn Integrity file -.yarn-integrity - -# parcel-bundler cache (https://parceljs.org/) -.cache - -# next.js build output -.next - -# nuxt.js build output -.nuxt - -# vuepress build output -.vuepress/dist - -# Serverless directories -.serverless/ - -# FuseBox cache -.fusebox/ - -# DynamoDB Local files -.dynamodb/ diff --git a/docs/.babelrc b/docs/.babelrc deleted file mode 100644 index 2a7aa6993b..0000000000 --- a/docs/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["next/babel", "linaria/babel"] -} diff --git a/docs/.env.example b/docs/.env.example deleted file mode 100644 index bf0bb398a6..0000000000 --- a/docs/.env.example +++ /dev/null @@ -1,4 +0,0 @@ -NEXT_PUBLIC_ALGOLIA_APP_ID = -NEXT_PUBLIC_ALGOLIA_API_KEY = -NEXT_PUBLIC_ALGOLIA_INDEX_NAME = -NEXT_PUBLIC_MEASUREMENT_ID = diff --git a/docs/.eslintrc.js b/docs/.eslintrc.js deleted file mode 100644 index f3cbe10dca..0000000000 --- a/docs/.eslintrc.js +++ /dev/null @@ -1,31 +0,0 @@ -module.exports = { - parser: "@typescript-eslint/parser", - parserOptions: { - project: "./tsconfig.json", - }, - extends: [ - `${__dirname}/../config/eslint/eslintrc.js`, - "airbnb", - "airbnb-typescript", - "next/core-web-vitals", - "plugin:storybook/recommended", - "prettier", - ], - rules: { - "react/function-component-definition": [ - "error", - { - namedComponents: ["arrow-function", "function-declaration"], - }, - ], - "no-shadow": "off", - "arrow-body-style": "off", - "react/jsx-props-no-spreading": "off", - "react/require-default-props": "off", - "react/no-array-index-key": "off", - "import/no-extraneous-dependencies": "off", - "@typescript-eslint/strict-boolean-expressions": "off", - "react/no-danger": "off", - "no-console": ["error", { allow: ["warn", "error"] }], - }, -}; diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index 6dac9b8c3c..0000000000 --- a/docs/.gitignore +++ /dev/null @@ -1,47 +0,0 @@ -# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. - -# dependencies -/node_modules -/.pnp -.pnp.js - -# testing -/coverage - -# next.js -/.next/ -/out/ - -# vscode -/.vscode - -# build -/build -/storybook-static -/temp/* -!/temp/info.md -/public/sitemap-0.xml -/public/sitemap*.xml -src/content/hardhat-runner/docs/errors/index.md - -# misc -.DS_Store -*.pem - -# debug -npm-debug.log* -yarn-debug.log* -yarn-error.log* -.pnpm-debug.log* - -# local env files -.env.local -.env.development.local -.env.test.local -.env.production.local - -# vercel -.vercel - -# typescript -*.tsbuildinfo diff --git a/docs/.prettierignore b/docs/.prettierignore deleted file mode 100644 index 07e6e472cc..0000000000 --- a/docs/.prettierignore +++ /dev/null @@ -1 +0,0 @@ -/node_modules diff --git a/docs/.storybook/common-decorators.js b/docs/.storybook/common-decorators.js deleted file mode 100644 index 92def8ae8a..0000000000 --- a/docs/.storybook/common-decorators.js +++ /dev/null @@ -1,7 +0,0 @@ -import React from "react"; - -export const mdWrapper = (Story) => ( -
- -
-); diff --git a/docs/.storybook/main.js b/docs/.storybook/main.js deleted file mode 100644 index 1fd63db5b6..0000000000 --- a/docs/.storybook/main.js +++ /dev/null @@ -1,26 +0,0 @@ -const nextConfig = require("../next.config.js"); - -module.exports = { - stories: ["../src/components/**/*.stories.tsx"], - addons: [ - "@react-theming/storybook-addon", - // "@storybook/addon-links", - // "@storybook/addon-essentials", - // "@storybook/addon-interactions", - ], - staticDirs: ["../public"], - framework: "@storybook/react", - webpackFinal: async (baseConfig) => { - return nextConfig.linariaConfig.webpack(baseConfig, {}); - }, - typescript: { - check: false, - checkOptions: {}, - reactDocgen: "react-docgen-typescript", - reactDocgenTypescriptOptions: { - shouldExtractLiteralValuesFromEnum: true, - propFilter: (prop) => - prop.parent ? !/node_modules/.test(prop.parent.fileName) : true, - }, - }, -}; diff --git a/docs/.storybook/preview.js b/docs/.storybook/preview.js deleted file mode 100644 index d836787ff7..0000000000 --- a/docs/.storybook/preview.js +++ /dev/null @@ -1,86 +0,0 @@ -import React from "react"; -import { withThemes } from "@react-theming/storybook-addon"; -import * as NextImage from "next/image"; - -import "../src/styles/globals.css"; - -import { - ThemeProvider, - media, - tmSelectors, - breakpoints, - lightPalette, - darkPalette, - hcDarkPalette, - ThemeContext, - theming, - ThemesEnum, -} from "../src/themes"; - -export const parameters = { - actions: { argTypesRegex: "^on[A-Z].*" }, - controls: { - matchers: { - color: /(background|color)$/i, - date: /Date$/, - }, - }, -}; - -const OriginalNextImage = NextImage.default; - -Object.defineProperty(NextImage, "default", { - configurable: true, - value: (props) => , -}); - -const providerFn = ({ theme, children }) => { - const appTheme = { - light: { - colors: theme, - }, - dark: { - colors: darkPalette, - }, - hcDark: { - colors: hcDarkPalette, - }, - media, - breakpoints, - tmSelectors, - }; - - const themesTypesMap = { - Light: ThemesEnum.LIGHT, - Dark: ThemesEnum.DARK, - "Dark HC": ThemesEnum.HC_DARK, - }; - - return ( - null }} - > - {children} - - ); -}; - -export const onThemeSwitch = (context) => { - const { theme } = context; - const background = theme.neutral0 || null; - const parameters = { - backgrounds: { - default: background, - }, - }; - return { - parameters, - }; -}; - -const themingDecorator = withThemes( - null, - [lightPalette, darkPalette, hcDarkPalette], - { providerFn, onThemeSwitch } -); -export const decorators = [themingDecorator]; diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index b5c9b1f93b..0000000000 --- a/docs/README.md +++ /dev/null @@ -1,212 +0,0 @@ -# Hardhat documentation website - -This is a NextJS-based application for the Hardhat documentation website. This app is utilizing SSG for creating pages on the build step. It's developed keeping the best practices in mind including accessibility, SEO and Performance optimizations, and scalability - -The app mainly provides two types of pages: - -- landing pages (see home page) -- documentation pages (see documentation section) - -Landing pages are composed of reusable blocks and separate content files. Blocks are full-width React Components that can be stacked to compose a page. Blocks output content passed to them via props. - -Documentation pages are generated from markdown files located in the `src/content` folder. This folder has a nesting structure that is mapped to the page URLs on the website. - -It's assumed that the app will be hosted on the Vercel platform which is highly optimized for SSG apps. - -We consider two directions of the follow-up application growing: - -- by creating and editing new content. -- by adding new features to the app. - -The first one can be provided by working with human-friendly file formats located in the content folder (MD and YAML). Only minimal tech knowledge is needed for that. The second way requires developers' efforts. - -## Preview - -https://hardhat-lime.vercel.app/ - -## Adding content - -Website content is located in `*.md` files within `src/content` folder. It's written in Markdown syntax. Folders structure in `content` is reflected on the website. - -To tune pages, behavior and appearance also use optional `*.yaml` files with additional configurations. - -To preview content locally, launch the app with `yarn dev` and open http://127.0.0.1:3000 in your browser. See details in [Development](#development) section. - -### Layouts - -All content is organized by hierarchy levels and the top-level entries are layouts. The layout represents a set of folders and provides navigation within them. Currently, a folder should belong to one of the layouts. In terms of UI, the layout is equal to a sidebar navigation menu with two-level items. Layouts settings can be found in the `src/content/layouts.yaml` file. It contains all layouts (currently "documentation" and "tutorial"). Each layout can have the following settings: - -- title (optional) -- folders - the list of folders should be included in this layout - -### Folders - -The next level is a folder. It can contain nesting folders and `*.md` files. Each `*.md` file represents a single documentation page. Folders usually are represented in a sidebar as a group of items with a common title - each item in this group opens a separate file in the folder. Folders can be nested but it only affects the page's path on the website, sidebar navigation is always of two levels. To configure folders we're using `_dirinfo.yaml` files which can contain the following settings: - -**section-title**: the title of a group in the sidebar. It's optional, if skipped the folder name will be used. - -**section-type**: this setting controls the appearance of the group in the sidebar. It can be: - -- group - a regular group with a title and list of items -- single - good for groups with a single item -- hidden - the folder won't be shown in the sidebar but when you open a page from this group sidebar is present. -- plugins - the "special" group with is generated not from the `*.md` files located in the content folder, but from README.md files from plugin packages - -**order**: an array of items in the order they should appear in the sidebar group. This is optional but if it's not specified the order will be based on file names. This array can contain two types of items: - -- simple href strings (which are the same as a path to a file without a file extension. e.g. `/explanation/mining-modes`). Note it shouldn't contain the group folder name in the path. In this case, the title of the item will be generated automatically and will be the same as a page title. -- objects with `href` and `title` keys. In this case, href can be any valid relative link. The title specifies the title of that item in the sidebar. Note: this allows to specify anchor links e.g. `"#quick-start"` or a "index" links - `/`. - -### MD Files - -All documentation content is represented by `*.md` files with Markdown syntax. Besides the base Markdown syntax, we support the following features: - -- MD Directives. Used to represent _Admonition_ components (currently `Tip` and `Warning`). -- Code syntax highlighting -- Line highlighting in code blocks. -- Code tabs with alternative languages - - - -### Redirects - -Redirects allow you to redirect an incoming request path to a different destination path. Redirects settings are located in `redirects.config.js` file. It exports an array of objects. Each object represents a single redirect option. We utilize [NextJS Redirects](https://nextjs.org/docs/api-reference/next.config.js/redirects) API for that. - -### Tabs - -We use the plugin `remark-directive` in order to provide tabs functionality. - -#### Use - -#### `tabsgroup` and `tab` - -`tabsgroup` is a wrapper that wraps a group of tabs and sets all possible values of tabs. - -`tab` is a wrapper that wraps a codeblock (or some other element). - -#### Example: - -``` -::::tabsgroup{options=npm,yarn} - :::tab{value=npm} - // codeblock or some other element - ::: - - :::tab{value=yarn} - // codeblock or some other element - ::: -:::: -``` - -#### Parameters - -Parameters are passed in curly braces. - -`options-list` - required parameter. Comma separated strings, which is provided in tabs' `value` parameter. - -`value` - required parameter. It should be provided as an option in `options-list` in `tabsgroup`. - -You can use `space` symbol in parameters by wrapping `options/value` in quotes(`""`). Examples: `options="npm 7+,yarn"` / `value="npm 7"`. - -### Front Matter - -The front matter must be the first thing in the markdown file and must take the form of valid YAML set between triple-dashed lines. Here is an example: - -``` ---- -title: Overview -description: Hardhat | Ethereum development environment for professionals -prev: false -next: false ---- -``` - -You can specify `title`, `description` for SEO manually or disable `prev` and `next` links for Footer Navigation by using Front Matter. - -## Development - -This website is an SSG application based on Next.js. To learn more about Next.js, take a look at the following resources: - -- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. -- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. - -First, install dependencies: - -```sh -cd docs -yarn -``` - -Then, run the development server: - -```bash -yarn dev -``` - -Open [http://127.0.0.1:3000](http://127.0.0.1:3000) with your browser to see the result. - -You can start editing the page by modifying `src/pages/...`. The page auto-updates as you edit the file. - -### Folders structure - -When developing the application you might need these main folders - -- src/components - React Components for rendering pages -- src/components/landingBlocks - "Building blocks" for creating landing pages -- src/components/mdxComponents - Components used to render markdown content -- src/components/ui - common UI components -- src/hooks - common React hooks -- src/model - business logic files -- src/pages - NextJS pages. `[...docPath].tsx` means multiple pages will be generated. Page routes are based on the relative paths -- src/styles - global CSS styles -- src/config.ts - keep main information about the app. -- public/ - static files -- .storybook/ - Storybook settings -- next.config.js - NextJS config -- redirects.config.js - Custom redirects - -## Storybook - -You can use Storybook to develop components in isolation. Launch it via `yarn storybook` and open http://127.0.0.1:6006/ You will see a list of components in the left-side sidebar. When you edit component's code and save it, the Storybook is auto-updating it. - -Each component can be exposed with different states (stories) independently by passing props you need. You can find component stories settings in `Component.stories.ts` files. - -We also deploy updated storybook on each build. You can find it on https://hardhat-storybook.netlify.app/ - -## Content generating tech details - -There are two relatively independent processes in the build step: - -1. Generating pages themselves. We get page paths directly from the files located in the content folder. Their paths are mapped to the page routes. Layout settings don't affect to page's existence. -2. Generating layouts and mapping layouts to pages. For that, we're checking which folders belong to what layout and assigning that layout to a page - -Page paths are generated in the `getStaticPaths` functions in files of the `page` folder. The result of these functions is an array of page paths. Page pros are generated with the `getStaticProps` function which is executed once per page with a page path passed as an argument and returns all required page props. - -Execution of `getStaticPaths` and `getStaticProps` is handled by NextJS on a build step and it runs them in isolation (which means we can't share common calculated parameters within them). To optimize building time, we store an intermediate config in a temporary file on the `getStaticPaths` execution and read it from `getStaticProps` functions. It contains layout settings and a map of pages with specific props. - -## Styling - -We utilize [Linaria](https://github.com/callstack/linaria) for styling components. It has the "Styled Components" syntax but generates css without runtime with works fine with SSG sites. - -## Theming - -The documentation section is Themable. A user can switch between light, dark and high contrast themes for their convenience. There is also an "Auto" setting when theme is selected based on a user system settings. - -Theming solution provides abilities to switch themes, keep the selected value in user's local storage, seamlessly keep selected page on navigating and page refreshing. - -We manage themes by applying a CSS class to the HTML body. Each component has special selectors in its CSS to reflect change color depending on selected theme. To support themes, components should provide styles for all app themes (add selectors and specify colors). - -Landing pages don't support themes. - -## Creating new landings - -Landing pages contains special "blocks" see src/components/landingBlocks. To create a new landing page start from copying `/pages/index.tsx` and `src/content/home.ts`. You can create another page by reodering existing blocks and passing another content to them. If necessary create new landing blocks. - -## CI/CD - -We use two CI/CD providers: - -- Github actions for launching code checks -- Vercel to deploy app - -Each branch triggers its own process on CI/CD so you can see code check details on Github and preview the current branch on Vercel. diff --git a/docs/next-env.d.ts b/docs/next-env.d.ts deleted file mode 100644 index 4f11a03dc6..0000000000 --- a/docs/next-env.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -/// -/// - -// NOTE: This file should not be edited -// see https://nextjs.org/docs/basic-features/typescript for more information. diff --git a/docs/next-sitemap.js b/docs/next-sitemap.js deleted file mode 100644 index c622aff27a..0000000000 --- a/docs/next-sitemap.js +++ /dev/null @@ -1,6 +0,0 @@ -/** @type {import('next-sitemap').IConfig} */ - -module.exports = { - siteUrl: "https://hardhat.org", - generateRobotsTxt: true, -}; diff --git a/docs/next.config.js b/docs/next.config.js deleted file mode 100644 index a99e253e55..0000000000 --- a/docs/next.config.js +++ /dev/null @@ -1,55 +0,0 @@ -/** @type {import('next').NextConfig} */ -const path = require("path"); -const withLinaria = require("next-linaria"); -const withPlugins = require("next-compose-plugins"); - -const customRedirects = require("./redirects.config"); -const withBundleAnalyzer = require("@next/bundle-analyzer")({ - enabled: process.env.ANALYZE === "true", -}); - -const linariaConfig = withLinaria({ - async redirects() { - return [ - { - /** - * NOTE: this removes '.html' extensions from URLs - * e.g. https://hardhat.org/hardhat-network/explanation/mining-modes.html becomes - * https://hardhat.org/hardhat-network/explanation/mining-modes - * - * We need this to keep the links of the previous version workable. - * - * The only exception is the privacy-policy.html file, which we host in - * public/ - */ - source: "/:slug((?!privacy-policy).*).html", - destination: "/:slug*", - permanent: true, - }, - ...customRedirects, - ]; - }, - reactStrictMode: true, - future: { - webpack5: true, - }, - webpack(baseConfig) { - // eslint-disable-next-line no-param-reassign - baseConfig.resolve.alias.theme = path.resolve(__dirname, "./src/themes"); - return baseConfig; - }, - linaria: { - cacheDirectory: - process.env.NODE_ENV === "production" - ? ".next/cache/.linaria-cache" - : ".linaria-cache", - }, - pageExtensions: ["ts", "tsx", "js", "jsx", "md", "mdx"], - images: { - dangerouslyAllowSVG: true, - domains: ["img.shields.io", "hardhat.org"], - }, -}); - -module.exports = withPlugins([linariaConfig, withBundleAnalyzer]); -module.exports.linariaConfig = linariaConfig; diff --git a/docs/package.json b/docs/package.json deleted file mode 100644 index b051b4e0a6..0000000000 --- a/docs/package.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "name": "docs", - "version": "0.1.0", - "private": true, - "scripts": { - "prebuild": "ts-node --transpileOnly --skipProject scripts/prepare-error-list.ts", - "dev": "next-remote-watch ./src/content", - "dev:debug": "NODE_OPTIONS='--inspect' next dev", - "build": "next build", - "postbuild": "next-sitemap", - "build:test": "ANALYZE=true next build", - "start": "next start", - "lint": "eslint src -f unix", - "storybook": "start-storybook -p 6006 --ci", - "build-storybook": "build-storybook" - }, - "dependencies": { - "@callstack/react-theme-provider": "^3.0.7", - "@docsearch/react": "3", - "glob": "^8.0.1", - "gray-matter": "^4.0.3", - "hastscript": "^7.0.2", - "linaria": "^2.3.1", - "next": "12.1.0", - "next-linaria": "^0.11.0", - "next-mdx-remote": "^4.0.2", - "react": "17.0.2", - "react-dom": "17.0.2", - "react-responsive-carousel": "^3.2.23", - "rehype-prism": "^2.1.2", - "remark-directive": "^2.0.1", - "remark-gfm": "^3.0.1", - "remark-prism": "^1.3.6", - "remark-unwrap-images": "^3.0.1", - "ts-node": "^10.8.0", - "undici": "^5.19.1", - "unist-util-visit": "^4.1.0" - }, - "devDependencies": { - "@babel/core": "^7.17.5", - "@babel/preset-env": "^7.16.11", - "@next/bundle-analyzer": "^12.1.5", - "@react-theming/storybook-addon": "^1.1.5", - "@storybook/addon-actions": "^6.4.19", - "@storybook/addon-essentials": "^6.4.19", - "@storybook/addon-interactions": "^6.4.19", - "@storybook/addon-links": "^6.4.19", - "@storybook/react": "^6.4.19", - "@storybook/testing-library": "^0.0.9", - "@types/mdx-js__react": "^1.5.5", - "@types/node": "17.0.21", - "@types/react": "17.0.39", - "@types/remark-prism": "^1.3.3", - "@typescript-eslint/eslint-plugin": "^5.16.0", - "@typescript-eslint/parser": "^5.16.0", - "babel-eslint": "^10.1.0", - "babel-loader": "^8.2.3", - "eslint": "8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.4", - "eslint-config-next": "12.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react-hooks": "^4.3.0", - "eslint-plugin-storybook": "^0.5.7", - "js-yaml": "^4.1.0", - "next-compose-plugins": "^2.2.1", - "next-remote-watch": "^1.0.0", - "next-sitemap": "^2.5.20", - "prettier": "2.4.1", - "typescript": "4.5.5" - } -} diff --git a/docs/public/buidler-plugin-badge.svg b/docs/public/buidler-plugin-badge.svg deleted file mode 100644 index 94f6a233e0..0000000000 --- a/docs/public/buidler-plugin-badge.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/public/card.jpg b/docs/public/card.jpg deleted file mode 100644 index 51eb13488c..0000000000 Binary files a/docs/public/card.jpg and /dev/null differ diff --git a/docs/public/cool-hardhat.svg b/docs/public/cool-hardhat.svg deleted file mode 100644 index 622abfd365..0000000000 --- a/docs/public/cool-hardhat.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/public/favicon.ico b/docs/public/favicon.ico deleted file mode 100755 index d5e6b335eb..0000000000 Binary files a/docs/public/favicon.ico and /dev/null differ diff --git a/docs/public/fonts/Chivo-Bold.ttf b/docs/public/fonts/Chivo-Bold.ttf deleted file mode 100755 index c83bb44c59..0000000000 Binary files a/docs/public/fonts/Chivo-Bold.ttf and /dev/null differ diff --git a/docs/public/fonts/Chivo-Bold.woff2 b/docs/public/fonts/Chivo-Bold.woff2 deleted file mode 100644 index 1530d7a6cf..0000000000 Binary files a/docs/public/fonts/Chivo-Bold.woff2 and /dev/null differ diff --git a/docs/public/fonts/Chivo-Light.ttf b/docs/public/fonts/Chivo-Light.ttf deleted file mode 100755 index daa73e5af1..0000000000 Binary files a/docs/public/fonts/Chivo-Light.ttf and /dev/null differ diff --git a/docs/public/fonts/Chivo-Light.woff2 b/docs/public/fonts/Chivo-Light.woff2 deleted file mode 100644 index b09dcae464..0000000000 Binary files a/docs/public/fonts/Chivo-Light.woff2 and /dev/null differ diff --git a/docs/public/fonts/Chivo-Regular.ttf b/docs/public/fonts/Chivo-Regular.ttf deleted file mode 100755 index f9cf49002c..0000000000 Binary files a/docs/public/fonts/Chivo-Regular.ttf and /dev/null differ diff --git a/docs/public/fonts/Chivo-Regular.woff2 b/docs/public/fonts/Chivo-Regular.woff2 deleted file mode 100644 index 3441424875..0000000000 Binary files a/docs/public/fonts/Chivo-Regular.woff2 and /dev/null differ diff --git a/docs/public/front-2.png b/docs/public/front-2.png deleted file mode 100644 index babe1702a2..0000000000 Binary files a/docs/public/front-2.png and /dev/null differ diff --git a/docs/public/front-5.png b/docs/public/front-5.png deleted file mode 100644 index 457d109fe2..0000000000 Binary files a/docs/public/front-5.png and /dev/null differ diff --git a/docs/public/front-6.png b/docs/public/front-6.png deleted file mode 100644 index c2c0aa5e8f..0000000000 Binary files a/docs/public/front-6.png and /dev/null differ diff --git a/docs/public/hardhat-tutorial.svg b/docs/public/hardhat-tutorial.svg deleted file mode 100644 index 6487cffc52..0000000000 --- a/docs/public/hardhat-tutorial.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/public/hardhat-vscode-images/configure_default_formatter.png b/docs/public/hardhat-vscode-images/configure_default_formatter.png deleted file mode 100644 index e986e53edc..0000000000 Binary files a/docs/public/hardhat-vscode-images/configure_default_formatter.png and /dev/null differ diff --git a/docs/public/hardhat-vscode-images/constrain-mutability.gif b/docs/public/hardhat-vscode-images/constrain-mutability.gif deleted file mode 100644 index e8505f5cd8..0000000000 Binary files a/docs/public/hardhat-vscode-images/constrain-mutability.gif and /dev/null differ diff --git a/docs/public/hardhat-vscode-images/diagnostic.gif b/docs/public/hardhat-vscode-images/diagnostic.gif deleted file mode 100644 index ba2fea8ac0..0000000000 Binary files a/docs/public/hardhat-vscode-images/diagnostic.gif and /dev/null differ diff --git a/docs/public/hardhat-vscode-images/format.gif b/docs/public/hardhat-vscode-images/format.gif deleted file mode 100644 index a888986053..0000000000 Binary files a/docs/public/hardhat-vscode-images/format.gif and /dev/null differ diff --git a/docs/public/hardhat-vscode-images/format_document_with.png b/docs/public/hardhat-vscode-images/format_document_with.png deleted file mode 100644 index 1eaaa9f613..0000000000 Binary files a/docs/public/hardhat-vscode-images/format_document_with.png and /dev/null differ diff --git a/docs/public/hardhat-vscode-images/implement-interface.gif b/docs/public/hardhat-vscode-images/implement-interface.gif deleted file mode 100644 index d08f8a3672..0000000000 Binary files a/docs/public/hardhat-vscode-images/implement-interface.gif and /dev/null differ diff --git a/docs/public/hardhat-vscode-images/import-completion.gif b/docs/public/hardhat-vscode-images/import-completion.gif deleted file mode 100644 index bb6e1a1d21..0000000000 Binary files a/docs/public/hardhat-vscode-images/import-completion.gif and /dev/null differ diff --git a/docs/public/hardhat-vscode-images/navigation.gif b/docs/public/hardhat-vscode-images/navigation.gif deleted file mode 100644 index df0c70a189..0000000000 Binary files a/docs/public/hardhat-vscode-images/navigation.gif and /dev/null differ diff --git a/docs/public/hardhat-vscode-images/on-hover.gif b/docs/public/hardhat-vscode-images/on-hover.gif deleted file mode 100644 index c52ca02a4d..0000000000 Binary files a/docs/public/hardhat-vscode-images/on-hover.gif and /dev/null differ diff --git a/docs/public/hardhat-vscode-images/open-config.gif b/docs/public/hardhat-vscode-images/open-config.gif deleted file mode 100644 index 94a1a6f8a5..0000000000 Binary files a/docs/public/hardhat-vscode-images/open-config.gif and /dev/null differ diff --git a/docs/public/hardhat-vscode-images/public-private.gif b/docs/public/hardhat-vscode-images/public-private.gif deleted file mode 100644 index 99fa8ec278..0000000000 Binary files a/docs/public/hardhat-vscode-images/public-private.gif and /dev/null differ diff --git a/docs/public/hardhat-vscode-images/rename.gif b/docs/public/hardhat-vscode-images/rename.gif deleted file mode 100644 index 599d647d5c..0000000000 Binary files a/docs/public/hardhat-vscode-images/rename.gif and /dev/null differ diff --git a/docs/public/hardhat-vscode-images/select_solidity_plus_hardhat.png b/docs/public/hardhat-vscode-images/select_solidity_plus_hardhat.png deleted file mode 100644 index 8abda218ea..0000000000 Binary files a/docs/public/hardhat-vscode-images/select_solidity_plus_hardhat.png and /dev/null differ diff --git a/docs/public/hardhat-vscode-images/virtual-override.gif b/docs/public/hardhat-vscode-images/virtual-override.gif deleted file mode 100644 index f2a4062d98..0000000000 Binary files a/docs/public/hardhat-vscode-images/virtual-override.gif and /dev/null differ diff --git a/docs/public/hh.gif b/docs/public/hh.gif deleted file mode 100644 index 6bfa0f21b1..0000000000 Binary files a/docs/public/hh.gif and /dev/null differ diff --git a/docs/public/images/nomic-foundation-logo-dark.svg b/docs/public/images/nomic-foundation-logo-dark.svg deleted file mode 100644 index d315b739ac..0000000000 --- a/docs/public/images/nomic-foundation-logo-dark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/public/images/nomic-foundation-logo.svg b/docs/public/images/nomic-foundation-logo.svg deleted file mode 100644 index 83ba25182e..0000000000 --- a/docs/public/images/nomic-foundation-logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/public/images/reveiws-logo/aone.svg b/docs/public/images/reveiws-logo/aone.svg deleted file mode 100755 index 3b4a37835c..0000000000 --- a/docs/public/images/reveiws-logo/aone.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/public/images/reveiws-logo/connext.svg b/docs/public/images/reveiws-logo/connext.svg deleted file mode 100755 index 359362fe59..0000000000 --- a/docs/public/images/reveiws-logo/connext.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/public/images/reveiws-logo/decentraland.svg b/docs/public/images/reveiws-logo/decentraland.svg deleted file mode 100755 index 37f56bb78c..0000000000 --- a/docs/public/images/reveiws-logo/decentraland.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/public/images/reveiws-logo/kyber.svg b/docs/public/images/reveiws-logo/kyber.svg deleted file mode 100755 index bae4f777d3..0000000000 --- a/docs/public/images/reveiws-logo/kyber.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/public/images/reveiws-logo/synthetix.svg b/docs/public/images/reveiws-logo/synthetix.svg deleted file mode 100755 index 8cb51c1a54..0000000000 --- a/docs/public/images/reveiws-logo/synthetix.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/public/images/vibrant_community.png b/docs/public/images/vibrant_community.png deleted file mode 100644 index c7e514b073..0000000000 Binary files a/docs/public/images/vibrant_community.png and /dev/null differ diff --git a/docs/public/privacy-policy.html b/docs/public/privacy-policy.html deleted file mode 100644 index 37fbcecfa7..0000000000 --- a/docs/public/privacy-policy.html +++ /dev/null @@ -1,1956 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - -
- -

Nomic Foundation Privacy Policy

- -

Nomic Foundation (the “Nomic Foundation,” “we,” or “us”), a Swiss -Foundation, located at c/o Kaiser Odermatt & -Partner AG, Baarerstrasse 12, 6300 Zug, is a software -development foundation building open-source software to unlock developer -productivity in the Ethereum ecosystem is the controller and processor of your -personal data.

- -

 

- -

This Privacy Policy applies to: (i) the Nomic Foundation -website (https://nomic.foundation), the Hardhat website (https://hardhat.org/), and any other website -published by us (“website”), (ii) the Hardhat software (“Hardhat”), and -the (iii) Hardhat tools and plugins, including the hardhat runner, the hardhat vscode, the @nomicfoundation/coc-solidity, and the hardhat -network which, with any other features, tools and/or materials, domains and -subdomains, projects, made available from time to time by the Foundation (the -“Tools”), all of which are referred to as “services” in this Privacy Policy. -Users of the websites, Hardhat and the Tools are referred to collectively -as “Clients.”

- -

 

- -

This Privacy Policy describes what information Nomic Foundation collects, -how we use that information, and how we protect it. Nomic Foundation collects -and processes personal data in order to run our organization and offer our -services to Clients. We do not share Client information with third parties -except for the limited purposes described in this Privacy Policy.

- -

 

- -

By using our services, Clients understand and agree that we will collect, -process and use their information as described in this Privacy Policy, and in -compliance with the Swiss Federal Act on Data Protection (“FADP”), the Swiss -Ordinance to the Federal Act on Data Protection (“OFADP”), and the General -European Data Protection Regulation (“GDPR”). We recommend that Clients read -this Privacy Policy in full to ensure they are fully informed.

- -

 

- -

If you have any questions about this Privacy Policy or how we handle -personal data, please contact us at privacy@nomic.foundation or use the -contact information set out at bottom of this Privacy Policy.

- -

 

- -

What Personal Data Does Nomic Foundation Collect, -and Why?

- -

The information that Nomic Foundation gathers from Clients allows us to -deliver and improve our services. For example, it allows us to communicate with -Clients, provide support, and (with Clients’ permission) monitor deployments -of Hardhat or any other website and the Tools for -performance-improvement and error-correction purposes.

- -

 

- -

A.        Information Our -Clients Provide

- -

We receive and store the information our Clients -supply to us when they communicate with us by email, GitHub, and social media. -This information may include the Client’s name, company, email address, -username, postal address, and telephone number.

- -

Personal data processed through social media is subject to their privacy -policies. You should check each social media privacy policies. The Nomic -Foundation is not responsible for the data collected by these platforms.

- -

 

- -

B.        Information -Automatically Collected from Clients

- -

We also collect certain information automatically, including:

- -

1.     Error and performance monitoring data

- -

Hardhat collects automated error and performance monitoring data to help -Nomic Foundation fix bugs and improve the performance of our software. This -data is only collected and processed if the Client opts into this feature.

- -

 

- -

The information collected includes: 1) a unique cryptographic identifier -to identify data from a single user; 2) the Hardhat version number; 3) whether -Hardhat is running on a server or desktop; 4) the Client’s operating system -(e.g. Windows, Mac, or Linux); 5) whether the Hardhat task running is a -build-in or user-defined task; 6) the versions of Node.js and Sentry running on -the Client’s computer; 7) error message text; 8) stack trace data; and 9) -timestamps.

- -

 

- -

The Nomic Foundation uses -third-party services, Sentry and Google analytics, to collect and process this -data: i) Google -analytics: extension version, machine Id, operating system, user agent; and ii) -Sentry: extension name + version, environment, machine id as mentioned above, -tags that provide context.

- -

In the case of Sentry, the data is anonymized before being sent to -Sentry’s servers. Any piece of data resembling a path -or a private key is removed on a best-effort basis. The data sent to Sentry is -subject to a data processing agreement limiting Sentry’s use of the data and -requiring Sentry to take appropriate security measures to protect the data.

- -

2.     Website cookies

- -

Like many websites, the Nomic Foundation websites use cookies to obtain -certain types of information when your web browser accesses our site. Cookies -are used most commonly to do things like tracking page -views, identifying repeat users and utilizing login tokens for a session.

- - - - - - - - - - - - - - - - - - - - -
-

Type of Cookie

-
-

Served By

-
-

How to Control These

-
-

Session cookies: these are used to anonymously track a user’s session - on our websites to deliver a better experience.

-
-

Nomic Foundation

-
-

You can block or delete these by changing your browser settings.

-
-

Performance and Targeting cookies: These cookies collect information - that is used either in aggregate form to help us understand how our website - is being used or how effective our marketing campaigns are, or to help us - customize our website for you. Such cookies may record site and - display-related activity for a session so that a client does not see displays - that are irrelevant or have already been dismissed.

-
-

Google

-
-

Google offers a Google - Analytics Opt-Out Browser Add-on for - most browsers.

-
-

You can set or amend your web browser controls to accept or refuse - cookies. If you choose to reject cookies, you may still use our website - though your access to some functionality and areas of our website may be - restricted. As the means by which you can refuse cookies through your web - browser controls vary from browser-to-browser, you should visit your - browser's help menu for more information.

-
- -

 

- -

Other information we collect and analyze includes the Internet Protocol -(IP) address used to connect your computer to the Internet, computer and -connection information such as browser type, version, language, and time zone -setting, browser plug-in type and version, screen resolution, and operating -system and platform. This information is stored in log files and is collected -automatically. We collect this technical information to better understand user -needs and provide Clients with an optimal online experience.

- -

 

- -

We also collect aggregate usage data for our websites, which may include -browsing patterns and broad demographic information, to enable us to understand -how our websites are being used and to develop and refine them to better serve -our Clients.

- -

 

- -

Our Legal Bases for Processing Personal Information

- -

For personal data under Nomic Foundation’s control, we rely on two bases -to lawfully obtain and process personal information. First, where Clients have -given us valid consent to use their data in certain ways, we rely on that -consent. Second, as described in more detail below, in certain cases we may -process information where this is necessary to meet legal obligations, such as -compliance with law enforcement subpoenas or warrants, and/or to further our -legitimate interests, so long as any such legitimate interests are not -overridden by your rights or interests.

- -

 

- -

How and When Do We Share Information?

- -

Nomic Foundation does not sell your information. As set out below, we -only share information on a limited basis in order to enable us to offer our -services. We do not otherwise make Client data available -to third parties.  

- -

 

- -

Service Providers

- -

We employ other organizations and service providers to perform certain -functions on our behalf. These third parties have only limited access to your -information, may use your information only to perform these tasks on our -behalf, and are obligated to Nomic Foundation not to disclose or use your -information for other purposes.

- -

 

- -

All Service Providers warrant to be in compliance with -the GDPR and provide sufficient security to the information they access to.

- -

 

- -

Our use of Service Providers includes:

- -

·       Google: for website analytics

- -

·       Sentry: for -collection and processing of error and performance monitoring data -for Hardhat

- -

If you have any questions about the specific Service Providers we -currently use, please contact us at privacy@nomic.foundation or by -using the contact information set out at the bottom of this Privacy Policy.

- -

 

- -

Legal Compliance / Protection of the Public and Our Business / -Legitimate Interests 

- -

We will release personal and account information: to comply with a -subpoena, court order, legal process, or other legal requirement when we -believe in good faith that such disclosure is necessary to comply with the law; -to protect, establish, or exercise our legal rights or defend against legal -claims; when we believe doing so is reasonably necessary to prevent harm to an -individual; or take action regarding illegal activities, suspected fraud, -threats to our property, or violations of our legal terms.

- -

 

- -

We may also share your information during an organizational transaction -like a merger or distribution of our assets to a successor organization. If -such a transaction occurs, we will provide notification of any changes to -control of your information, as well as choices you may have.

- -

 

- -

Children’s Privacy

- -

The services are not intended for children under the age of 16. We do -not knowingly collect personal information from anyone under the age of -sixteen. If you are under the age of sixteen, your parent or guardian must -provide their consent for you to use the services.

- -

 

- -

Data Transfers

- -

Nomic Foundation provides a voluntary service and Clients can choose whether or not they wish to use it. Consequently, when -decided to use our Services you entitled Nomic Foundation to transfer your -personal data to the Services Providers for the purposes of the data processing -described in this Privacy Policy.

- -

 

- -

When your data is moved from its home country to another country, the -laws and rules that protect your personal information in the country to which -your information is transferred may be different from those in the country -where you reside. Because we offer our services to people in different -countries and use technical infrastructure based in different jurisdictions, we -may need to transfer your personal information across borders in order to -deliver our services.

- -

 

- -

Our Services Providers are obliged to protect data privacy at least to -the same extent as ourselves. We contractually ensure that the protection of -your personal data corresponds to the applicable laws by using the standard -contractual clauses to comply with the GDPR.

- -

 

- -

How Secure Is Your Information?

- -

We maintain administrative, technical, and physical safeguards designed -to protect the privacy and security of the information we maintain about you. -The connection between your computer and our website server is encrypted using -Secure Sockets Layer (SSL) software that encrypts that information.

- -

 

- -

We use a Digital Certificate and secure pages will be identified by a -padlock sign and “https://” in the address bar. Likewise, -all Hardhat error and performance monitoring data is transmitted over -HTTPS transport layer security (TLS)-secured connections.

- -

 

- -

However, no method of transmission or storage is 100% secure. As a -result, while we strive to protect your personal information, you acknowledge -that: (a) there are security and privacy limitations inherent to the Internet -which are beyond our control; and (b) security, integrity, and privacy of any and all information and data exchanged between you and -us through this Site cannot be guaranteed.

- -

 

- -

What Are Your Rights?

- -

Upon request, Nomic Foundation will provide Clients with information -about whether we hold any of their personal information (“Right to -confirmation”). In certain cases, subject to relevant legal rights, Clients -have the right to object to the processing of their personal information, to -request changes, corrections, or the deletion of their personal information, -and to obtain a copy of their personal information in an easily accessible -format (“Right to access”, “Right to object”, “Right to rectification”).

- -

 

- -

In order to do this, Clients can contact us using the contact -information set out at the bottom of this Privacy Policy. We will respond to -every request within a reasonable timeframe and may need to take reasonable -steps to confirm identity before proceeding.

- -

 

- -

You can also withdraw your consent to our processing of your information -and the use of our services, and/or delete your Client -account at any time, by using the contact information below to request that -your personal information be deleted (“right to be forgotten”).

- -

 

- -

If you are an EU resident and believe that our processing of your -personal data is contrary to the EU General Data Protection Regulation, you -have the right to lodge a complaint with the appropriate supervisory authority.

- -

 

- -

If you withdraw your consent to the use or sharing of your personal -information for the purposes set out in this policy, we may not be able to -provide you with our services. Please note that in certain cases we may -continue to process your information after you have withdrawn consent and -requested that we delete your information if we have a legal basis/need to do -so.

- -

 

- -

Data Retention

- -

For personal data under its control, Nomic Foundation will retain such -data only for as long as is necessary for the purposes set out in this policy, -or as needed to provide Clients with our services.

- -

 

- -

If a Client no longer wishes to use our -services then it may request deletion of its data at any time.

- -

 

- -

Notwithstanding the above, Nomic Foundation will retain and use Client -information to the extent necessary to comply with our legal obligations (for -example, if we are required to retain your information to comply with -applicable tax/revenue laws), resolve disputes, and enforce our agreements.

- -

 

- -

We may also retain log files for the purpose of internal analysis, for -site safety, security and fraud prevention, to improve site functionality, or -where we are legally required to retain them for longer time periods.

- -

 

- -

Contact Us

- -

If you have any questions, comments or suggestions about how we handle -personal information you can contact Nomic Foundation at privacy@nomic.foundation

- -

 

- -
- - - - diff --git a/docs/public/robots.txt b/docs/public/robots.txt deleted file mode 100644 index 1ce6c5d201..0000000000 --- a/docs/public/robots.txt +++ /dev/null @@ -1,9 +0,0 @@ -# * -User-agent: * -Allow: / - -# Host -Host: https://hardhat.org - -# Sitemaps -Sitemap: https://hardhat.org/sitemap.xml diff --git a/docs/public/sitemap.xml b/docs/public/sitemap.xml deleted file mode 100644 index 385e9b27d0..0000000000 --- a/docs/public/sitemap.xml +++ /dev/null @@ -1,4 +0,0 @@ - - -https://hardhat.org/sitemap-0.xml - \ No newline at end of file diff --git a/docs/redirects.config.js b/docs/redirects.config.js deleted file mode 100644 index 0d801afd81..0000000000 --- a/docs/redirects.config.js +++ /dev/null @@ -1,281 +0,0 @@ -const path = require("path"); - -/** - * This config allows to specify custom redirects. In order to place a new one, add an object with the following keys: - * { - * source: "/sourcePath/:sourceSlug", - destination: "/destPath/:sourceSlug", - permanent: true/false, - * } - * - * (:sourceSlug is optional) - * - * Read more about NextJS redirects https://nextjs.org/docs/api-reference/next.config.js/redirects - * - */ -const customRedirects = [ - // shortlinks - { - source: "/config", - destination: "/hardhat-runner/docs/config", - permanent: false - }, - { - source: "/plugins", - destination: "/hardhat-runner/plugins", - permanent: false - }, - { - source: "/getting-started", - destination: "/hardhat-runner/docs/getting-started#overview", - permanent: false - }, - { source: "/links/stack-traces", destination: "/", permanent: false }, - { - source: "/reportbug", - destination: "https://github.com/NomicFoundation/hardhat/issues/new", - permanent: false - }, - { - source: "/report-bug", - destination: "https://github.com/NomicFoundation/hardhat/issues/new", - permanent: false - }, - { - source: "/console-log", - destination: "/hardhat-network/#console.log", - permanent: false - }, - { - source: "/discord", - destination: "https://discord.gg/TETZs2KK4k", - permanent: false - }, - { - source: "/hre", - destination: "/advanced/hardhat-runtime-environment", - permanent: false - }, - { - source: "/nodejs-versions", - destination: "/reference/stability-guarantees#node.js-versions-support", - permanent: false - }, - { - source: "/verify-custom-networks", - destination: "/plugins/nomicfoundation-hardhat-verify#adding-support-for-other-networks", - permanent: false - }, - { - source: "/verify-multiple-networks", - destination: "plugins/nomicfoundation-hardhat-verify.html#multiple-api-keys-and-alternative-block-explorers", - permanent: false - }, - { - source: "/metamask-issue", - destination: "/hardhat-network/docs/metamask-issue", - permanent: false - }, - { - source: "/migrate-from-waffle", - destination: "/hardhat-runner/docs/guides/migrating-from-hardhat-waffle", - permanent: false - }, - { - source: "/custom-hardfork-history", - destination: "/hardhat-network/docs/guides/forking-other-networks.html#using-a-custom-hardfork-history", - permanent: false - }, - { - source: "/solidity-survey-2022", - destination: "https://cryptpad.fr/form/#/2/form/view/HuPIRv4gvziSV0dPV1SJncKzYJXTVc8LGCaMfLUoj2c/", - permanent: false - }, - { - source: "/solc-viair", - destination: "/hardhat-runner/docs/reference/solidity-support#support-for-ir-based-codegen", - permanent: false - }, - - // top-level component URLs - { - source: "/hardhat-runner", - destination: "/hardhat-runner/docs/getting-started#overview", - permanent: false - }, - { - source: "/hardhat-runner/docs", - destination: "/hardhat-runner/docs/getting-started#overview", - permanent: false - }, - { - source: "/hardhat-network", - destination: "/hardhat-network/docs/overview", - permanent: false - }, - { - source: "/hardhat-network/docs", - destination: "/hardhat-network/docs/overview", - permanent: false - }, - { - source: "/hardhat-vscode", - destination: "/hardhat-vscode/docs/overview", - permanent: false - }, - { - source: "/hardhat-vscode/docs", - destination: "/hardhat-vscode/docs/overview", - permanent: false - }, - { - source: "/hardhat-chai-matchers", - destination: "/hardhat-chai-matchers/docs/overview", - permanent: false - }, - { - source: "/hardhat-chai-matchers/docs", - destination: "/hardhat-chai-matchers/docs/overview", - permanent: false - }, - { - source: "/hardhat-network-helpers", - destination: "/hardhat-network-helpers/docs/overview", - permanent: false - }, - { - source: "/hardhat-network-helpers/docs", - destination: "/hardhat-network-helpers/docs/overview", - permanent: false - }, - - // legacy URLs - { - source: "/configuration", - destination: "/hardhat-runner/docs/config", - permanent: false - }, - { - source: "/guides/create-plugin", - destination: "/advanced/building-plugins", - permanent: false - }, - { - source: "/guides/mainnet-forking", - destination: "/hardhat-network/docs/guides/forking-other-networks", - permanent: false - }, - { - source: "/hardhat-network/guides/mainnet-forking", - destination: "/hardhat-network/docs/guides/forking-other-networks", - permanent: false - }, - { - source: "/hardhat-network/reference", - destination: "/hardhat-network/docs/reference", - permanent: false - }, - { - source: "/hardhat-network/explanation/mining-modes", - destination: "/hardhat-network/docs/explanation/mining-modes", - permanent: false - }, - { - source: "/troubleshooting/verbose-logging", - destination: "/hardhat-runner/docs/troubleshooting/verbose-logging", - permanent: false - }, - { - source: "/troubleshooting/common-problems", - destination: "/hardhat-runner/docs/troubleshooting/common-problems", - permanent: false - }, - { - source: "/errors", - destination: "/hardhat-runner/docs/errors", - permanent: false - }, - { - source: "/reference/stability-guarantees", - destination: "/hardhat-runner/docs/reference/stability-guarantees", - permanent: false - }, - { - source: "/reference/solidity-support", - destination: "/hardhat-runner/docs/reference/solidity-support", - permanent: false - }, - { - source: "/plugins/:slug", - destination: "/hardhat-runner/plugins/:slug", - permanent: false - }, - { - source: "/hardhat-runner/docs/guides/shorthand", - destination: "/hardhat-runner/docs/guides/command-line-completion", - permanent: false - }, - // guides redirects, exceptions go first - { - source: "/guides/:slug(hardhat-runtime-environment|create-task|scripts|building-plugins|vscode-tests)", - destination: "/hardhat-runner/docs/advanced/:slug", - permanent: false - }, - { - source: "/guides/:slug(waffle-testing|truffle-testing|truffle-migration|ganache-tests)", - destination: "/hardhat-runner/docs/other-guides/:slug", - permanent: false - }, - { - source: "/guides/parallel-tests", - destination: "/hardhat-runner/docs/guides/test-contracts#running-tests-in-parallel", - permanent: false - }, - { - source: "/guides/:slug", - destination: "/hardhat-runner/docs/guides/:slug", - permanent: false - }, - { - source: "/advanced/:slug", - destination: "/hardhat-runner/docs/advanced/:slug", - permanent: false - }, - { - source: "/chai-matchers", - destination: "/hardhat-chai-matchers", - permanent: false - }, - { - source: "/chai-matchers/:slug", - destination: "/hardhat-chai-matchers/docs/:slug", - permanent: false - }, - { - source: "/network-helpers", - destination: "/hardhat-network-helpers", - permanent: false - }, - { - source: "/network-helpers/:slug", - destination: "/hardhat-network-helpers/docs/:slug", - permanent: false - }, - { - source: "/hardhat-runner/plugins/nomiclabs-hardhat-etherscan", - destination: "/hardhat-runner/plugins/nomicfoundation-hardhat-verify", - permanent: false - }, - ...loadErrorRedirects() -]; - - -module.exports = customRedirects; - -function loadErrorRedirects() { - try { - return require(path.join(__dirname, "temp/error-redirects.json")); - } catch (e) { - return []; - } -} diff --git a/docs/scripts/prepare-error-list.ts b/docs/scripts/prepare-error-list.ts deleted file mode 100644 index 6b0725e70b..0000000000 --- a/docs/scripts/prepare-error-list.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { - ERROR_RANGES, - ErrorDescriptor, - ERRORS, - getErrorCode, -} from "../../packages/hardhat-core/src/internal/core/errors-list"; -import * as fs from "fs"; -import * as path from "path"; - -interface Redirect { - source: string; - destination: string; - permanent: boolean; -} - -let content = `# Hardhat errors -This section contains a list of all the possible errors you may encounter when -using Hardhat and an explanation of each of them.`; - -const errorRedirects: Redirect[] = []; - -for (const [rangeName, range] of Object.entries(ERROR_RANGES)) { - content += ` -## ${range.title} -`; - - for (const errorDescriptor of Object.values( - ERRORS[rangeName] - )) { - const errorCode = getErrorCode(errorDescriptor); - const title = `${errorCode}: ${errorDescriptor.title}`; - - content += `### [${title}](#${errorCode}) -${errorDescriptor.description} -`; - - const shortLink = errorCode; - // TODO: Fix anchor generation - const anchor = shortLink; - - errorRedirects.push({ - source: `/${shortLink}`, - destination: `/errors/#${anchor}`, - permanent: false, - }); - errorRedirects.push({ - source: `/${shortLink.toLowerCase()}`, - destination: `/errors/#${anchor}`, - permanent: false, - }); - } -} - -fs.writeFileSync( - path.join(__dirname, "../src/content/hardhat-runner/docs/errors/index.md"), - content, - "utf-8" -); -fs.writeFileSync( - path.join(__dirname, "../temp/error-redirects.json"), - JSON.stringify(errorRedirects, undefined, 2), - "utf-8" -); diff --git a/docs/src/assets/animation/desktop/he-eyes_open.svg b/docs/src/assets/animation/desktop/he-eyes_open.svg deleted file mode 100755 index 05858cd290..0000000000 --- a/docs/src/assets/animation/desktop/he-eyes_open.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/animation/desktop/he-head.svg b/docs/src/assets/animation/desktop/he-head.svg deleted file mode 100755 index bfdfe81a0a..0000000000 --- a/docs/src/assets/animation/desktop/he-head.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/animation/desktop/hero-back_texture-dark.svg b/docs/src/assets/animation/desktop/hero-back_texture-dark.svg deleted file mode 100644 index d5839a2711..0000000000 --- a/docs/src/assets/animation/desktop/hero-back_texture-dark.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/docs/src/assets/animation/desktop/hero-back_texture.svg b/docs/src/assets/animation/desktop/hero-back_texture.svg deleted file mode 100755 index 67885801fe..0000000000 --- a/docs/src/assets/animation/desktop/hero-back_texture.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/animation/desktop/hero-back_texture_reflect.svg b/docs/src/assets/animation/desktop/hero-back_texture_reflect.svg deleted file mode 100755 index c123d245ba..0000000000 --- a/docs/src/assets/animation/desktop/hero-back_texture_reflect.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/animation/desktop/mascots-ethereum_logo-dark.svg b/docs/src/assets/animation/desktop/mascots-ethereum_logo-dark.svg deleted file mode 100644 index 0c1a1a3e24..0000000000 --- a/docs/src/assets/animation/desktop/mascots-ethereum_logo-dark.svg +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/src/assets/animation/desktop/mascots-ethereum_logo.svg b/docs/src/assets/animation/desktop/mascots-ethereum_logo.svg deleted file mode 100755 index c3f254313a..0000000000 --- a/docs/src/assets/animation/desktop/mascots-ethereum_logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/animation/desktop/shadow-dark.svg b/docs/src/assets/animation/desktop/shadow-dark.svg deleted file mode 100644 index 3a0b0fb4b6..0000000000 --- a/docs/src/assets/animation/desktop/shadow-dark.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/docs/src/assets/animation/desktop/shadow.svg b/docs/src/assets/animation/desktop/shadow.svg deleted file mode 100755 index f07962b37d..0000000000 --- a/docs/src/assets/animation/desktop/shadow.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/animation/desktop/she-eyes_open.svg b/docs/src/assets/animation/desktop/she-eyes_open.svg deleted file mode 100755 index 284e9e246d..0000000000 --- a/docs/src/assets/animation/desktop/she-eyes_open.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/animation/desktop/she-head.svg b/docs/src/assets/animation/desktop/she-head.svg deleted file mode 100755 index fc0cbb4752..0000000000 --- a/docs/src/assets/animation/desktop/she-head.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/animation/mobile/ethereum_logo-dark.svg b/docs/src/assets/animation/mobile/ethereum_logo-dark.svg deleted file mode 100644 index 13c3631925..0000000000 --- a/docs/src/assets/animation/mobile/ethereum_logo-dark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/animation/mobile/ethereum_logo.svg b/docs/src/assets/animation/mobile/ethereum_logo.svg deleted file mode 100755 index f3a4a14b75..0000000000 --- a/docs/src/assets/animation/mobile/ethereum_logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/animation/mobile/he-eyes_open.svg b/docs/src/assets/animation/mobile/he-eyes_open.svg deleted file mode 100755 index 76560686ff..0000000000 --- a/docs/src/assets/animation/mobile/he-eyes_open.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/animation/mobile/mascots.svg b/docs/src/assets/animation/mobile/mascots.svg deleted file mode 100755 index d8ae41cfaf..0000000000 --- a/docs/src/assets/animation/mobile/mascots.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/animation/mobile/she-eyes_open.svg b/docs/src/assets/animation/mobile/she-eyes_open.svg deleted file mode 100755 index 2e5ba718ba..0000000000 --- a/docs/src/assets/animation/mobile/she-eyes_open.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/buidler-plugin-badge.svg b/docs/src/assets/buidler-plugin-badge.svg deleted file mode 100644 index 94f6a233e0..0000000000 --- a/docs/src/assets/buidler-plugin-badge.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/src/assets/ethereum-foundation-logo-dark.svg b/docs/src/assets/ethereum-foundation-logo-dark.svg deleted file mode 100644 index 3b4b4b89d5..0000000000 --- a/docs/src/assets/ethereum-foundation-logo-dark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/ethereum-foundation-logo.svg b/docs/src/assets/ethereum-foundation-logo.svg deleted file mode 100644 index ed3ff8cadd..0000000000 --- a/docs/src/assets/ethereum-foundation-logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Desktop/ExtensibleImage.svg b/docs/src/assets/feature-cards/Desktop/ExtensibleImage.svg deleted file mode 100644 index 00892f49e9..0000000000 --- a/docs/src/assets/feature-cards/Desktop/ExtensibleImage.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Desktop/ExtensibleImageDark.svg b/docs/src/assets/feature-cards/Desktop/ExtensibleImageDark.svg deleted file mode 100644 index c88fdb45d4..0000000000 --- a/docs/src/assets/feature-cards/Desktop/ExtensibleImageDark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Desktop/FastIterationImage.svg b/docs/src/assets/feature-cards/Desktop/FastIterationImage.svg deleted file mode 100644 index 3301ffa975..0000000000 --- a/docs/src/assets/feature-cards/Desktop/FastIterationImage.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Desktop/FastIterationImageDark.svg b/docs/src/assets/feature-cards/Desktop/FastIterationImageDark.svg deleted file mode 100644 index 797dfa6049..0000000000 --- a/docs/src/assets/feature-cards/Desktop/FastIterationImageDark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Desktop/FlexibilityImage.svg b/docs/src/assets/feature-cards/Desktop/FlexibilityImage.svg deleted file mode 100644 index 0a14d67d83..0000000000 --- a/docs/src/assets/feature-cards/Desktop/FlexibilityImage.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Desktop/FlexibilityImageDark.svg b/docs/src/assets/feature-cards/Desktop/FlexibilityImageDark.svg deleted file mode 100644 index de91a16a7f..0000000000 --- a/docs/src/assets/feature-cards/Desktop/FlexibilityImageDark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Desktop/SolidityImage.svg b/docs/src/assets/feature-cards/Desktop/SolidityImage.svg deleted file mode 100644 index 2bcdab2d6d..0000000000 --- a/docs/src/assets/feature-cards/Desktop/SolidityImage.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Desktop/SolidityImageDark.svg b/docs/src/assets/feature-cards/Desktop/SolidityImageDark.svg deleted file mode 100644 index 4cd45567f2..0000000000 --- a/docs/src/assets/feature-cards/Desktop/SolidityImageDark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Mobile/ExtensibleImage.svg b/docs/src/assets/feature-cards/Mobile/ExtensibleImage.svg deleted file mode 100644 index e9d1ea4055..0000000000 --- a/docs/src/assets/feature-cards/Mobile/ExtensibleImage.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Mobile/ExtensibleImageDark.svg b/docs/src/assets/feature-cards/Mobile/ExtensibleImageDark.svg deleted file mode 100644 index 0ae9045270..0000000000 --- a/docs/src/assets/feature-cards/Mobile/ExtensibleImageDark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Mobile/FastIterationImage.svg b/docs/src/assets/feature-cards/Mobile/FastIterationImage.svg deleted file mode 100644 index aefa3a6607..0000000000 --- a/docs/src/assets/feature-cards/Mobile/FastIterationImage.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Mobile/FastIterationImageDark.svg b/docs/src/assets/feature-cards/Mobile/FastIterationImageDark.svg deleted file mode 100644 index ce3155a2e4..0000000000 --- a/docs/src/assets/feature-cards/Mobile/FastIterationImageDark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Mobile/FlexibilityImage.svg b/docs/src/assets/feature-cards/Mobile/FlexibilityImage.svg deleted file mode 100644 index 690d63b2e3..0000000000 --- a/docs/src/assets/feature-cards/Mobile/FlexibilityImage.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Mobile/FlexibilityImageDark.svg b/docs/src/assets/feature-cards/Mobile/FlexibilityImageDark.svg deleted file mode 100644 index 1232f8b955..0000000000 --- a/docs/src/assets/feature-cards/Mobile/FlexibilityImageDark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Mobile/SolidityImage.svg b/docs/src/assets/feature-cards/Mobile/SolidityImage.svg deleted file mode 100644 index 6c48b7122e..0000000000 --- a/docs/src/assets/feature-cards/Mobile/SolidityImage.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/feature-cards/Mobile/SolidityImageDark.svg b/docs/src/assets/feature-cards/Mobile/SolidityImageDark.svg deleted file mode 100644 index 07976cb478..0000000000 --- a/docs/src/assets/feature-cards/Mobile/SolidityImageDark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/get-started/bl.svg b/docs/src/assets/get-started/bl.svg deleted file mode 100644 index fd30b639ae..0000000000 --- a/docs/src/assets/get-started/bl.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/src/assets/get-started/br.svg b/docs/src/assets/get-started/br.svg deleted file mode 100644 index 58d700585a..0000000000 --- a/docs/src/assets/get-started/br.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/docs/src/assets/hardhat-logo-dark.svg b/docs/src/assets/hardhat-logo-dark.svg deleted file mode 100644 index ea46980aa2..0000000000 --- a/docs/src/assets/hardhat-logo-dark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/hardhat-logo.svg b/docs/src/assets/hardhat-logo.svg deleted file mode 100644 index 3f1e1c310d..0000000000 --- a/docs/src/assets/hardhat-logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/homepage-assets/brett.jpg b/docs/src/assets/homepage-assets/brett.jpg deleted file mode 100644 index 43c0d78070..0000000000 Binary files a/docs/src/assets/homepage-assets/brett.jpg and /dev/null differ diff --git a/docs/src/assets/homepage-assets/brett.webp b/docs/src/assets/homepage-assets/brett.webp deleted file mode 100644 index 50413804ea..0000000000 Binary files a/docs/src/assets/homepage-assets/brett.webp and /dev/null differ diff --git a/docs/src/assets/homepage-assets/esteban.png b/docs/src/assets/homepage-assets/esteban.png deleted file mode 100644 index c43346a68c..0000000000 Binary files a/docs/src/assets/homepage-assets/esteban.png and /dev/null differ diff --git a/docs/src/assets/homepage-assets/esteban.webp b/docs/src/assets/homepage-assets/esteban.webp deleted file mode 100644 index caf8f8490b..0000000000 Binary files a/docs/src/assets/homepage-assets/esteban.webp and /dev/null differ diff --git a/docs/src/assets/homepage-assets/justin.jpg b/docs/src/assets/homepage-assets/justin.jpg deleted file mode 100644 index 52ed14ec0c..0000000000 Binary files a/docs/src/assets/homepage-assets/justin.jpg and /dev/null differ diff --git a/docs/src/assets/homepage-assets/justin.webp b/docs/src/assets/homepage-assets/justin.webp deleted file mode 100644 index 7aa14bb532..0000000000 Binary files a/docs/src/assets/homepage-assets/justin.webp and /dev/null differ diff --git a/docs/src/assets/homepage-assets/rahul.png b/docs/src/assets/homepage-assets/rahul.png deleted file mode 100644 index 8d12781172..0000000000 Binary files a/docs/src/assets/homepage-assets/rahul.png and /dev/null differ diff --git a/docs/src/assets/homepage-assets/rahul.webp b/docs/src/assets/homepage-assets/rahul.webp deleted file mode 100644 index 88d0421504..0000000000 Binary files a/docs/src/assets/homepage-assets/rahul.webp and /dev/null differ diff --git a/docs/src/assets/homepage-assets/reviews-block.ts b/docs/src/assets/homepage-assets/reviews-block.ts deleted file mode 100644 index ab94bd22ae..0000000000 --- a/docs/src/assets/homepage-assets/reviews-block.ts +++ /dev/null @@ -1,15 +0,0 @@ -import brett from "./brett.webp"; -import esteban from "./esteban.webp"; -import justin from "./justin.webp"; -import rahul from "./rahul.webp"; -import victor from "./victor.webp"; - -const images = { - brett, - esteban, - justin, - rahul, - victor, -}; - -export default images; diff --git a/docs/src/assets/homepage-assets/victor.png b/docs/src/assets/homepage-assets/victor.png deleted file mode 100644 index 65dd09cda5..0000000000 Binary files a/docs/src/assets/homepage-assets/victor.png and /dev/null differ diff --git a/docs/src/assets/homepage-assets/victor.webp b/docs/src/assets/homepage-assets/victor.webp deleted file mode 100644 index 2cafb0f9f6..0000000000 Binary files a/docs/src/assets/homepage-assets/victor.webp and /dev/null differ diff --git a/docs/src/assets/icons/carousel-arrow.tsx b/docs/src/assets/icons/carousel-arrow.tsx deleted file mode 100644 index f99455052e..0000000000 --- a/docs/src/assets/icons/carousel-arrow.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import * as React from "react"; -import { SVGProps } from "react"; - -const CarouselArrow = (props: SVGProps) => ( - - - -); - -export default CarouselArrow; diff --git a/docs/src/assets/icons/external-link-icon.tsx b/docs/src/assets/icons/external-link-icon.tsx deleted file mode 100644 index 2d0e99ca05..0000000000 --- a/docs/src/assets/icons/external-link-icon.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import * as React from "react"; -import { SVGProps } from "react"; - -const ExternalLinkIcon = (props: SVGProps) => ( - - - - - -); - -export default ExternalLinkIcon; diff --git a/docs/src/assets/icons/footer-arrow.tsx b/docs/src/assets/icons/footer-arrow.tsx deleted file mode 100644 index 5fd5689f94..0000000000 --- a/docs/src/assets/icons/footer-arrow.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import * as React from "react"; -import { SVGProps } from "react"; - -const FooterArrow = (props: SVGProps) => ( - - - - -); - -export default FooterArrow; diff --git a/docs/src/assets/icons/mobile-menu-arrow-back.tsx b/docs/src/assets/icons/mobile-menu-arrow-back.tsx deleted file mode 100644 index b0a0b8db1a..0000000000 --- a/docs/src/assets/icons/mobile-menu-arrow-back.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import * as React from "react"; -import { SVGProps } from "react"; - -const MobileMenuArrowBack = (props: SVGProps) => ( - - - - -); - -export default MobileMenuArrowBack; diff --git a/docs/src/assets/icons/mobile-menu-arrow-forward.tsx b/docs/src/assets/icons/mobile-menu-arrow-forward.tsx deleted file mode 100644 index 5a2b835991..0000000000 --- a/docs/src/assets/icons/mobile-menu-arrow-forward.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import * as React from "react"; -import { SVGProps } from "react"; - -const MobileMenuArrowForward = (props: SVGProps) => ( - - - - -); - -export default MobileMenuArrowForward; diff --git a/docs/src/assets/icons/theme-switcher-dark.svg b/docs/src/assets/icons/theme-switcher-dark.svg deleted file mode 100644 index 67e0d3449f..0000000000 --- a/docs/src/assets/icons/theme-switcher-dark.svg +++ /dev/null @@ -1,2 +0,0 @@ - - \ No newline at end of file diff --git a/docs/src/assets/icons/theme-switcher.svg b/docs/src/assets/icons/theme-switcher.svg deleted file mode 100644 index 205b7b8b0c..0000000000 --- a/docs/src/assets/icons/theme-switcher.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/tools/ignition-dark.tsx b/docs/src/assets/tools/ignition-dark.tsx deleted file mode 100644 index 8ecaa87dd7..0000000000 --- a/docs/src/assets/tools/ignition-dark.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import * as React from "react"; -import { SVGProps } from "react"; - -const IgnitionIconDark = (props: SVGProps) => ( - - - - - - - - - - - - - - - - - - - - - - - -); - -export default IgnitionIconDark; diff --git a/docs/src/assets/tools/ignition.tsx b/docs/src/assets/tools/ignition.tsx deleted file mode 100644 index d6ef6f5ebf..0000000000 --- a/docs/src/assets/tools/ignition.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import * as React from "react"; -import { SVGProps, memo } from "react"; - -const IgnitionIcon = (props: SVGProps) => ( - - - - - - - - - - - - - - - - - - - - - - - -); - -export default memo(IgnitionIcon); diff --git a/docs/src/assets/tools/index.ts b/docs/src/assets/tools/index.ts deleted file mode 100644 index 9e314cf054..0000000000 --- a/docs/src/assets/tools/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -import RunnerIcon from "./runner"; -import IgnitionIcon from "./ignition"; -import NetworkIcon from "./network"; -import SolidityIcon from "./solidity"; -import RunnerIconDark from "./runner-dark"; -import IgnitionIconDark from "./ignition-dark"; -import NetworkIconDark from "./network-dark"; - -const ToolsIcons = { - RunnerIcon, - IgnitionIcon, - NetworkIcon, - SolidityIcon, - RunnerIconDark, - IgnitionIconDark, - NetworkIconDark, -}; - -export default ToolsIcons; diff --git a/docs/src/assets/tools/network-dark.tsx b/docs/src/assets/tools/network-dark.tsx deleted file mode 100644 index 5e86d1f154..0000000000 --- a/docs/src/assets/tools/network-dark.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import * as React from "react"; -import { SVGProps } from "react"; - -const NetworkIconDark = (props: SVGProps) => ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -); - -export default NetworkIconDark; diff --git a/docs/src/assets/tools/network.tsx b/docs/src/assets/tools/network.tsx deleted file mode 100644 index e9f66729c1..0000000000 --- a/docs/src/assets/tools/network.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import * as React from "react"; -import { SVGProps, memo } from "react"; - -const NetworkIcon = (props: SVGProps) => ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -); - -export default memo(NetworkIcon); diff --git a/docs/src/assets/tools/runner-dark.tsx b/docs/src/assets/tools/runner-dark.tsx deleted file mode 100644 index 461657cc75..0000000000 --- a/docs/src/assets/tools/runner-dark.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import * as React from "react"; -import { SVGProps } from "react"; - -const RunnerIconDark = (props: SVGProps) => ( - - - - - - - - - - - - - - - - - - - - - - - - - - - -); - -export default RunnerIconDark; diff --git a/docs/src/assets/tools/runner.tsx b/docs/src/assets/tools/runner.tsx deleted file mode 100644 index baefee40b1..0000000000 --- a/docs/src/assets/tools/runner.tsx +++ /dev/null @@ -1,77 +0,0 @@ -import * as React from "react"; -import { SVGProps, memo } from "react"; - -const RunnerIcon = (props: SVGProps) => ( - - - - - - - - - - - - - - - - - - - - - - - - - -); - -export default memo(RunnerIcon); diff --git a/docs/src/assets/tools/solidity-dark.tsx b/docs/src/assets/tools/solidity-dark.tsx deleted file mode 100644 index bfc692fe22..0000000000 --- a/docs/src/assets/tools/solidity-dark.tsx +++ /dev/null @@ -1,138 +0,0 @@ -import * as React from "react"; -import { SVGProps } from "react"; - -const SolidityIconDark = (props: SVGProps) => ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -); - -export default SolidityIconDark; diff --git a/docs/src/assets/tools/solidity.tsx b/docs/src/assets/tools/solidity.tsx deleted file mode 100644 index 468a055af9..0000000000 --- a/docs/src/assets/tools/solidity.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import * as React from "react"; -import { SVGProps } from "react"; - -const SolidityIcon = (props: SVGProps) => ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -); - -export default SolidityIcon; diff --git a/docs/src/assets/trustedTeamsLogos/1inch.png b/docs/src/assets/trustedTeamsLogos/1inch.png deleted file mode 100644 index 49a90acbbf..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/1inch.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/aave.png b/docs/src/assets/trustedTeamsLogos/aave.png deleted file mode 100644 index 0f4898f106..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/aave.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/aragonOne.png b/docs/src/assets/trustedTeamsLogos/aragonOne.png deleted file mode 100644 index 9667db1320..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/aragonOne.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/augur.png b/docs/src/assets/trustedTeamsLogos/augur.png deleted file mode 100644 index 95746d6340..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/augur.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/balancer.png b/docs/src/assets/trustedTeamsLogos/balancer.png deleted file mode 100644 index 496611b8e9..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/balancer.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/celer.png b/docs/src/assets/trustedTeamsLogos/celer.png deleted file mode 100644 index 546c50cf73..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/celer.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/celo.png b/docs/src/assets/trustedTeamsLogos/celo.png deleted file mode 100644 index e90aab53bc..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/celo.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/chainlink.png b/docs/src/assets/trustedTeamsLogos/chainlink.png deleted file mode 100644 index 0f75314582..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/chainlink.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/connext.png b/docs/src/assets/trustedTeamsLogos/connext.png deleted file mode 100644 index e21e946510..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/connext.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/1inch-dark.png b/docs/src/assets/trustedTeamsLogos/dark/1inch-dark.png deleted file mode 100644 index 49a90acbbf..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/1inch-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/aave-dark.png b/docs/src/assets/trustedTeamsLogos/dark/aave-dark.png deleted file mode 100644 index 0f4898f106..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/aave-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/aragonOne-dark.png b/docs/src/assets/trustedTeamsLogos/dark/aragonOne-dark.png deleted file mode 100644 index 9667db1320..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/aragonOne-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/augur-dark.png b/docs/src/assets/trustedTeamsLogos/dark/augur-dark.png deleted file mode 100644 index 95746d6340..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/augur-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/balancer-dark.png b/docs/src/assets/trustedTeamsLogos/dark/balancer-dark.png deleted file mode 100644 index 496611b8e9..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/balancer-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/celer-dark.png b/docs/src/assets/trustedTeamsLogos/dark/celer-dark.png deleted file mode 100644 index 546c50cf73..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/celer-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/celo-dark.png b/docs/src/assets/trustedTeamsLogos/dark/celo-dark.png deleted file mode 100644 index e90aab53bc..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/celo-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/chainlink-dark.png b/docs/src/assets/trustedTeamsLogos/dark/chainlink-dark.png deleted file mode 100644 index 0f75314582..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/chainlink-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/connext-dark.png b/docs/src/assets/trustedTeamsLogos/dark/connext-dark.png deleted file mode 100644 index e21e946510..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/connext-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/decentraland-dark.png b/docs/src/assets/trustedTeamsLogos/dark/decentraland-dark.png deleted file mode 100644 index f1de5ccbda..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/decentraland-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/dharma-dark.png b/docs/src/assets/trustedTeamsLogos/dark/dharma-dark.png deleted file mode 100644 index e7f66884c7..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/dharma-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/ens-dark.png b/docs/src/assets/trustedTeamsLogos/dark/ens-dark.png deleted file mode 100644 index c94a828f81..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/ens-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/gnosis-dark.png b/docs/src/assets/trustedTeamsLogos/dark/gnosis-dark.png deleted file mode 100644 index d798f682e6..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/gnosis-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/hegic-dark.png b/docs/src/assets/trustedTeamsLogos/dark/hegic-dark.png deleted file mode 100644 index cd83c2da51..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/hegic-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/horizon-dark.png b/docs/src/assets/trustedTeamsLogos/dark/horizon-dark.png deleted file mode 100644 index 802084f819..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/horizon-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/instadapp-dark.png b/docs/src/assets/trustedTeamsLogos/dark/instadapp-dark.png deleted file mode 100644 index b9578d1334..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/instadapp-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/kleros-dark.png b/docs/src/assets/trustedTeamsLogos/dark/kleros-dark.png deleted file mode 100644 index 9eef23717c..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/kleros-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/kyber-dark.png b/docs/src/assets/trustedTeamsLogos/dark/kyber-dark.png deleted file mode 100644 index 2d28e8108e..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/kyber-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/livepeer-dark.png b/docs/src/assets/trustedTeamsLogos/dark/livepeer-dark.png deleted file mode 100644 index ef44a64604..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/livepeer-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/lodestar-dark.png b/docs/src/assets/trustedTeamsLogos/dark/lodestar-dark.png deleted file mode 100644 index 9be21c1626..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/lodestar-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/loopring-dark.png b/docs/src/assets/trustedTeamsLogos/dark/loopring-dark.png deleted file mode 100644 index ac2834561d..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/loopring-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/mainframe-dark.png b/docs/src/assets/trustedTeamsLogos/dark/mainframe-dark.png deleted file mode 100644 index 24774411e8..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/mainframe-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/melon-dark.png b/docs/src/assets/trustedTeamsLogos/dark/melon-dark.png deleted file mode 100644 index 087dc82518..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/melon-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/molochdao-dark.png b/docs/src/assets/trustedTeamsLogos/dark/molochdao-dark.png deleted file mode 100644 index e1c5ae1155..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/molochdao-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/mstable-dark.png b/docs/src/assets/trustedTeamsLogos/dark/mstable-dark.png deleted file mode 100644 index 8096265b87..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/mstable-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/mycrypto-dark.png b/docs/src/assets/trustedTeamsLogos/dark/mycrypto-dark.png deleted file mode 100644 index 16d00e4b46..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/mycrypto-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/openGSN-dark.png b/docs/src/assets/trustedTeamsLogos/dark/openGSN-dark.png deleted file mode 100644 index 2747ff68eb..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/openGSN-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/openzeppelin-dark.png b/docs/src/assets/trustedTeamsLogos/dark/openzeppelin-dark.png deleted file mode 100644 index 4722d6d035..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/openzeppelin-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/optimism-dark.png b/docs/src/assets/trustedTeamsLogos/dark/optimism-dark.png deleted file mode 100644 index 50d332f6ae..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/optimism-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/opyn-dark.png b/docs/src/assets/trustedTeamsLogos/dark/opyn-dark.png deleted file mode 100644 index 6607c22d8d..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/opyn-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/pieDAO-dark.png b/docs/src/assets/trustedTeamsLogos/dark/pieDAO-dark.png deleted file mode 100644 index 6828cd13cd..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/pieDAO-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/poap-dark.png b/docs/src/assets/trustedTeamsLogos/dark/poap-dark.png deleted file mode 100644 index d908dbed0f..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/poap-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/pool-dark.png b/docs/src/assets/trustedTeamsLogos/dark/pool-dark.png deleted file mode 100644 index 210cca6d83..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/pool-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/reflexer-dark.png b/docs/src/assets/trustedTeamsLogos/dark/reflexer-dark.png deleted file mode 100644 index 2a01d8819c..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/reflexer-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/set-dark.png b/docs/src/assets/trustedTeamsLogos/dark/set-dark.png deleted file mode 100644 index db757652c7..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/set-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/skale-dark.png b/docs/src/assets/trustedTeamsLogos/dark/skale-dark.png deleted file mode 100644 index b94c9d3db1..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/skale-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/status-dark.png b/docs/src/assets/trustedTeamsLogos/dark/status-dark.png deleted file mode 100644 index e530e495bd..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/status-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/sushiswap-dark.png b/docs/src/assets/trustedTeamsLogos/dark/sushiswap-dark.png deleted file mode 100644 index b91f3b44ab..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/sushiswap-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/synthetix-dark.png b/docs/src/assets/trustedTeamsLogos/dark/synthetix-dark.png deleted file mode 100644 index 6aa21e66f3..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/synthetix-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/uma-dark.png b/docs/src/assets/trustedTeamsLogos/dark/uma-dark.png deleted file mode 100644 index 97dee74c97..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/uma-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/uniswap-dark.png b/docs/src/assets/trustedTeamsLogos/dark/uniswap-dark.png deleted file mode 100644 index 4371ecec15..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/uniswap-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/unlock-dark.png b/docs/src/assets/trustedTeamsLogos/dark/unlock-dark.png deleted file mode 100644 index 7220b93ace..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/unlock-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/yearn-dark.png b/docs/src/assets/trustedTeamsLogos/dark/yearn-dark.png deleted file mode 100644 index df580de62a..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/yearn-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dark/zksync-dark.png b/docs/src/assets/trustedTeamsLogos/dark/zksync-dark.png deleted file mode 100644 index c8697d5566..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dark/zksync-dark.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/decentraland.png b/docs/src/assets/trustedTeamsLogos/decentraland.png deleted file mode 100644 index f1de5ccbda..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/decentraland.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/dharma.png b/docs/src/assets/trustedTeamsLogos/dharma.png deleted file mode 100644 index e7f66884c7..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/dharma.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/ens.png b/docs/src/assets/trustedTeamsLogos/ens.png deleted file mode 100644 index c94a828f81..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/ens.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/gnosis.png b/docs/src/assets/trustedTeamsLogos/gnosis.png deleted file mode 100644 index d798f682e6..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/gnosis.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/hegic.png b/docs/src/assets/trustedTeamsLogos/hegic.png deleted file mode 100644 index cd83c2da51..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/hegic.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/horizon.png b/docs/src/assets/trustedTeamsLogos/horizon.png deleted file mode 100644 index 802084f819..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/horizon.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/instadapp.png b/docs/src/assets/trustedTeamsLogos/instadapp.png deleted file mode 100644 index b9578d1334..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/instadapp.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/kleros.png b/docs/src/assets/trustedTeamsLogos/kleros.png deleted file mode 100644 index 9eef23717c..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/kleros.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/kyber.png b/docs/src/assets/trustedTeamsLogos/kyber.png deleted file mode 100644 index 2d28e8108e..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/kyber.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/livepeer.png b/docs/src/assets/trustedTeamsLogos/livepeer.png deleted file mode 100644 index ef44a64604..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/livepeer.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/lodestar.png b/docs/src/assets/trustedTeamsLogos/lodestar.png deleted file mode 100644 index 9be21c1626..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/lodestar.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/logos.ts b/docs/src/assets/trustedTeamsLogos/logos.ts deleted file mode 100644 index 0275075713..0000000000 --- a/docs/src/assets/trustedTeamsLogos/logos.ts +++ /dev/null @@ -1,342 +0,0 @@ -/* eslint global-require: "off" */ - -export const TrustedTeamsLogos = [ - { - img: require("./lodestar.png"), - alt: "Lodestar company logo", - }, - { - img: require("./connext.png"), - alt: "Connext company logo", - }, - { img: require("./set.png"), alt: "Set company logo" }, - { - img: require("./opyn.png"), - alt: "Opyn company logo", - }, - { - img: require("./balancer.png"), - alt: "Balancer company logo", - }, - { - img: require("./molochdao.png"), - alt: "Molochdao company logo", - }, - { - img: require("./kyber.png"), - alt: "Kyber company logo", - }, - { - img: require("./openzeppelin.png"), - alt: "Openzepellin company logo", - }, - { - img: require("./pieDAO.png"), - alt: "PieDAO company logo", - }, - { - img: require("./optimism.png"), - alt: "Optimism company logo", - }, - { - img: require("./decentraland.png"), - alt: "Decentraland company logo", - }, - { - img: require("./aragonOne.png"), - alt: "ARAGON ONE company logo", - }, - { - img: require("./kleros.png"), - alt: "Kleros company logo", - }, - { - img: require("./mstable.png"), - alt: "M STABLE company logo", - }, - { - img: require("./celo.png"), - alt: "Celo company logo", - }, - { - img: require("./mycrypto.png"), - alt: "MyCrypto company logo", - }, - { - img: require("./poap.png"), - alt: "Poap company logo", - }, - { - img: require("./melon.png"), - alt: "Melon company logo", - }, - { - img: require("./openGSN.png"), - alt: "OpenGSN company logo", - }, - { - img: require("./unlock.png"), - alt: "Unlock company logo", - }, - { - img: require("./status.png"), - alt: "Status company logo", - }, - { - img: require("./pool.png"), - alt: "Pool company logo", - }, - { - img: require("./instadapp.png"), - alt: "Instadapp company logo", - }, - { - img: require("./mainframe.png"), - alt: "Mainframe company logo", - }, - { - img: require("./horizon.png"), - alt: "Horizon company logo", - }, - { - img: require("./aave.png"), - alt: "Aave company logo", - }, - { - img: require("./skale.png"), - alt: "Skale company logo", - }, - { - img: require("./synthetix.png"), - alt: "Synthetix company logo", - }, - { - img: require("./celer.png"), - alt: "Celer company logo", - }, - { img: require("./uma.png"), alt: "Uma company logo" }, - { - img: require("./chainlink.png"), - alt: "Chainlink company logo", - }, - { - img: require("./gnosis.png"), - alt: "Gnosis company logo", - }, - { - img: require("./sushiswap.png"), - alt: "Sushiswap company logo", - }, - { img: require("./ens.png"), alt: "ENS company logo" }, - { - img: require("./yearn.png"), - alt: "Yearn company logo", - }, - { - img: require("./reflexer.png"), - alt: "Reflexer company logo", - }, - { - img: require("./dharma.png"), - alt: "Dharma company logo", - }, - { - img: require("./1inch.png"), - alt: "1inch company logo", - }, - { - img: require("./uniswap.png"), - alt: "Uniswap company logo", - }, - { - img: require("./hegic.png"), - alt: "Hegic company logo", - }, - { - img: require("./augur.png"), - alt: "Augur company logo", - }, - { - img: require("./zksync.png"), - alt: "zkSync company logo", - }, - { - img: require("./livepeer.png"), - alt: "Livepeer company logo", - }, - { - img: require("./loopring.png"), - alt: "Loopring company logo", - }, -]; - -// TODO-LANDING-DARK: Replace images below with correct dark themed images. -export const TrustedTeamsLogosDark = [ - { - img: require("./dark/lodestar-dark.png"), - alt: "Lodestar company logo", - }, - { - img: require("./dark/connext-dark.png"), - alt: "Connext company logo", - }, - { img: require("./dark/set-dark.png"), alt: "Set company logo" }, - { - img: require("./dark/opyn-dark.png"), - alt: "Opyn company logo", - }, - { - img: require("./dark/balancer-dark.png"), - alt: "Balancer company logo", - }, - { - img: require("./dark/molochdao-dark.png"), - alt: "Molochdao company logo", - }, - { - img: require("./dark/kyber-dark.png"), - alt: "Kyber company logo", - }, - { - img: require("./dark/openzeppelin-dark.png"), - alt: "Openzepellin company logo", - }, - { - img: require("./dark/pieDAO-dark.png"), - alt: "PieDAO company logo", - }, - { - img: require("./dark/optimism-dark.png"), - alt: "Optimism company logo", - }, - { - img: require("./dark/decentraland-dark.png"), - alt: "Decentraland company logo", - }, - { - img: require("./dark/aragonOne-dark.png"), - alt: "ARAGON ONE company logo", - }, - { - img: require("./dark/kleros-dark.png"), - alt: "Kleros company logo", - }, - { - img: require("./dark/mstable-dark.png"), - alt: "M STABLE company logo", - }, - { - img: require("./dark/celo-dark.png"), - alt: "Celo company logo", - }, - { - img: require("./dark/mycrypto-dark.png"), - alt: "MyCrypto company logo", - }, - { - img: require("./dark/poap-dark.png"), - alt: "Poap company logo", - }, - { - img: require("./dark/melon-dark.png"), - alt: "Melon company logo", - }, - { - img: require("./dark/openGSN-dark.png"), - alt: "OpenGSN company logo", - }, - { - img: require("./dark/unlock-dark.png"), - alt: "Unlock company logo", - }, - { - img: require("./dark/status-dark.png"), - alt: "Status company logo", - }, - { - img: require("./dark/pool-dark.png"), - alt: "Pool company logo", - }, - { - img: require("./dark/instadapp-dark.png"), - alt: "Instadapp company logo", - }, - { - img: require("./dark/mainframe-dark.png"), - alt: "Mainframe company logo", - }, - { - img: require("./dark/horizon-dark.png"), - alt: "Horizon company logo", - }, - { - img: require("./dark/aave-dark.png"), - alt: "Aave company logo", - }, - { - img: require("./dark/skale-dark.png"), - alt: "Skale company logo", - }, - { - img: require("./dark/synthetix-dark.png"), - alt: "Synthetix company logo", - }, - { - img: require("./dark/celer-dark.png"), - alt: "Celer company logo", - }, - { img: require("./dark/uma-dark.png"), alt: "Uma company logo" }, - { - img: require("./dark/chainlink-dark.png"), - alt: "Chainlink company logo", - }, - { - img: require("./dark/gnosis-dark.png"), - alt: "Gnosis company logo", - }, - { - img: require("./dark/sushiswap-dark.png"), - alt: "Sushiswap company logo", - }, - { img: require("./dark/ens-dark.png"), alt: "ENS company logo" }, - { - img: require("./dark/yearn-dark.png"), - alt: "Yearn company logo", - }, - { - img: require("./dark/reflexer-dark.png"), - alt: "Reflexer company logo", - }, - { - img: require("./dark/dharma-dark.png"), - alt: "Dharma company logo", - }, - { - img: require("./dark/1inch-dark.png"), - alt: "1inch company logo", - }, - { - img: require("./dark/uniswap-dark.png"), - alt: "Uniswap company logo", - }, - { - img: require("./dark/hegic-dark.png"), - alt: "Hegic company logo", - }, - { - img: require("./dark/augur-dark.png"), - alt: "Augur company logo", - }, - { - img: require("./dark/zksync-dark.png"), - alt: "zkSync company logo", - }, - { - img: require("./dark/livepeer-dark.png"), - alt: "Livepeer company logo", - }, - { - img: require("./dark/loopring-dark.png"), - alt: "Loopring company logo", - }, -]; diff --git a/docs/src/assets/trustedTeamsLogos/loopring.png b/docs/src/assets/trustedTeamsLogos/loopring.png deleted file mode 100644 index ac2834561d..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/loopring.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/mainframe.png b/docs/src/assets/trustedTeamsLogos/mainframe.png deleted file mode 100644 index 24774411e8..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/mainframe.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/melon.png b/docs/src/assets/trustedTeamsLogos/melon.png deleted file mode 100644 index 087dc82518..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/melon.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/molochdao.png b/docs/src/assets/trustedTeamsLogos/molochdao.png deleted file mode 100644 index e1c5ae1155..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/molochdao.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/mstable.png b/docs/src/assets/trustedTeamsLogos/mstable.png deleted file mode 100644 index 8096265b87..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/mstable.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/mycrypto.png b/docs/src/assets/trustedTeamsLogos/mycrypto.png deleted file mode 100644 index 16d00e4b46..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/mycrypto.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/openGSN.png b/docs/src/assets/trustedTeamsLogos/openGSN.png deleted file mode 100644 index 2747ff68eb..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/openGSN.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/openzeppelin.png b/docs/src/assets/trustedTeamsLogos/openzeppelin.png deleted file mode 100644 index 4722d6d035..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/openzeppelin.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/optimism.png b/docs/src/assets/trustedTeamsLogos/optimism.png deleted file mode 100644 index 50d332f6ae..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/optimism.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/opyn.png b/docs/src/assets/trustedTeamsLogos/opyn.png deleted file mode 100644 index 6607c22d8d..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/opyn.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/pieDAO.png b/docs/src/assets/trustedTeamsLogos/pieDAO.png deleted file mode 100644 index 6828cd13cd..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/pieDAO.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/poap.png b/docs/src/assets/trustedTeamsLogos/poap.png deleted file mode 100644 index d908dbed0f..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/poap.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/pool.png b/docs/src/assets/trustedTeamsLogos/pool.png deleted file mode 100644 index 210cca6d83..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/pool.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/reflexer.png b/docs/src/assets/trustedTeamsLogos/reflexer.png deleted file mode 100644 index 2a01d8819c..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/reflexer.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/set.png b/docs/src/assets/trustedTeamsLogos/set.png deleted file mode 100644 index db757652c7..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/set.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/skale.png b/docs/src/assets/trustedTeamsLogos/skale.png deleted file mode 100644 index b94c9d3db1..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/skale.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/status.png b/docs/src/assets/trustedTeamsLogos/status.png deleted file mode 100644 index e530e495bd..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/status.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/sushiswap.png b/docs/src/assets/trustedTeamsLogos/sushiswap.png deleted file mode 100644 index b91f3b44ab..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/sushiswap.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/synthetix.png b/docs/src/assets/trustedTeamsLogos/synthetix.png deleted file mode 100644 index 6aa21e66f3..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/synthetix.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/uma.png b/docs/src/assets/trustedTeamsLogos/uma.png deleted file mode 100644 index 97dee74c97..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/uma.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/uniswap.png b/docs/src/assets/trustedTeamsLogos/uniswap.png deleted file mode 100644 index 4371ecec15..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/uniswap.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/unlock.png b/docs/src/assets/trustedTeamsLogos/unlock.png deleted file mode 100644 index 7220b93ace..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/unlock.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/yearn.png b/docs/src/assets/trustedTeamsLogos/yearn.png deleted file mode 100644 index df580de62a..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/yearn.png and /dev/null differ diff --git a/docs/src/assets/trustedTeamsLogos/zksync.png b/docs/src/assets/trustedTeamsLogos/zksync.png deleted file mode 100644 index c8697d5566..0000000000 Binary files a/docs/src/assets/trustedTeamsLogos/zksync.png and /dev/null differ diff --git a/docs/src/assets/vibrantCommunityImage.svg b/docs/src/assets/vibrantCommunityImage.svg deleted file mode 100644 index b3081809de..0000000000 --- a/docs/src/assets/vibrantCommunityImage.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/assets/vibrantCommunityImageDark.svg b/docs/src/assets/vibrantCommunityImageDark.svg deleted file mode 100644 index f60c58fff0..0000000000 --- a/docs/src/assets/vibrantCommunityImageDark.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/docs/src/components/CookiePopUp.stories.tsx b/docs/src/components/CookiePopUp.stories.tsx deleted file mode 100644 index 87e86bf50a..0000000000 --- a/docs/src/components/CookiePopUp.stories.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from "react"; - -import CookiePopUp from "./CookiePopUp"; -import { GDPR } from "../config"; - -export default { - title: "Common/Cookies", -}; - -export const Cookie = () => ( - null} onReject={() => null} /> -); diff --git a/docs/src/components/CookiePopUp.tsx b/docs/src/components/CookiePopUp.tsx deleted file mode 100644 index 1c8f812dad..0000000000 --- a/docs/src/components/CookiePopUp.tsx +++ /dev/null @@ -1,159 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../themes"; -import CTA from "./ui/CTA"; - -const Container = styled.section` - z-index: 100; - position: fixed; - bottom: 24px; - right: 0px; - width: auto; - padding: 16px 20px; - border-radius: 4px; - margin: 0px 24px; - background-color: ${tm(({ colors }) => colors.cookiePopUpBackground)}; - box-shadow: 0px 6px 50px ${tm(({ colors }) => colors.cookieShadow)}; - filter: drop-shadow( - 0px 6px 50px ${tm(({ colors }) => colors.cookieDropShadow)} - ); - display: flex; - flex-direction: column; - max-width: 332px; - ${media.md} { - width: 332spx; - margin: 0px 24px; - left: unset; - } - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.cookiePopUpBackground)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.cookiePopUpBackground)}; - } - } -`; - -const Title = styled.h3` - font-weight: 400; - font-size: 12px; - line-height: 24px; - letter-spacing: 0.2em; - text-transform: uppercase; - color: ${tm(({ colors }) => colors.neutral900)}; - mix-blend-mode: normal; - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } -`; - -const Text = styled.p` - font-family: ChivoLight, sans-serif; - margin-top: 16px; - font-weight: 400; - font-size: 12px; - line-height: 140%; - color: ${tm(({ colors }) => colors.cookieTextColor)}; - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.cookieTextColor)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.cookieTextColor)}; - } - } -`; - -const ButtonsContainer = styled.div` - display: flex; - margin-top: 16px; - - & .secondary { - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.cookieTextColor)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.cookieTextColor)}; - } - } - } -`; - -const CTAWrapper = styled.div` - & > button { - font-size: 10px; - padding: 10px 12px; - height: 32px; - } - &:first-child { - margin-right: 16px; - } -`; - -const ReadMoreLink = styled.a` - font-family: ChivoRegular, sans-serif; - color: ${tm(({ colors }) => colors.neutral900)}; - font-weight: 800; - margin-left: 6px; - cursor: pointer; - &:hover { - opacity: 0.8; - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } -`; - -interface Props { - title: string; - text: string; - readMoreHref: string; - onAccept: () => void; - onReject: () => void; -} - -const CookiePopUp = ({ - title, - text, - readMoreHref, - onAccept, - onReject, -}: Props) => { - return ( - - {title} - - {text} - Read More - - - - - Reject all - - - - Accept all - - - - ); -}; - -export default CookiePopUp; diff --git a/docs/src/components/DesktopAnimation.tsx b/docs/src/components/DesktopAnimation.tsx deleted file mode 100644 index 4539e0ea7f..0000000000 --- a/docs/src/components/DesktopAnimation.tsx +++ /dev/null @@ -1,252 +0,0 @@ -import React from "react"; -import Image from "next/image"; -import { styled } from "linaria/react"; - -import heroBackTextureReflect from "../assets/animation/desktop/hero-back_texture_reflect.svg"; -import heroBackTexture from "../assets/animation/desktop/hero-back_texture.svg"; -import heroBackTextureDark from "../assets/animation/desktop/hero-back_texture-dark.svg"; -import mascotsEthereumLogo from "../assets/animation/desktop/mascots-ethereum_logo.svg"; -import mascotsEthereumLogoDark from "../assets/animation/desktop/mascots-ethereum_logo-dark.svg"; -import heHead from "../assets/animation/desktop/he-head.svg"; -import sheHead from "../assets/animation/desktop/she-head.svg"; -import heEyesOpen from "../assets/animation/desktop/he-eyes_open.svg"; -import sheEyesOpen from "../assets/animation/desktop/she-eyes_open.svg"; -import shadow from "../assets/animation/desktop/shadow.svg"; -import shadowDark from "../assets/animation/desktop/shadow-dark.svg"; -import { media, tmSelectors } from "../themes"; - -const AnimationContainer = styled.section` - display: none; - width: 580px; - height: 685px; - position: absolute; - ${media.md} { - display: block; - left: -72px; - } - ${media.lg} { - left: 0px; - } - - & > .bounce { - background-color: transparent; - height: 100%; - width: 100%; - & > span { - position: absolute; - } - animation: bounce 8s linear infinite; - } - - & > span { - position: absolute; - z-index: 1; - } - & .back-texture { - z-index: 0; - top: -100px; - left: 50px; - } - - & .back-reflect { - z-index: 0; - ${tmSelectors.dark} { - display: none; - } - ${media.mqDark} { - ${tmSelectors.auto} { - display: none; - } - } - } - - & .mascots-ethereum-logo { - top: 0; - left: 120px; - } - & .he-head { - top: 130px; - left: 293px; - animation: headShake 8s linear infinite; - animation-delay: 1s; - } - & .he-eyes { - top: 240px; - left: 330px; - animation: blink 8s linear infinite; - animation-delay: 1s; - } - & .she-head { - top: 134px; - left: 145.5px; - animation: headShake 8s linear infinite; - } - & .she-eyes { - top: 243px; - left: 198px; - animation: blink 8s linear infinite; - } - & .shadow { - bottom: 30px; - left: 220px; - animation: shadowSpread 8s linear infinite; - z-index: 0; - ${tmSelectors.dark} { - fill: "#111316"; - } - ${media.mqDark} { - ${tmSelectors.auto} { - fill: "#111316"; - } - } - } - @keyframes bounce { - 0% { - transform: translateY(0); - } - 50% { - transform: translateY(40px); - } - 100% { - transform: translateY(0); - } - } - - @keyframes shadowSpread { - 0% { - transform: none; - } - 50% { - transform: scaleX(1.6); - } - 100% { - transform: none; - } - } - - @keyframes blink { - 0% { - transform: none; - } - 39% { - transform: none; - } - 40% { - transform: matrix(1, 0, 0, 0.2, 0, 0); - } - 41% { - transform: none; - } - 100% { - transform: none; - } - } - - @keyframes headShake { - 0% { - transform: none; - } - 39% { - transform: none; - } - 40% { - transform: translateY(2px); - } - 41% { - transform: none; - } - 100% { - transform: none; - } - } - & .light { - display: inline; - } - & .dark { - display: none; - } - ${tmSelectors.dark} { - & .light { - display: none; - } - & .dark { - display: inline; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - & .light { - display: none; - } - & .dark { - display: inline; - } - } - } -`; - -const DesktopAnimation = () => { - return ( - - - back reflect - - - - back texture - - - back texture dark - - -
- - - mascots ethereum logo - - - mascots ethereum logo dark - - - - he-head - - - he-eyes - - - - she-head - - - she-eyes - -
- - - shadow - - - shadow-dark - - -
- ); -}; - -export default DesktopAnimation; diff --git a/docs/src/components/DocsNavigation.tsx b/docs/src/components/DocsNavigation.tsx deleted file mode 100644 index 262e83a1e1..0000000000 --- a/docs/src/components/DocsNavigation.tsx +++ /dev/null @@ -1,129 +0,0 @@ -import React, { FC, useContext } from "react"; -import { styled } from "linaria/react"; -import Link from "next/link"; -import Image from "next/image"; - -import { media, ThemeContext, tm, tmDark, tmSelectors } from "../themes"; -import logo from "../assets/hardhat-logo.svg"; -import darkLogo from "../assets/hardhat-logo-dark.svg"; -import Hamburger from "./ui/Hamburger"; -import DesktopMenu from "./ui/DesktopMenu"; -import { menuItemsList, socialsItems } from "../config"; -import ThemeSwitchButton from "./ThemeSwitchButton"; - -interface Props { - isSidebarOpen: boolean; - onSidebarOpen: React.Dispatch>; -} - -const NavigationStyled = styled.nav` - position: relative; - width: 100%; - display: flex; - justify-content: center; - align-items: center; - height: 96px; - box-sizing: border-box; - padding: 32px 24px; - transition: all ease-in-out 0.25s; - background-color: ${tm(({ colors }) => colors.neutral0)}; - z-index: 10; - ${media.md} { - padding: 24px; - } - - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - } -`; - -const ControlsContainer = styled.section` - width: 100%; - height: 96px; - display: flex; - justify-content: space-between; - align-items: center; - background-color: ${tm(({ colors }) => colors.transparent)}; - box-sizing: border-box; -`; - -const LogoContainer = styled.a` - display: flex; - justify-content: center; - align-items: center; - padding: 4px 8px; - box-sizing: border-box; - background-color: ${tm(({ colors }) => colors.transparent)}; - border: none; - cursor: pointer; - & .dark-logo { - display: none; - } - ${tmSelectors.dark} { - & .dark-logo { - display: inline; - } - & .light-logo { - display: none; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - & .dark-logo { - display: inline; - } - & .light-logo { - display: none; - } - } - } -`; - -const HamburgerLogoWrapper = styled.div` - display: flex; - align-items: center; -`; -const HamburgerWrapper = styled.div` - ${media.md} { - display: none; - } -`; - -const DocsNavigation: FC = ({ isSidebarOpen, onSidebarOpen }) => { - const { theme } = useContext(ThemeContext); - - return ( - - - - - - - logo - - - logo - - - - - - - - - onSidebarOpen(!isSidebarOpen)} - /> - - - - ); -}; - -export default DocsNavigation; diff --git a/docs/src/components/DocumentationFooter.tsx b/docs/src/components/DocumentationFooter.tsx deleted file mode 100644 index 73a67e9e8e..0000000000 --- a/docs/src/components/DocumentationFooter.tsx +++ /dev/null @@ -1,179 +0,0 @@ -import React from "react"; -import Link from "next/link"; -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../themes"; -import ExternalLinkIcon from "../assets/icons/external-link-icon"; -import FooterArrow from "../assets/icons/footer-arrow"; -import { FooterNavigation } from "./types"; - -type Props = FooterNavigation; - -const Footer = styled.footer` - display: flex; - width: 100%; - flex-direction: column; - margin-top: 74px; - padding: 0 34px; - font-size: 10px; - - & a { - cursor: pointer; - &:hover { - opacity: 0.8; - } - } - - ${media.md} { - padding: 0 140px; - font-size: 16px; - } -`; - -const PageEdit = styled.div` - display: flex; - width: 100%; - justify-content: space-between; - padding-bottom: 16px; - font-weight: 700; - line-height: 150%; - border-bottom: 1px solid ${tm(({ colors }) => colors.neutral400)}; - color: ${tm(({ colors }) => colors.editPageColor)}; - stroke: ${tm(({ colors }) => colors.editPageColor)}; - - ${tmSelectors.dark} { - stroke: ${tmDark(({ colors }) => colors.editPageColor)}; - color: ${tmDark(({ colors }) => colors.editPageColor)}; - border-color: ${tmDark(({ colors }) => colors.neutral400)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - stroke: ${tmDark(({ colors }) => colors.editPageColor)}; - color: ${tmDark(({ colors }) => colors.editPageColor)}; - border-color: ${tmDark(({ colors }) => colors.neutral400)}; - } - } -`; - -const PageNavigation = styled.div` - display: flex; - width: 100%; - justify-content: space-between; - padding: 16px 0 48px; -`; - -const PageNavigationLinkWrapper = styled.div` - & .arrow-reversed { - transform: scaleX(-1); - margin-right: 12px; - } - & > a { - display: inline-flex; - align-items: center; - & > span { - margin-right: 12px; - } - } - font-weight: 700; - color: ${tm(({ colors }) => colors.accent700)}; - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.accent700)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.accent700)}; - } - } -`; - -const ImprovePageLinkWrapper = styled.div` - & > a { - & > span { - max-width: 100px; - display: flex; - align-items: center; - & > svg { - min-width: 20px; - ${media.sm} { - margin-left: 10px; - } - } - ${media.sm} { - max-width: unset; - } - } - } -`; - -const LastUpdatedWrapper = styled.div` - display: flex; - flex-wrap: wrap; - justify-content: flex-end; - align-items: center; - max-width: 80px; - & > span:last-child { - font-weight: 300; - margin-left: 8px; - } - ${media.sm} { - max-width: unset; - } -`; - -const DocumentationFooter = ({ next, prev, lastEditDate, editLink }: Props) => { - const date = lastEditDate ? new Date(lastEditDate).toLocaleString() : ""; - return ( -
- - {editLink ? ( - - - - Help us improve this page - - - - ) : ( -
- )} - {date ? ( - - Last Updated: - {date} - - ) : ( -
- )} - - - {prev !== false && prev?.href !== undefined ? ( - - - {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} - - - {prev.label} - - - - ) : ( -
- )} - {next !== false && next?.href !== undefined ? ( - - - {/* eslint-disable-next-line jsx-a11y/anchor-is-valid */} - - {next.label} - - - - - ) : ( -
- )} - -
- ); -}; - -export default DocumentationFooter; diff --git a/docs/src/components/DocumentationLayout.tsx b/docs/src/components/DocumentationLayout.tsx deleted file mode 100644 index 667cf21df5..0000000000 --- a/docs/src/components/DocumentationLayout.tsx +++ /dev/null @@ -1,328 +0,0 @@ -import React, { useEffect, useRef, useState } from "react"; -import { styled } from "linaria/react"; -import { useRouter } from "next/router"; -import { MDXRemote, MDXRemoteSerializeResult } from "next-mdx-remote"; - -import SEO from "./SEO"; -import DocsNavigation from "./DocsNavigation"; -import Banner, { DefaultBanner } from "./ui/Banner"; -import { tm, tmSelectors, tmDark, media, ThemeProvider } from "../themes"; -import { DefaultBannerProps } from "./ui/types"; -import { - FooterNavigation, - IDocumentationSidebarStructure, - ISeo, -} from "./types"; -import Sidebar from "./Sidebar"; -import { menuItemsList, socialsItems, bannerContent } from "../config"; -import MobileSidebarMenu from "./MobileSidebarMenu"; -import DocumentationFooter from "./DocumentationFooter"; -import Title from "./mdxComponents/Title"; -import Paragraph from "./mdxComponents/Paragraph"; -import CodeBlocks from "./mdxComponents/CodeBlocks"; -import Admonition from "./mdxComponents/Admonition"; -import UnorderedList from "./mdxComponents/UnorderedList"; -import HorizontalRule from "./mdxComponents/HorizontalRule"; -import MDLink from "./mdxComponents/MDLink"; -import Table from "./mdxComponents/Table"; -import MDImage from "./mdxComponents/MDImage"; -import OrderedList from "./mdxComponents/OrderedList"; -import TabsGroup from "./mdxComponents/TabsGroup"; -import Tab from "./mdxComponents/Tab"; -import GDPRNotice from "./GDPRNotice"; - -const Container = styled.div` - position: relative; - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, - Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; - -webkit-font-smoothing: antialiased; - height: 100vh; - min-width: 320px; -`; - -const Main = styled.main` - padding-top: 136px; - flex: 1 1 auto; - display: flex; - justify-content: flex-start; - align-items: center; - background-color: ${tm(({ colors }) => colors.neutral0)}; - width: 100%; - position: relative; - transition: background-color ease-in-out 0.25s; - - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - } -`; - -export const SidebarMask = styled.div` - display: flex; - flex-direction: column; - height: 100%; -`; -export const MobileSidebarMenuMask = styled.div` - display: flex; - flex-direction: column; - height: 100%; - position: absolute; - width: 100%; - left: -100%; - top: 0; - transition: all 0.25s ease-in-out; - &[data-open="true"] { - left: 0; - } -`; - -export const SidebarContainer = styled.aside<{ isSidebarOpen: boolean }>` - flex-direction: column; - width: min(366px, 100%); - position: fixed; - top: 136px; - left: ${({ isSidebarOpen }) => (isSidebarOpen ? "0px" : "-120vw")}; - height: calc(100vh - 136px); - display: flex; - overflow-y: auto; - transition: all ease-out 0.25s; - z-index: 50; - background-color: ${tm(({ colors }) => colors.neutral0)}; - - ${media.md} { - left: 0; - } - - .landing & { - ${media.md} { - display: none; - } - pointer-events: ${({ isSidebarOpen }) => (isSidebarOpen ? "auto" : "none")}; - } - - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - } - - :not(&[data-no-border="true"]) { - border-right: 1px solid ${tm(({ colors }) => colors.neutral400)}; - ${tmSelectors.dark} { - border-right: 1px solid ${tmDark(({ colors }) => colors.border)}; - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - border-right: 1px solid ${tmDark(({ colors }) => colors.border)}; - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - } - } - - ${SidebarMask} { - display: none; - ${media.md} { - display: flex; - } - } - ${MobileSidebarMenuMask} { - display: flex; - ${media.md} { - display: none; - } - } - - &[data-no-border="true"] { - border-right: none; - } -`; - -export const Header = styled.header` - position: fixed; - width: 100%; - top: 0; - left: 0; - display: flex; - flex-direction: column; - z-index: 199; -`; - -const View = styled.section` - display: flex; - flex-direction: column; - align-items: center; - justify-content: space-between; - padding-top: 24px; - width: 100%; - height: calc(100vh - 136px); - overflow-y: scroll; - scroll-behavior: smooth; - ${media.md} { - padding-left: 366px; - } -`; -const Content = styled.section` - width: 100%; - max-width: 774px; - padding: 0 34px; - color: ${tm(({ colors }) => colors.neutral900)}; - - & h2 + p { - margin-top: 32px; - } - - color: ${tm(({ colors }) => colors.neutral900)}; - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } -`; - -export const components = { - h1: Title.H1, - h2: Title.H2, - h3: Title.H3, - h4: Title.H4, - h5: Title.H5, - p: Paragraph, - code: CodeBlocks.Code, - pre: CodeBlocks.Pre, - tip: Admonition.Tip, - warning: Admonition.Warning, - ul: UnorderedList, - ol: OrderedList, - hr: HorizontalRule, - a: MDLink, - table: Table, - img: MDImage, - tabsgroup: TabsGroup, - tab: Tab, -}; - -interface Props { - seo: ISeo; - sidebarLayout: IDocumentationSidebarStructure; - footerNavigation?: FooterNavigation; - mdxSource: MDXRemoteSerializeResult; -} - -const DocumentationLayout = ({ - mdxSource, - seo, - sidebarLayout, - footerNavigation, -}: Props) => { - const [isSidebarOpen, setIsSidebarOpen] = useState(false); - const router = useRouter(); - const docViewRef = useRef() as React.MutableRefObject; - - useEffect(() => { - docViewRef.current.scrollTo(0, 0); - }, [router.asPath]); - - useEffect(() => { - const body = document.querySelector("body"); - if (!body) return; - - if (isSidebarOpen) { - // Disable scroll - body.style.overflow = "hidden"; - } else { - // Enable scroll - body.style.overflow = "auto"; - } - }, [isSidebarOpen]); - - useEffect(() => { - const listener = () => { - if (isSidebarOpen) { - setIsSidebarOpen(false); - } - }; - - document.addEventListener("click", listener); - - return () => document.removeEventListener("click", listener); - }, [isSidebarOpen]); - - return ( - - -
- ( - - )} - /> - -
- - - -
- { - e.stopPropagation(); - }} - isSidebarOpen={isSidebarOpen} - > - - setIsSidebarOpen(false)} - /> - - - setIsSidebarOpen(false)} - isDocumentation - /> - - - - - {/* @ts-ignore */} - - - {footerNavigation ? ( - - ) : null} - -
-
- -
- ); -}; - -export default DocumentationLayout; diff --git a/docs/src/components/GDPRNotice.model.ts b/docs/src/components/GDPRNotice.model.ts deleted file mode 100644 index f8c5f8f81b..0000000000 --- a/docs/src/components/GDPRNotice.model.ts +++ /dev/null @@ -1,15 +0,0 @@ -/* eslint-disable import/prefer-default-export */ -const MeasurementID = process.env.NEXT_PUBLIC_MEASUREMENT_ID as string; - -export const loadAnalyticsScript = () => { - const existingScript = document.querySelector("#google-tag-manager"); - if (existingScript) { - return; - } - - const script = document.createElement("script"); - script.id = "google-tag-manager"; - script.async = true; - script.src = `https://www.googletagmanager.com/gtag/js?id=${MeasurementID}`; - document.head.appendChild(script); -}; diff --git a/docs/src/components/GDPRNotice.tsx b/docs/src/components/GDPRNotice.tsx deleted file mode 100644 index f637bc8e4b..0000000000 --- a/docs/src/components/GDPRNotice.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import CookiePopUp from "./CookiePopUp"; -import { GDPR } from "../config"; -import { loadAnalyticsScript } from "./GDPRNotice.model"; - -enum GDPRStatus { - ACCEPTED = "accepted", - REJECTED = "rejected", - UNKNOWN = "unknown", -} - -const ITEM_KEY = "GDPR_ACCEPTED"; - -const Container = styled.div` - position: fixed; - bottom: 30px; - right: 30px; - z-index: 101; -`; - -const useGDPR = () => { - const [isOpen, setIsOpen] = React.useState(false); - - React.useEffect(() => { - const acceptedStatus = (localStorage.getItem(ITEM_KEY) ?? - GDPRStatus.UNKNOWN) as GDPRStatus; - if (acceptedStatus === GDPRStatus.UNKNOWN) { - setIsOpen(true); - } - if (acceptedStatus === GDPRStatus.ACCEPTED) { - loadAnalyticsScript(); - } - }, []); - - const handleAccept = () => { - localStorage.setItem(ITEM_KEY, GDPRStatus.ACCEPTED); - setIsOpen(false); - loadAnalyticsScript(); - }; - - const handleReject = () => { - localStorage.setItem(ITEM_KEY, GDPRStatus.REJECTED); - setIsOpen(false); - }; - - return { - isOpen, - handleAccept, - handleReject, - }; -}; - -const GDPRNotice = () => { - const manageGDPR = useGDPR(); - - if (!manageGDPR.isOpen) { - return null; - } - - return ( - - - - ); -}; - -export default GDPRNotice; diff --git a/docs/src/components/LandingFooter.tsx b/docs/src/components/LandingFooter.tsx deleted file mode 100644 index 58605160db..0000000000 --- a/docs/src/components/LandingFooter.tsx +++ /dev/null @@ -1,153 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import Image from "next/image"; -import Link from "next/link"; -import ethereumFoundationLogo from "../assets/ethereum-foundation-logo.svg"; -import ethereumFoundationLogoDark from "../assets/ethereum-foundation-logo-dark.svg"; -import { media, tm, tmDark, tmSelectors } from "../themes"; -import { PRIVACY_POLICY_PATH } from "../config"; - -const Footer = styled.footer` - padding: 80px 24px 120px; - width: 100%; - display: flex; - flex-direction: column; - align-items: center; - background-color: ${tm(({ colors }) => colors.neutral900)}; - ${media.md} { - padding: 64px 24px 40px; - } - & .light { - display: inline; - } - & .dark { - display: none; - } - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.neutral900)}; - - & .light { - display: none; - } - & .dark { - display: inline; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.neutral900)}; - - & .light { - display: none; - } - & .dark { - display: inline; - } - } - } -`; - -const SupportedBy = styled.section` - display: flex; - flex-direction: column; - align-items: center; - ${media.md} { - flex-direction: row; - } -`; - -const Subtitle = styled.h2` - color: ${tm(({ colors }) => colors.footerText)}; - font-size: 18px; - font-weight: normal; - line-height: 40px; - letter-spacing: 0; - text-align: center; - margin-bottom: 16px; - font-family: ChivoLight, sans-serif; - ${media.md} { - margin-bottom: unset; - margin-right: 24px; - font-size: 24px; - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.footerText)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.footerText)}; - } - } -`; - -const Legal = styled.section` - margin-top: 80px; - padding-top: 21px; - position: relative; - font-size: 12px; - line-height: 12px; - letter-spacing: 0; - text-align: center; - color: ${tm(({ colors }) => colors.footerText2)}; - &:before { - content: " "; - height: 1px; - width: 186px; - position: absolute; - top: 0; - left: 50%; - transform: translateX(-50%); - background-color: ${tm(({ colors }) => colors.footerText2)}; - } - ${media.md} { - font-size: 15px; - line-height: 24px; - margin-top: 96px; - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.footerText2)}; - &:before { - background-color: ${tmDark(({ colors }) => colors.footerText2)}; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - &:before { - background-color: ${tmDark(({ colors }) => colors.footerText2)}; - } - color: ${tmDark(({ colors }) => colors.footerText2)}; - } - } -`; - -const PrivacyPolicyLink = styled.a` - cursor: pointer; - margin-left: 4px; - &:hover { - opacity: 0.8; - } -`; - -const LandingFooter = () => { - return ( -
- - Supported by - - logo - - - logo dark - - - - Copyright {new Date().getFullYear()} Nomic Foundation | - - Privacy Policy - - -
- ); -}; - -export default LandingFooter; diff --git a/docs/src/components/LandingLayout.tsx b/docs/src/components/LandingLayout.tsx deleted file mode 100644 index f5144b4876..0000000000 --- a/docs/src/components/LandingLayout.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import React, { useEffect, useState } from "react"; -import { styled } from "linaria/react"; - -import SEO from "./SEO"; -import LandingFooter from "./LandingFooter"; -import Banner, { DefaultBanner } from "./ui/Banner"; -import { media, ThemeProvider, tm, tmDark, tmSelectors } from "../themes"; -import { DefaultBannerProps } from "./ui/types"; -import { bannerContent, menuItemsList, socialsItems } from "../config"; -import GDPRNotice from "./GDPRNotice"; -import DocsNavigation from "./DocsNavigation"; -import { - Header, - MobileSidebarMenuMask, - SidebarContainer, -} from "./DocumentationLayout"; -import MobileSidebarMenu from "./MobileSidebarMenu"; -import { IDocumentationSidebarStructure, ISeo } from "./types"; - -const Container = styled.div` - position: relative; - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; - -webkit-font-smoothing: antialiased; - background-color: ${tm(({ colors }) => colors.neutral0)}; - transition: all ease-in-out 0.25s; - min-width: 320px; - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - } -`; - -const Main = styled.main` - overflow-x: hidden; - padding-top: 136px; - flex: 1 1 auto; - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; - width: 100%; -`; - -type Props = React.PropsWithChildren<{ - seo: ISeo; - sidebarLayout: IDocumentationSidebarStructure; -}>; - -const LandingLayout = ({ children, seo, sidebarLayout }: Props) => { - const [isSidebarOpen, setIsSidebarOpen] = useState(false); - - useEffect(() => { - const body = document.querySelector("body"); - if (!body) return; - - if (isSidebarOpen) { - // Disable scroll - body.style.overflow = "hidden"; - } else { - // Enable scroll - body.style.overflow = "auto"; - } - }, [isSidebarOpen]); - - useEffect(() => { - const listener = () => { - if (isSidebarOpen) { - setIsSidebarOpen(false); - } - }; - - document.addEventListener("click", listener); - - return () => document.removeEventListener("click", listener); - }, [isSidebarOpen]); - return ( - - -
- ( - - )} - /> - -
- - -
- { - e.stopPropagation(); - }} - isSidebarOpen={isSidebarOpen} - data-no-border={!isSidebarOpen && sidebarLayout.length === 0} - > - - setIsSidebarOpen(false)} - isDocumentation={false} - /> - - - {children} - -
-
- -
- ); -}; - -export default LandingLayout; diff --git a/docs/src/components/MobileAnimation.tsx b/docs/src/components/MobileAnimation.tsx deleted file mode 100644 index 15939cc0fe..0000000000 --- a/docs/src/components/MobileAnimation.tsx +++ /dev/null @@ -1,183 +0,0 @@ -import React, { useEffect, useRef, useState } from "react"; -import Image from "next/image"; -import { styled } from "linaria/react"; - -import ethereumLogo from "../assets/animation/mobile/ethereum_logo.svg"; -import ethereumLogoDark from "../assets/animation/mobile/ethereum_logo-dark.svg"; -import mascots from "../assets/animation/mobile/mascots.svg"; -import heEyesOpen from "../assets/animation/mobile/he-eyes_open.svg"; -import sheEyesOpen from "../assets/animation/mobile/she-eyes_open.svg"; -import { media, tmSelectors } from "../themes"; - -const AnimationContainer = styled.section` - width: 300px; - height: 152px; - position: fixed; - bottom: 0; - left: 50%; - z-index: 1; - transform: translateX(-30%) scale(0.7); - pointer-events: none; - transform-origin: bottom center; - - ${media.xxs} { - transform: translateX(-50%) scale(0.85); - } - ${media.sm} { - transform: translateX(-50%) scale(1.2); - } - ${media.smd} { - transform: translateX(-50%) scale(1.7); - } - ${media.md} { - display: none; - } - & .light { - display: inline; - } - & .dark { - display: none; - } - ${tmSelectors.dark} { - & .light { - display: none; - } - & .dark { - display: inline; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - & .light { - display: none; - } - & .dark { - display: inline; - } - } - } -`; - -const Anchor = styled.span` - height: 0; - width: 0; - visibility: hidden; - position: absolute; - top: 0; - left: 0; - ${media.md} { - display: block; - } -`; - -const EthereumLogoContainer = styled.span<{ anchorPosition: number }>` - position: absolute; - bottom: -20px; - left: 55px; - opacity: ${({ anchorPosition }) => (100 + anchorPosition * 0.8) / 100}; -`; -const MascotsContainer = styled.span<{ anchorPosition: number }>` - position: absolute; - bottom: ${({ anchorPosition }) => `${anchorPosition}px`}; - left: 5px; - & .he-eyes { - bottom: 48px; - left: 182px; - animation: blink 8s linear infinite; - animation-delay: 1s; - position: absolute; - } - & .she-eyes { - bottom: 60px; - left: 48px; - animation: blink 8s linear infinite; - position: absolute; - } - @keyframes blink { - 0% { - transform: none; - } - 39% { - transform: none; - } - 40% { - transform: matrix(1, 0, 0, 0.2, 0, 0); - } - 41% { - transform: none; - } - 100% { - transform: none; - } - } -`; - -const defaultTopPosition = 140; - -const validateAnchorPosition = ( - anchorPosition: number, - defaultAnchorPosition: number -) => { - return anchorPosition - defaultAnchorPosition > 0 - ? 0 - : anchorPosition - defaultAnchorPosition; -}; - -const MobileAnimation = () => { - const [anchorPosition, setAnchorPosition] = useState(0); - const anchorRef = useRef(null); - - useEffect(() => { - const listener = () => { - const anchorTopPosition = - anchorRef.current?.getBoundingClientRect()?.top ?? 0; - - const validatedAnchorPosition = validateAnchorPosition( - anchorTopPosition, - defaultTopPosition - ); - - setAnchorPosition(validatedAnchorPosition); - }; - document.addEventListener("scroll", listener); - - // eslint-disable-next-line - return () => { - document.removeEventListener("scroll", listener); - }; - }, []); - - return ( - <> - { - e.preventDefault(); - }} - > - - - ethereum logo - - - ethereum logo dark - - - - mascots - - he-eyes - - - she-eyes - - - - - - ); -}; - -export default MobileAnimation; diff --git a/docs/src/components/MobileSidebarMenu.tsx b/docs/src/components/MobileSidebarMenu.tsx deleted file mode 100644 index 5bd8de634b..0000000000 --- a/docs/src/components/MobileSidebarMenu.tsx +++ /dev/null @@ -1,482 +0,0 @@ -import React, { - Dispatch, - FC, - SetStateAction, - useEffect, - useMemo, - useState, -} from "react"; -import Link from "next/link"; -import { useRouter } from "next/router"; -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../themes"; -import Sidebar from "./Sidebar"; -import { menuItemsList, socialsItems as defaultSocialItems } from "../config"; -import ExternalLinkIcon from "../assets/icons/external-link-icon"; -import { IDocumentationSidebarStructure } from "./types"; -import { MenuItemType, NavigationPagesPaths, SocialsEnum } from "./ui/types"; -import MobileMenuArrowForward from "../assets/icons/mobile-menu-arrow-forward"; -import { SocialsList } from "./ui/DesktopMenu"; -import ThemeSwitchButton from "./ThemeSwitchButton"; -import MobileMenuArrowBack from "../assets/icons/mobile-menu-arrow-back"; - -interface Props { - sidebarElementsList: IDocumentationSidebarStructure; - menuItems: typeof menuItemsList; - socialsItems: typeof defaultSocialItems; - closeSidebar: () => void; - isDocumentation: boolean; -} - -interface ModalProps { - modalState: MenuItemType | null; - setModalState: Dispatch>; - closeSidebar: () => void; - sidebarElementsList: IDocumentationSidebarStructure; - socialsItems: typeof defaultSocialItems; -} - -const MobileSidebarContainer = styled.section` - display: flex; - flex-direction: column; -`; - -const MobileNavigationContainer = styled.ul` - list-style-type: none; - display: flex; - flex-direction: column; - padding: 16px 0; - color: ${tm(({ colors }) => colors.neutral900)}; - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } -`; - -const MenuItem = styled.li` - padding: 8px 32px; - display: flex; - align-items: center; - font-size: 24px; - font-weight: 400; - text-transform: uppercase; - font-family: ChivoRegular, sans-serif; - cursor: pointer; - margin-top: 8px; - - &:first-child { - margin-top: unset; - } - &:hover { - color: ${tm(({ colors }) => colors.accent700)}; - & svg { - stroke: ${tm(({ colors }) => colors.accent700)}; - fill: ${tm(({ colors }) => colors.accent700)}; - } - & a:after { - background-color: ${tm(({ colors }) => colors.accent700)}; - } - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.accent700)}; - & svg { - stroke: ${tmDark(({ colors }) => colors.accent700)}; - fill: ${tmDark(({ colors }) => colors.accent700)}; - } - & a:after { - background-color: ${tmDark(({ colors }) => colors.accent700)}; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.accent700)}; - & svg { - stroke: ${tmDark(({ colors }) => colors.accent700)}; - fill: ${tmDark(({ colors }) => colors.accent700)}; - } - & a:after { - background-color: ${tmDark(({ colors }) => colors.accent700)}; - } - } - } - } - & > a { - position: relative; - &:after { - transition: all ease-in-out 0.2s; - position: absolute; - bottom: -8px; - left: 0; - content: " "; - width: 0; - height: 1px; - background-color: ${tm(({ colors }) => colors.neutral800)}; - - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.neutral800)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.neutral800)}; - } - } - } - } - &[data-current="true"] { - & > a { - &:after { - width: 100%; - } - } - } - & svg { - margin-left: 4px; - stroke: ${tm(({ colors }) => colors.neutral900)}; - fill: ${tm(({ colors }) => colors.neutral900)}; - - ${tmSelectors.dark} { - stroke: ${tmDark(({ colors }) => colors.neutral900)}; - fill: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - stroke: ${tmDark(({ colors }) => colors.neutral900)}; - fill: ${tmDark(({ colors }) => colors.neutral900)}; - } - } - } -`; - -const MobileMenuFooter = styled.div<{ isRelative?: boolean }>` - display: flex; - justify-content: space-between; - align-items: center; - width: 100%; - padding: 16px 40px 32px; - position: ${({ isRelative }) => (isRelative ? "relative" : "absolute")}; - bottom: 0; - &::before { - content: " "; - height: 1px; - width: 200px; - position: absolute; - top: 0; - left: 32px; - background-color: ${tm(({ colors }) => colors.border)}; - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.border)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.border)}; - } - } - } -`; - -const ModalContainer = styled.div<{ isModalOpen: boolean }>` - display: flex; - flex-direction: column; - height: calc(100vh - 136px); - padding: 32px 0; - position: absolute; - width: 100%; - top: 0px; - transition: all ease-out 0.25s; - font-family: ChivoRegular, sans-serif; - z-index: 50; - left: ${({ isModalOpen }) => (isModalOpen ? "0px" : "-120vw")}; - color: ${tm(({ colors }) => colors.neutral800)}; - background-color: ${tm(({ colors }) => colors.neutral0)}; - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - } -`; - -const ModalBackToMenuButton = styled.button` - margin-left: 32px; - display: flex; - align-items: center; - font-size: 15px; - line-height: 20px; - width: fit-content; - background-color: ${tm(({ colors }) => colors.transparent)}; - border: none; - color: ${tm(({ colors }) => colors.backButton)}; - cursor: pointer; - &:hover { - opacity: 0.8; - } - & svg { - margin-right: 6px; - stroke: ${tm(({ colors }) => colors.backButton)}; - fill: ${tm(({ colors }) => colors.backButton)}; - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.backButton)}; - & svg { - stroke: ${tmDark(({ colors }) => colors.backButton)}; - fill: ${tmDark(({ colors }) => colors.backButton)}; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.backButton)}; - & svg { - stroke: ${tmDark(({ colors }) => colors.backButton)}; - fill: ${tmDark(({ colors }) => colors.backButton)}; - } - } - } -`; - -const ModalTitle = styled.h4` - margin: 16px 32px 8px; - font-size: 24px; - font-weight: 400; - width: fit-content; - text-transform: uppercase; - position: relative; - color: ${tm(({ colors }) => colors.neutral900)}; - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } - &:after { - transition: all ease-in-out 0.2s; - position: absolute; - bottom: -8px; - left: 0; - content: " "; - width: 100%; - height: 1px; - background-color: ${tm(({ colors }) => colors.neutral900)}; - - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } - } -`; - -const ToolsList = styled.ul` - display: flex; - flex-direction: column; - user-select: none; - list-style-type: none; - font-size: 16.5px; - line-height: 150%; - font-weight: 400; - padding: 19.5px 32px; -`; - -const ToolsListItem = styled.li` - margin-top: 15px; - &:first-child { - margin-top: unset; - } -`; - -const SocialItem = ({ name, href }: { name: SocialsEnum; href: string }) => { - return ( - - - {name.toLowerCase()} - - - - ); -}; - -const getCurrentSection = ({ - isDocumentation, - currentLocation, -}: { - isDocumentation: boolean; - currentLocation: string; -}): NavigationPagesPaths => { - if (isDocumentation) { - if (currentLocation.startsWith(NavigationPagesPaths.TUTORIAL)) - return NavigationPagesPaths.TUTORIAL; - return NavigationPagesPaths.DOCUMENTATION; - } - return currentLocation as NavigationPagesPaths; -}; - -const MobileSidebarMenuModal: FC = ({ - modalState, - setModalState, - sidebarElementsList, - closeSidebar, - socialsItems, -}) => { - const renderModalContent = ( - selectedSection: NavigationPagesPaths | string - ) => { - if (selectedSection === NavigationPagesPaths.TOOLS) { - return ( - - {modalState?.subItems?.map((subItem) => { - return ( - - - {/* eslint-disable-next-line */} - {`${subItem.prefix as string} ${ - subItem.label - }`} - - - ); - })} - - ); - } - return ( - - ); - }; - - return ( - - setModalState(null)}> - - Back - - {modalState?.label} - {modalState !== null && renderModalContent(modalState.href)} - - - - - - ); -}; - -const MobileSidebarMenu: FC = ({ - sidebarElementsList, - closeSidebar, - menuItems, - socialsItems, - isDocumentation = false, -}) => { - const router = useRouter(); - const [modalState, setModalState] = useState(null); - const gitHubSocial = socialsItems.find( - (socialsItem) => socialsItem.name === SocialsEnum.GITHUB - ); - const currentSection = getCurrentSection({ - isDocumentation, - currentLocation: router?.asPath, - }); - const isModal = useMemo( - () => - [ - NavigationPagesPaths.DOCUMENTATION, - NavigationPagesPaths.TUTORIAL, - NavigationPagesPaths.TOOLS, - ].includes(currentSection), - [currentSection] - ); - - useEffect(() => { - if (isModal) { - setModalState( - menuItems.find((menuItem) => menuItem.href === currentSection) || null - ); - } - }, [currentSection, menuItems, isModal]); - - const handleClick = ( - event: React.MouseEvent, - menuItem: MenuItemType - ) => { - if ( - menuItem.href === NavigationPagesPaths.TOOLS || - ([ - NavigationPagesPaths.DOCUMENTATION, - NavigationPagesPaths.TUTORIAL, - ].includes(currentSection) && - currentSection === menuItem.href) - ) { - event.preventDefault(); - setModalState(menuItem); - } else { - closeSidebar(); - } - }; - - return ( - - - {menuItems.map((menuItem) => { - return ( - handleClick(e, menuItem)} - > - - {/* eslint-disable-next-line */} - { - if ( - menuItem.href === NavigationPagesPaths.TOOLS || - ([ - NavigationPagesPaths.DOCUMENTATION, - NavigationPagesPaths.TUTORIAL, - ].includes(currentSection) && - currentSection === menuItem.href) - ) { - e.preventDefault(); - } - }} - > - {menuItem.label} - - - {sidebarElementsList.length > 0 && - currentSection === menuItem.href && ( - - )} - - ); - })} - {gitHubSocial && } - - - - - - - - - ); -}; - -export default MobileSidebarMenu; diff --git a/docs/src/components/Navigation.mocks.json b/docs/src/components/Navigation.mocks.json deleted file mode 100644 index f542795d7e..0000000000 --- a/docs/src/components/Navigation.mocks.json +++ /dev/null @@ -1,203 +0,0 @@ -[ - { - "label": "Getting started", - "href": "/getting-started", - "type": "single", - "children": [ - { - "label": "Overview", - "href": "/getting-started#overview" - }, - { - "label": "Installation", - "href": "/getting-started#installation" - }, - { - "label": "Quick start", - "href": "/getting-started#quick-start" - } - ] - }, - { - "label": "Configuration", - "href": "/config", - "type": "single" - }, - { - "label": "Hardhat Network", - "type": "group", - "children": [ - { - "label": "What is it?", - "href": "/hardhat-network" - }, - { - "label": "Mainnet Forking", - "href": "/hardhat-network/guides/forking-other-networks" - }, - { - "label": "Mining Modes", - "href": "/hardhat-network/explanation/mining-modes" - }, - { - "label": "Reference", - "href": "/hardhat-network/reference" - } - ] - }, - { - "label": "Guides", - "type": "group", - "children": [ - { - "label": "Settings up a project", - "href": "/guides/project-setup" - }, - { - "label": "Compiling your contracts", - "href": "/guides/compile-contracts" - }, - { - "label": "Testing with ethers.js & Waffle", - "href": "/guides/waffle-testing" - }, - { - "label": "Testing with Web3.js & Truffle", - "href": "/guides/truffle-testing" - }, - { - "label": "Running tests in parallel", - "href": "/guides/parallel-tests" - }, - { - "label": "Migrating from Truffle", - "href": "/guides/truffle-migration" - }, - { - "label": "Deploying your contracts", - "href": "/guides/deploying" - }, - { - "label": "Writing scripts with Hardhat", - "href": "/guides/scripts" - }, - { - "label": "Using the Hardhat console", - "href": "/guides/hardhat-console" - }, - { - "label": "Creating a task", - "href": "/guides/create-task" - }, - { - "label": "Running tests with Ganache", - "href": "/guides/ganache-tests" - }, - { - "label": "Running tests on Visual Studio Code", - "href": "/guides/vscode-tests" - }, - { - "label": "TypeScript Support", - "href": "/guides/typescript" - }, - { - "label": "Shorthand (hh) and autocomplete", - "href": "/guides/shorthand" - } - ] - }, - { - "label": "Advanced", - "type": "group", - "children": [ - { - "label": "Hardhat Runtime Environment (HRE)", - "href": "/advanced/hardhat-runtime-environment" - }, - { - "label": "Building plugins", - "href": "/advanced/building-plugins" - } - ] - }, - { - "label": "Troubleshooting", - "type": "group", - "children": [ - { - "label": "Verbose logging", - "href": "/troubleshooting/verbose-logging" - }, - { - "label": "Common problems", - "href": "/troubleshooting/common-problems" - } - ] - }, - { - "label": "Reference", - "type": "group", - "children": [ - { - "label": "Stability guarantees", - "href": "/reference/stability-guarantees" - }, - { - "label": "Solidity support", - "href": "/reference/solidity-support" - } - ] - }, - { - "label": "Plugins", - "type": "group", - "children": [ - { - "label": "@nomiclabs/hardhat-ethers", - "href": "/plugins/nomiclabs-hardhat-ethers" - }, - { - "label": "@nomiclabs/hardhat-waffle", - "href": "/plugins/nomiclabs-hardhat-waffle" - }, - { - "label": "@nomicfoundation/hardhat-verify", - "href": "/plugins/nomicfoundation-hardhat-verify" - }, - { - "label": "@nomiclabs/hardhat-web3", - "href": "/plugins/nomiclabs-hardhat-web3" - }, - { - "label": "@nomiclabs/hardhat-truffle5", - "href": "/plugins/nomiclabs-hardhat-truffle5" - }, - { - "label": "@nomiclabs/hardhat-solhint", - "href": "/plugins/nomiclabs-hardhat-solhint" - }, - { - "label": "@nomiclabs/hardhat-solpp", - "href": "/plugins/nomiclabs-hardhat-solpp" - }, - { - "label": "@nomiclabs/hardhat-vyper", - "href": "/plugins/nomiclabs-hardhat-vyper" - }, - { - "label": "@nomiclabs/hardhat-truffle4", - "href": "/plugins/nomiclabs-hardhat-truffle4" - }, - { - "label": "@nomiclabs/hardhat-web3-legacy", - "href": "/plugins/nomiclabs-hardhat-web3-legacy" - } - ] - }, - { - "label": "Community Plugins", - "href": "/plugins/#community-plugins", - "type": "single" - } -] diff --git a/docs/src/components/Navigation.stories.tsx b/docs/src/components/Navigation.stories.tsx deleted file mode 100644 index 32b54e3186..0000000000 --- a/docs/src/components/Navigation.stories.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React, { useState } from "react"; -import { menuItemsList, socialsItems } from "../config"; -import DocumentationSidebarStructure from "./Navigation.mocks.json"; -import MobileSidebarMenu from "./MobileSidebarMenu"; - -import DocumentationNavigation from "./DocsNavigation"; -import Sidebar from "./Sidebar"; -import { IDocumentationSidebarStructure } from "./types"; - -export default { - title: "Documentation/ Navigation", -}; - -export const MobileSidebar = () => ( - {}} - isDocumentation={false} - /> -); - -export const SidebarMenu = () => ( - -); - -export const Navigation = () => { - const [isSidebarOpen, setIsSidebarOpen] = useState(false); - return ( - - ); -}; diff --git a/docs/src/components/PluginSnippet.tsx b/docs/src/components/PluginSnippet.tsx deleted file mode 100644 index a49a3cf69c..0000000000 --- a/docs/src/components/PluginSnippet.tsx +++ /dev/null @@ -1,141 +0,0 @@ -import React from "react"; -import Link from "next/link"; -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../themes"; -import { IPlugin } from "../model/types"; - -const StyledPluginSnippetContainer = styled.div` - width: 100%; - display: flex; - flex-direction: column; - margin-bottom: 50px; -`; - -const PluginNameAuthorContainer = styled.div` - display: flex; - flex-direction: column; - ${media.md} { - flex-direction: row; - align-items: center; - } -`; - -const PluginName = styled.a` - font-size: 20px; - line-height: 150%; - font-weight: 700; - color: ${tm(({ colors }) => colors.accent900)}; - margin-right: 18px; - &:hover { - opacity: 0.8; - } -`; - -const Author = styled.a` - font-size: 16px; - line-height: 150%; - color: ${tm(({ colors }) => colors.autoThemeButton)}; - - &:hover { - opacity: 0.8; - } - - ${media.md} { - padding-left: 8px; - border-left: 1px solid ${tm(({ colors }) => colors.autoThemeButton)}; - } - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.autoThemeButton)}; - border-color: ${tmDark(({ colors }) => colors.autoThemeButton)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.autoThemeButton)}; - border-color: ${tmDark(({ colors }) => colors.autoThemeButton)}; - } - } -`; - -const Description = styled.p` - font-size: 16; - line-height: 150%; - width: 100%; - margin-top: 12px; - color: ${tm(({ colors }) => colors.neutral800)}; - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - } -`; - -const TagsContainer = styled.div` - display: flex; - flex-wrap: wrap; - margin-top: 16px; -`; - -const Tag = styled.div` - padding: 4px 16px; - margin: 8px 8px 0 0; - border-radius: 5px; - font-size: 13px; - line-height: 19.5px; - background-color: ${tm(({ colors }) => colors.tagBackground)}; - color: ${tm(({ colors }) => colors.codeColor)}; - - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.tagBackground)}; - color: ${tmDark(({ colors }) => colors.codeColor)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.tagBackground)}; - color: ${tmDark(({ colors }) => colors.codeColor)}; - } - } -`; - -const PluginSnippet = ({ - name, - author, - authorUrl, - description, - tags, - href, -}: IPlugin & { href: string }) => { - const isExternalLink = href.startsWith("http"); - - return ( - - - {isExternalLink ? ( - - {name} - - ) : ( - - {/* eslint-disable-next-line */} - {name} - - )} - - {author} - - - {description} - - {tags.map((tagName) => ( - {tagName} - ))} - - - ); -}; - -export default PluginSnippet; diff --git a/docs/src/components/PluginsLayout.tsx b/docs/src/components/PluginsLayout.tsx deleted file mode 100644 index 9ded21ac61..0000000000 --- a/docs/src/components/PluginsLayout.tsx +++ /dev/null @@ -1,179 +0,0 @@ -import React, { useEffect, useRef, useState } from "react"; -import { styled } from "linaria/react"; -import { useRouter } from "next/router"; - -import SEO from "./SEO"; -import DocsNavigation from "./DocsNavigation"; -import Banner, { DefaultBanner } from "./ui/Banner"; -import { tm, tmSelectors, tmDark, media, ThemeProvider } from "../themes"; -import { DefaultBannerProps } from "./ui/types"; -import { IDocumentationSidebarStructure, ISeo } from "./types"; -import { bannerContent, menuItemsList, socialsItems } from "../config"; -import { - Header, - MobileSidebarMenuMask, - SidebarContainer, -} from "./DocumentationLayout"; -import MobileSidebarMenu from "./MobileSidebarMenu"; - -const Container = styled.div` - position: relative; - display: flex; - flex-direction: column; - justify-content: flex-start; - align-items: center; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, - Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif; - -webkit-font-smoothing: antialiased; - height: 100vh; - min-width: 320px; -`; - -const Main = styled.main` - padding-top: 136px; - flex: 1 1 auto; - display: flex; - justify-content: flex-start; - align-items: center; - background-color: ${tm(({ colors }) => colors.neutral0)}; - width: 100%; - position: relative; - transition: background-color ease-in-out 0.25s; - - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - } - ${media.md} { - & aside { - display: none; - } - } -`; - -const View = styled.section` - display: flex; - flex-direction: column; - align-items: center; - padding-top: 24px; - width: 100%; - height: calc(100vh - 136px); - overflow-y: scroll; -`; -const Content = styled.section` - display: flex; - flex-direction: column; - width: 100%; - max-width: 774px; - padding: 0 34px; - color: ${tm(({ colors }) => colors.neutral900)}; - & h2:not(:first-of-type) { - padding-top: 80px; - } - - & h2 + p { - margin-top: 32px; - } - - color: ${tm(({ colors }) => colors.neutral900)}; - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } -`; - -type Props = React.PropsWithChildren<{ - seo: ISeo; - sidebarLayout: IDocumentationSidebarStructure; -}>; - -const PluginsLayout = ({ children, seo, sidebarLayout }: Props) => { - const [isSidebarOpen, setIsSidebarOpen] = useState(false); - const router = useRouter(); - const pluginsViewRef = useRef() as React.MutableRefObject; - - useEffect(() => { - pluginsViewRef.current.scrollTo(0, 0); - }, [router.asPath]); - - useEffect(() => { - const body = document.querySelector("body"); - if (!body) return; - - if (isSidebarOpen) { - // Disable scroll - body.style.overflow = "hidden"; - } else { - // Enable scroll - body.style.overflow = "auto"; - } - }, [isSidebarOpen]); - - useEffect(() => { - const listener = () => { - if (isSidebarOpen) { - setIsSidebarOpen(false); - } - }; - - document.addEventListener("click", listener); - - return () => document.removeEventListener("click", listener); - }, [isSidebarOpen]); - - return ( - - -
- ( - - )} - /> - -
- - - -
- { - e.stopPropagation(); - }} - isSidebarOpen={isSidebarOpen} - data-no-border={!isSidebarOpen && sidebarLayout.length === 0} - > - - setIsSidebarOpen(false)} - isDocumentation={false} - /> - - - - {children} - -
-
-
- ); -}; - -export default PluginsLayout; diff --git a/docs/src/components/SEO.tsx b/docs/src/components/SEO.tsx deleted file mode 100644 index 9b233ab776..0000000000 --- a/docs/src/components/SEO.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from "react"; -import Head from "next/head"; - -interface Props { - seo: { - title: string; - description: string; - }; -} - -const commonTitlePart = - " | Ethereum development environment for professionals by Nomic Foundation"; - -const SEO = ({ seo }: Props) => { - const title = `${seo.title}${commonTitlePart}`; - return ( - - {title} - - - - - - - - - - ); -}; - -export default SEO; diff --git a/docs/src/components/Searching.tsx b/docs/src/components/Searching.tsx deleted file mode 100644 index 13138675d6..0000000000 --- a/docs/src/components/Searching.tsx +++ /dev/null @@ -1,97 +0,0 @@ -import React from "react"; -import Head from "next/head"; -import { DocSearch } from "@docsearch/react"; -import "@docsearch/css"; -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../themes"; - -const appId = process.env.NEXT_PUBLIC_ALGOLIA_APP_ID as string; -const apiKey = process.env.NEXT_PUBLIC_ALGOLIA_API_KEY as string; -const indexName = process.env.NEXT_PUBLIC_ALGOLIA_INDEX_NAME as string; - -const Container = styled.div` - .DocSearch-Button { - border-radius: 4px; - border: 1px solid ${tm(({ colors }) => colors.codeBlockBorder)}; - width: 200px; - font-size: 15px; - font-weight: 300; - } - - .DocSearch-Button-Keys { - display: none; - } - - display: flex; - --docsearch-searchbox-shadow-custom: ${tm( - ({ colors }) => colors.searchShadow - )}; - --docsearch-searchbox-background: ${tm(({ colors }) => colors.neutral0)}; - --docsearch-primary-color: ${tm(({ colors }) => colors.accent700)}; - --docsearch-text-color: ${tm(({ colors }) => colors.neutral800)}; - --docsearch-searchbox-focus-background: ${tm( - ({ colors }) => colors.neutral0 - )}; - --docsearch-highlight-color: var(--docsearch-primary-color); - --docsearch-muted-color: var(--docsearch-text-color); - --docsearch-searchbox-shadow: inset 0 0 0 2px - var(--docsearch-searchbox-shadow-custom); - --docsearch-spacing: 12px; - - ${tmSelectors.dark} { - --docsearch-searchbox-background: ${tmDark( - ({ colors }) => colors.neutral0 - )}; - --docsearch-primary-color: ${tmDark(({ colors }) => colors.accent700)}; - --docsearch-text-color: ${tmDark(({ colors }) => colors.neutral800)}; - --docsearch-searchbox-focus-background: ${tmDark( - ({ colors }) => colors.neutral0 - )}; - --docsearch-searchbox-shadow-custom: ${tmDark( - ({ colors }) => colors.searchShadow - )}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - --docsearch-searchbox-background: ${tmDark( - ({ colors }) => colors.neutral0 - )}; - --docsearch-primary-color: ${tmDark(({ colors }) => colors.accent700)}; - --docsearch-text-color: ${tmDark(({ colors }) => colors.neutral800)}; - --docsearch-searchbox-focus-background: ${tmDark( - ({ colors }) => colors.neutral0 - )}; - --docsearch-searchbox-shadow-custom: ${tmDark( - ({ colors }) => colors.searchShadow - )}; - } - } - .landing & { - visibility: hidden; - } -`; - -const Searching = () => { - return ( - - - {/** - * By adding this snippet to the head, we can hint the browser that the website will load data from Algolia, - * and allows it to preconnect to the DocSearch cluster. It makes the first query faster, - * especially on mobile. - * - * But we don't want to affect landing pages where we don't use searching. So we adding this only on pages - * where we actually using this - */} - - - - - ); -}; - -export default Searching; diff --git a/docs/src/components/Section.tsx b/docs/src/components/Section.tsx deleted file mode 100644 index 1c531dfc8e..0000000000 --- a/docs/src/components/Section.tsx +++ /dev/null @@ -1,42 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import { media } from "../themes"; - -const Container = styled.section` - width: 100%; - box-sizing: border-box; - position: relative; - padding: 0 24px; - max-width: 960px; - ${media.md} { - padding: 0; - } - &.clear-padding { - padding: unset; - max-width: unset; - } -`; - -type Props = React.PropsWithChildren<{ - clearPadding?: boolean; - id?: string | number; -}>; - -const Section = ({ children, clearPadding = false, id }: Props) => { - const containerProps = { - // eslint-disable-next-line - [id ? "id" : ""]: id, - }; - delete containerProps[""]; - - return ( - - {children} - - ); -}; - -export default Section; diff --git a/docs/src/components/Sidebar.tsx b/docs/src/components/Sidebar.tsx deleted file mode 100644 index 7e6516f780..0000000000 --- a/docs/src/components/Sidebar.tsx +++ /dev/null @@ -1,214 +0,0 @@ -import React from "react"; -import { useRouter } from "next/router"; -import Link from "next/link"; - -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../themes"; -import { IDocumentationSidebarStructure } from "./types"; - -interface Props { - elementsList: IDocumentationSidebarStructure; - closeSidebar?: () => void; -} - -const Container = styled.ul` - padding: 16px 0; - width: 100%; - display: flex; - flex-direction: column; - list-style-type: none; - color: ${tm(({ colors }) => colors.neutral800)}; - font-weight: 400; - font-size: 15px; - line-height: 28px; - letter-spacing: 0em; - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - } -`; - -const SidebarLinkWrapper = styled.a` - cursor: pointer; - width: 100%; - - &:hover { - color: ${tm(({ colors }) => colors.accent700)}; - } - - &[data-active="true"] { - color: ${tm(({ colors }) => colors.accent700)}; - &.heading { - border-left: 4px solid ${tm(({ colors }) => colors.transparent)}; - } - } - &[data-anchor="true"][data-active="true"] { - color: ${tm(({ colors }) => colors.accent700)}; - background-color: ${tm(({ colors }) => colors.accent200)}; - } - - ${tmSelectors.dark} { - &[data-active="true"] { - color: ${tmDark(({ colors }) => colors.accent700)}; - border-color: ${tmDark(({ colors }) => colors.accent700)}; - } - &[data-anchor="true"][data-active="true"] { - color: ${tmDark(({ colors }) => colors.accent700)}; - background-color: ${tmDark(({ colors }) => colors.accent200)}; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - &[data-active="true"] { - color: ${tmDark(({ colors }) => colors.accent700)}; - border-color: ${tmDark(({ colors }) => colors.accent700)}; - } - &[data-anchor="true"][data-active="true"] { - color: ${tmDark(({ colors }) => colors.accent700)}; - background-color: ${tmDark(({ colors }) => colors.accent200)}; - } - } - } -`; - -const SidebarItem = styled.li` - display: flex; - flex-direction: column; - & ${SidebarLinkWrapper} { - padding: 4px 28px; - &[data-active="true"] { - background-color: ${tm(({ colors }) => colors.accent200)}; - &.heading { - background-color: unset; - } - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.accent200)}; - &.heading { - background-color: unset; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.accent200)}; - &.heading { - background-color: unset; - } - } - } - } - } - &.group { - margin-top: 16px; - } -`; - -const SidebarHeading = styled.p` - font-weight: 700; - font-size: 17px; - line-height: 25px; - padding: 4px 32px; - border-left: 4px solid ${tm(({ colors }) => colors.transparent)}; - - &[data-child-active="true"] { - color: ${tm(({ colors }) => colors.accent700)}; - border-color: ${tm(({ colors }) => colors.accent700)}; - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.accent700)}; - border-color: ${tmDark(({ colors }) => colors.accent700)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.accent700)}; - border-color: ${tmDark(({ colors }) => colors.accent700)}; - } - } - } -`; - -const SidebarSubLinksList = styled.ul` - display: flex; - flex-direction: column; - line-height: 28px; - list-style-type: none; - & li > a { - width: 100%; - display: block; - } - & ${SidebarLinkWrapper} { - padding: 0.5px 16px 0.5px 64px; - } -`; - -const Sidebar = ({ elementsList, closeSidebar }: Props) => { - const router = useRouter(); - return ( - - {elementsList?.map((sidebarItem) => { - const isLinkActive: boolean = - sidebarItem.href !== undefined && - router?.asPath.indexOf(sidebarItem.href) > -1; - const hasActiveChild = - sidebarItem?.children?.find( - (child) => - router?.asPath.replace(/\//g, "") === - child.href.replace(/\//g, "") - ) !== undefined; - return ( - - {sidebarItem.href !== undefined ? ( - - - {sidebarItem.label} - - - ) : ( - - {sidebarItem.label} - - )} - - {sidebarItem?.children && ( - - {sidebarItem.children.map((subItem) => { - const isSubLinkActive = - router?.asPath.replace(/\//g, "") === - subItem.href.replace(/\//g, ""); - - const isAnchor = subItem.href.includes("#"); - return ( - // eslint-disable-next-line -
  • - - - {subItem.label} - - -
  • - ); - })} -
    - )} -
    - ); - })} -
    - ); -}; - -export default Sidebar; diff --git a/docs/src/components/ThemeSwitchButton.tsx b/docs/src/components/ThemeSwitchButton.tsx deleted file mode 100644 index e473bde339..0000000000 --- a/docs/src/components/ThemeSwitchButton.tsx +++ /dev/null @@ -1,101 +0,0 @@ -import React, { useContext } from "react"; -import { styled } from "linaria/react"; -import Image from "next/image"; -import { - media, - ThemeContext, - ThemesEnum, - tm, - tmDark, - tmSelectors, -} from "../themes"; -import ThemeSwitcher from "../assets/icons/theme-switcher.svg"; -import ThemeSwitcherDark from "../assets/icons/theme-switcher-dark.svg"; - -const ThemeButton = styled.button` - font-size: 15px; - line-height: 13px; - display: none; - justify-content: flex-end; - align-items: center; - background-color: ${tm(({ colors }) => colors.transparent)}; - color: ${tm(({ colors }) => colors.neutral900)}; - border: none; - cursor: pointer; - transform-origin: center; - min-width: 45px; - transition: transform ease-in-out 0.25s; - &:hover { - opacity: 0.8; - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.autoThemeButton)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.autoThemeButton)}; - } - } - ${media.md} { - display: flex; - } - &[data-mobile="true"] { - display: flex; - } -`; - -const ThemeIconWrapper = styled.div` - transition: transform ease-in-out 0.25s; - & > span { - display: none; - } - & > .theme-switcher { - position: relative; - bottom: -3px; - } - & > .light { - display: inline; - } - ${tmSelectors.dark} { - & > .light { - display: none; - } - & > .dark { - display: inline; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - & > .light { - display: none; - } - & > .dark { - display: inline; - } - } - } -`; - -const ThemeSwitchButton = ({ isMobile = false }: { isMobile?: boolean }) => { - const { theme, changeTheme } = useContext(ThemeContext); - - return ( - - {theme === ThemesEnum.AUTO && "A"} - - - theme-switcher - - - theme-switcher - - - - ); -}; - -export default ThemeSwitchButton; diff --git a/docs/src/components/landingBlocks/BuiltByBlock.stories.tsx b/docs/src/components/landingBlocks/BuiltByBlock.stories.tsx deleted file mode 100644 index c2bd776aa6..0000000000 --- a/docs/src/components/landingBlocks/BuiltByBlock.stories.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from "react"; - -import BuiltByBlock from "./BuiltByBlock"; -import homepageContent from "../../content/home"; - -export default { - title: "Landing Blocks/Built by", -}; - -export const Default = () => ( - -); diff --git a/docs/src/components/landingBlocks/BuiltByBlock.tsx b/docs/src/components/landingBlocks/BuiltByBlock.tsx deleted file mode 100644 index d8fd9f3340..0000000000 --- a/docs/src/components/landingBlocks/BuiltByBlock.tsx +++ /dev/null @@ -1,94 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import Image from "next/image"; - -import Section from "../Section"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; - -interface Props { - content: { title: string; imageUrl: string; imageDarkUrl: string }; -} - -const Container = styled.div` - margin-bottom: 234px; - text-align: center; - - ${media.md} { - margin-bottom: 195px; - display: flex; - justify-content: center; - align-items: center; - } - & .dark { - display: none; - } - ${tmSelectors.dark} { - & .light { - display: none; - } - & .dark { - display: inline; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - & .light { - display: none; - } - & .dark { - display: inline; - } - } - } -`; - -const Title = styled.h2` - margin-bottom: 16px; - font-size: 18px; - line-height: 40px; - font-weight: 400; - font-family: ChivoLight, sans-serif; - color: ${tm(({ colors }) => colors.neutral900)}; - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } - - ${media.md} { - margin-right: 22px; - margin-top: 10px; - font-size: 24px; - } -`; - -const BuiltByBlock = ({ content }: Props) => { - return ( -
    - - {content.title} - - Nomic Foundation logo - - - Nomic Foundation logo - - -
    - ); -}; - -export default BuiltByBlock; diff --git a/docs/src/components/landingBlocks/GetStartedBlock.stories.tsx b/docs/src/components/landingBlocks/GetStartedBlock.stories.tsx deleted file mode 100644 index 7f3293a737..0000000000 --- a/docs/src/components/landingBlocks/GetStartedBlock.stories.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from "react"; - -import homepageContent from "../../content/home"; -import GetStartedBlock from "./GetStartedBlock"; - -export default { - title: "Landing Blocks/Get Started", -}; - -export const Default = () => ( - -); diff --git a/docs/src/components/landingBlocks/GetStartedBlock.tsx b/docs/src/components/landingBlocks/GetStartedBlock.tsx deleted file mode 100644 index 5499267c3c..0000000000 --- a/docs/src/components/landingBlocks/GetStartedBlock.tsx +++ /dev/null @@ -1,216 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import Image from "next/image"; - -import { breakpoints, media, tm, tmDark, tmSelectors } from "../../themes"; -import useWindowSize from "../../hooks/useWindowSize"; -import CTA from "../ui/CTA"; -import Section from "../Section"; -import { CTAType } from "../ui/types"; -import bl from "../../assets/get-started/bl.svg"; -import br from "../../assets/get-started/br.svg"; - -interface Props { - content: { - title: string; - subtitle: string; - cta: CTAType; - }; -} - -const GetStartedBlockStyled = styled.section` - width: 100%; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - padding: 64px 16px; - height: 724px; - overflow: hidden; - background-color: ${tm(({ colors }) => colors.neutral0)}; - position: relative; - margin: 48px 0; - ${media.md} { - margin: unset; - height: 792px; - } - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - } -`; - -const StyledBackground = styled.div` - position: absolute; - left: 0; - top: 0; - background: ${tm( - ({ colors }) => - `linear-gradient(254.24deg, ${colors.complementary600} 0%, ${colors.accent100} 100%, ${colors.accent100} 100%)` - )}; - height: 100%; - width: 100%; - ${tmSelectors.dark} { - mix-blend-mode: color-dodge; - background: ${tmDark( - ({ colors }) => - `linear-gradient(254.24deg, ${colors.complementary600} 0%, ${colors.accent100} 100%, ${colors.accent100} 100%)` - )}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - mix-blend-mode: color-dodge; - background: ${tmDark( - ({ colors }) => - `linear-gradient(254.24deg, ${colors.complementary600} 0%, ${colors.accent100} 100%, ${colors.accent100} 100%)` - )}; - } - } -`; - -const StyledTopGradient = styled.div` - width: 100%; - height: 50%; - top: 0; - left: 0; - position: absolute; - background: ${tm(({ colors }) => colors.getStartedTopBackground)}; - ${tmSelectors.dark} { - background: ${tmDark(({ colors }) => colors.getStartedTopBackground)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background: ${tmDark(({ colors }) => colors.getStartedTopBackground)}; - } - } -`; - -const StyledBottomGradient = styled.div` - width: 100%; - height: 50%; - bottom: 0; - left: 0; - position: absolute; - background: ${tm(({ colors }) => colors.getStartedBottomBackground)}; - transform: rotate(180deg); - ${tmSelectors.dark} { - background: ${tmDark(({ colors }) => colors.getStartedBottomBackground)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background: ${tmDark(({ colors }) => colors.getStartedBottomBackground)}; - } - } -`; - -const TextureBrickWrapper = styled.div` - position: absolute; - right: 0; - &.left { - left: 0; - right: auto; - } - ${tmSelectors.dark} { - filter: invert(0.5); - } - ${media.mqDark} { - ${tmSelectors.auto} { - filter: invert(0.5); - } - } -`; - -const ContentBlock = styled.section` - display: flex; - flex-direction: column; - align-items: center; - z-index: 1; - color: ${tm(({ colors }) => colors.neutral900)}; - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } -`; - -const Title = styled.h1` - font-family: ChivoBold, sans-serif; - font-weight: normal; - font-size: 39px; - line-height: 41px; - letter-spacing: -0.01em; - text-align: center; - max-width: 642px; - - ${media.md} { - font-size: 45px; - line-height: 50px; - letter-spacing: 0; - } -`; - -const Subtitle = styled.p` - font-family: ChivoLight, sans-serif; - font-size: 20px; - line-height: 31px; - letter-spacing: 0; - text-align: center; - margin-top: 24px; - margin-bottom: 48px; - ${media.md} { - font-size: 24px; - line-height: 40px; - margin-top: 32px; - margin-bottom: 64px; - } -`; - -const CTAWrapper = styled.div` - filter: drop-shadow(0px 1px 2px rgba(10, 10, 10, 0.1)) - drop-shadow(0px 8px 30px rgba(184, 113, 255, 0.1)); -`; - -const Background = () => { - const windowSize = useWindowSize(); - const isDesktop = breakpoints.md <= windowSize.width; - return ( - - {isDesktop && ( - - decorations - - )} - - decorations - - - - - ); -}; - -const GetStartedBlock = ({ content }: Props) => { - return ( -
    - - - - {content.title} - {content.subtitle} - - {content.cta.title} - - - -
    - ); -}; - -export default GetStartedBlock; diff --git a/docs/src/components/landingBlocks/HeroBlock.stories.tsx b/docs/src/components/landingBlocks/HeroBlock.stories.tsx deleted file mode 100644 index ae283d837e..0000000000 --- a/docs/src/components/landingBlocks/HeroBlock.stories.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from "react"; -import HeroBlock from "./HeroBlock"; -import homepageContent from "../../content/home"; - -const { heroBlockContent } = homepageContent; - -export default { - title: "Landing Blocks/Hero", -}; - -export const Default = () => { - return ; -}; diff --git a/docs/src/components/landingBlocks/HeroBlock.tsx b/docs/src/components/landingBlocks/HeroBlock.tsx deleted file mode 100644 index 5b30532280..0000000000 --- a/docs/src/components/landingBlocks/HeroBlock.tsx +++ /dev/null @@ -1,118 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import Section from "../Section"; -import CTA from "../ui/CTA"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; -import { CTAType } from "../ui/types"; -import DesktopAnimation from "../DesktopAnimation"; -import MobileAnimation from "../MobileAnimation"; - -interface Props { - content: { - title: string; - tagline: string; - cta: CTAType; - }; -} - -const Container = styled.section` - width: 100%; - display: flex; - flex-direction: column; - margin-top: 40px; - color: ${tm(({ colors }) => colors.neutral900)}; - margin-bottom: 300px; - ${media.md} { - flex-direction: row; - justify-content: space-between; - margin-bottom: 280px; - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } -`; - -const Block = styled.div` - width: 100%; - display: flex; - flex-direction: column; - padding: 0 0 24px; - min-height: 100px; - &.content { - z-index: 2; - } - & svg { - margin: 0 auto; - } - &.animation-container { - height: calc(100vh - 700px); - } - ${media.md} { - width: 40%; - &:first-child { - width: 60%; - } - padding: 0; - position: relative; - &.animation-container { - height: auto; - } - } -`; - -const TagLine = styled.span` - font-family: ChivoLight, sans-serif; - margin-bottom: 24px; - font-size: 22px; - line-height: 32px; - letter-spacing: -0.02em; - text-align: left; - ${media.md} { - font-size: 32px; - line-height: 32px; - letter-spacing: 0; - text-align: left; - margin-top: 32px; - } -`; - -const Title = styled.h1` - margin-bottom: 48px; - font-size: 40px; - line-height: 45px; - letter-spacing: -0.01em; - font-family: ChivoBold, sans-serif; - font-weight: normal; - ${media.md} { - margin-bottom: 64px; - font-size: 72px; - line-height: 72px; - letter-spacing: 0; - } -`; - -const HeroBlock = ({ content }: Props) => { - return ( -
    - - - {content.tagline} - {content.title} - {content.cta.title} - - - - - - -
    - ); -}; - -export default HeroBlock; diff --git a/docs/src/components/landingBlocks/ReviewsBlock.stories.tsx b/docs/src/components/landingBlocks/ReviewsBlock.stories.tsx deleted file mode 100644 index ae8360c59a..0000000000 --- a/docs/src/components/landingBlocks/ReviewsBlock.stories.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from "react"; - -import ReviewsBlock from "./ReviewsBlock"; -import homepageContent from "../../content/home"; - -export default { - title: "Landing Blocks/Reviews", -}; - -export const Default = () => ( - -); diff --git a/docs/src/components/landingBlocks/ReviewsBlock.tsx b/docs/src/components/landingBlocks/ReviewsBlock.tsx deleted file mode 100644 index 6d985676c2..0000000000 --- a/docs/src/components/landingBlocks/ReviewsBlock.tsx +++ /dev/null @@ -1,343 +0,0 @@ -import React from "react"; -import Image from "next/image"; -import { Carousel } from "react-responsive-carousel"; -import { styled } from "linaria/react"; - -import Section from "../Section"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; -import CarouselArrow from "../../assets/icons/carousel-arrow"; - -interface Props { - content: Array<{ - name: string; - position: string; - personImage: StaticImageData; - companyImage: string; - alt: string; - comment: string; - }>; -} - -const SliderWrapper = styled.div` - margin-bottom: 240px; - padding: 0 24px; - - ${media.md} { - padding: 0; - - & .carousel:before, - .carousel:after { - content: ""; - width: 36px; - position: absolute; - top: 0; - min-height: 480px; - border: 0.1rem solid ${tm(({ colors }) => colors.neutral600)}; - ${tmSelectors.dark} { - border-color: ${tmDark(({ colors }) => colors.neutral600)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - border-color: ${tmDark(({ colors }) => colors.neutral600)}; - } - } - } - - & .carousel:after { - right: 0; - border-left: none; - } - - & .carousel:before { - left: 0; - border-right: none; - } - } - - & .carousel { - position: relative; - width: 100%; - } - - & .carousel .slider-wrapper { - overflow: hidden; - margin: auto; - width: 100%; - transition: height 0.15s ease-in; - } - - & .carousel .slider-wrapper.axis-horizontal .slider { - -ms-box-orient: horizontal; - display: -webkit-box; - display: -moz-box; - display: -ms-flexbox; - display: -moz-flex; - display: -webkit-flex; - display: flex; - } - - & .carousel .slide { - min-width: 100%; - margin: 0; - position: relative; - text-align: center; - list-style: none; - } -`; - -const SlideContainer = styled.div` - display: flex; - flex-direction: column; - ${media.md} { - padding: 100px 82px; - height: 490px; - flex-direction: row; - } -`; - -const ImageWithCaptionContainer = styled.div` - margin-bottom: 42px; - display: flex; - justify-content: center; - width: 100%; - - ${media.md} { - width: 29%; - align-items: center; - padding: 0 10px; - flex-direction: column; - margin: 0 40px 0 0; - } -`; - -const PersonImage = styled.div` - min-height: 110px; - min-width: 110px; - width: 110px; - height: 110px; - border-radius: 100px; - overflow: hidden; - - ${media.md} { - min-height: 150px; - min-width: 150px; - width: 150px; - height: 150px; - margin-bottom: 10px; - } -`; - -const PersonCaption = styled.div` - margin-left: 30px; - text-align: left; - font-family: ChivoRegular, sans-serif; - font-weight: normal; - font-size: 15px; - line-height: 24px; - color: ${tm(({ colors }) => colors.neutral900)}; - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } - - ${media.md} { - margin-left: 0; - text-align: center; - margin-top: 24px; - - & > p { - display: inline; - } - - & > img { - display: block; - margin: 10px auto; - max-height: 40px; - max-width: 100px; - } - } -`; - -const CommentContainer = styled.p` - text-align: left; - font-family: ChivoLight, sans-serif; - font-weight: 400; - font-size: 15px; - line-height: 28px; - color: ${tm(({ colors }) => colors.neutral600)}; - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - } - ${media.md} { - width: 70%; - padding: 24px; - align-self: center; - } -`; - -const SliderArrow = styled.button` - position: absolute; - width: 24px; - height: 24px; - display: flex; - justify-content: center; - align-items: center; - top: 30px; - z-index: 1; - background-color: ${tm(({ colors }) => colors.neutral0)}; - border: none; - box-shadow: 0 3px 6px ${tm(({ colors }) => colors.sliderButtonShadow)}; - border-radius: 30px; - cursor: pointer; - transition: all 0.2s ease-in-out; - border: 1px solid ${tm(({ colors }) => colors.transparent)}; - - ${tmSelectors.dark} { - border-color: ${tmDark(({ colors }) => colors.neutral600)}; - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - border-color: ${tmDark(({ colors }) => colors.neutral600)}; - } - } - - & > span { - top: 2px; - right: 2px; - } - - &.right { - right: -20px; - transform: scaleX(-1); - } - - &.left { - left: -20px; - } - - & > svg { - width: 4px; - height: 8px; - } - - ${media.md} { - width: 48px; - height: 48px; - top: 210px; - & > svg { - width: 8px; - height: 17px; - } - - &:hover { - top: 205px; - box-shadow: 0 8px 20px - ${tm(({ colors }) => colors.sliderButtonHoverShadow)}; - } - - &:active { - background-color: ${tm(({ colors }) => colors.neutral100)}; - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.neutral100)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.neutral100)}; - } - } - } - - &.right { - right: -80px; - } - - &.left { - left: -80px; - } - } -`; - -const NamePositionBlock = styled.div` - display: flex; - flex-direction: column; - margin-bottom: 12px; - ${media.md} { - align-items: center; - } -`; - -const ReviewsBlock = ({ content }: Props) => { - return ( -
    - - - hasNext && ( - - - - ) - } - renderArrowPrev={(clickHandler, hasPrev, label) => - hasPrev && ( - - - - ) - } - > - {content.map((item) => ( - - - - Picture of the author - - - -

    {item.name},

    -

    {item.position}

    -
    - - company-logo -
    -
    - {item.comment} -
    - ))} -
    -
    -
    - ); -}; - -export default ReviewsBlock; diff --git a/docs/src/components/landingBlocks/ToolsBlock.stories.tsx b/docs/src/components/landingBlocks/ToolsBlock.stories.tsx deleted file mode 100644 index ca7369c35e..0000000000 --- a/docs/src/components/landingBlocks/ToolsBlock.stories.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from "react"; - -import homepageContent from "../../content/home"; -import ToolsBlock from "./ToolsBlock"; - -export default { - title: "Landing Blocks/Hero", -}; - -export const Default = () => ( - -); diff --git a/docs/src/components/landingBlocks/ToolsBlock.styled.tsx b/docs/src/components/landingBlocks/ToolsBlock.styled.tsx deleted file mode 100644 index b19b643578..0000000000 --- a/docs/src/components/landingBlocks/ToolsBlock.styled.tsx +++ /dev/null @@ -1,485 +0,0 @@ -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; - -const Container = styled.div` - margin-bottom: 162px; - display: flex; - flex-direction: column; - position: relative; - margin-top: 150px; - &:before { - width: 100%; - height: 32px; - top: -32px; - content: ""; - position: absolute; - background: ${tm(({ colors }) => colors.transparent)}; - border-top: 1px solid ${tm(({ colors }) => colors.toolsBlockBorder)}; - border-right: 1px solid ${tm(({ colors }) => colors.toolsBlockBorder)}; - ${tmSelectors.dark} { - border-color: ${tmDark(({ colors }) => colors.toolsBlockBorder)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - border-color: ${tmDark(({ colors }) => colors.toolsBlockBorder)}; - } - } - } - - &:after { - content: ""; - position: absolute; - height: 32px; - width: 100%; - right: 0; - bottom: -44px; - border-top: 1px solid ${tm(({ colors }) => colors.toolsBlockBorder)}; - border-right: 1px solid ${tm(({ colors }) => colors.toolsBlockBorder)}; - transform: rotate(180deg); - ${tmSelectors.dark} { - border-color: ${tmDark(({ colors }) => colors.toolsBlockBorder)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - border-color: ${tmDark(({ colors }) => colors.toolsBlockBorder)}; - } - } - } - - ${media.md} { - flex-direction: row; - margin-bottom: 200px; - margin-top: 150px; - - &:before { - width: 36px; - height: 100%; - border-left: 1px solid ${tm(({ colors }) => colors.toolsBlockBorder)}; - border-bottom: 1px solid ${tm(({ colors }) => colors.toolsBlockBorder)}; - border-right: none; - top: 0; - ${tmSelectors.dark} { - border-color: ${tmDark(({ colors }) => colors.toolsBlockBorder)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - border-color: ${tmDark(({ colors }) => colors.toolsBlockBorder)}; - } - } - } - - &:after { - top: 0; - width: 36px; - height: 100%; - bottom: unset; - border-left: 1px solid ${tm(({ colors }) => colors.toolsBlockBorder)}; - border-bottom: 1px solid ${tm(({ colors }) => colors.toolsBlockBorder)}; - border-right: none; - ${tmSelectors.dark} { - border-color: ${tmDark(({ colors }) => colors.toolsBlockBorder)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - border-color: ${tmDark(({ colors }) => colors.toolsBlockBorder)}; - } - } - } - } -`; - -const ToolsIconsBlock = styled.div` - position: relative; - padding-bottom: 40px; - - &:before { - position: absolute; - content: ""; - width: 172px; - height: 1px; - left: calc(50% - 86px); - bottom: 0; - background: ${tm(({ colors }) => colors.toolsBlockBorder)}; - ${tmSelectors.dark} { - background: ${tmDark(({ colors }) => colors.toolsBlockBorder)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background: ${tmDark(({ colors }) => colors.toolsBlockBorder)}; - } - } - } - - &:after { - position: absolute; - content: ""; - bottom: -5px; - right: calc(50% - 5px); - width: 10px; - height: 10px; - background: ${tm(({ colors }) => colors.neutral0)}; - border-top: 1px solid ${tm(({ colors }) => colors.toolsBlockBorder)}; - border-left: 1px solid ${tm(({ colors }) => colors.toolsBlockBorder)}; - transform: translateY(0) rotate(225deg); - ${tmSelectors.dark} { - background: ${tmDark(({ colors }) => colors.neutral0)}; - border-color: ${tmDark(({ colors }) => colors.toolsBlockBorder)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background: ${tmDark(({ colors }) => colors.neutral0)}; - border-color: ${tmDark(({ colors }) => colors.toolsBlockBorder)}; - } - } - } - - ${media.md} { - width: 50%; - padding: 40px; - - &:before { - right: 0; - top: calc(50% - 116px); - left: unset; - height: 232px; - width: 1px; - background: ${tm(({ colors }) => colors.toolsBlockBorder)}; - ${tmSelectors.dark} { - background: ${tmDark(({ colors }) => colors.toolsBlockBorder)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background: ${tmDark(({ colors }) => colors.toolsBlockBorder)}; - } - } - } - - &:after { - top: calc(50% - 5px); - right: -5px; - bottom: unset; - transform: rotate(135deg); - } - } -`; - -const IconsBlockTitle = styled.h2` - margin-bottom: 24px; - font-family: ChivoRegular, sans-serif; - font-weight: 400; - font-size: 20px; - line-height: 24px; - letter-spacing: 4px; - text-transform: uppercase; - color: ${tm(({ colors }) => colors.neutral900)}; - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } -`; - -const ButtonsContainer = styled.div` - height: 208px; - display: grid; - grid-template-columns: 1fr 1fr; - grid-row-gap: 12px; - justify-content: space-around; -`; - -const ButtonContainer = styled.div` - position: relative; - height: 88px; - max-width: 162px; - width: 100%; - justify-self: center; - padding: 12px 0 12px 6px; - display: flex; - border-radius: 4px; - align-items: center; - white-space: nowrap; - cursor: pointer; - transition: all 0.1s ease-in-out; - - &.active { - box-shadow: 6px -2px 10px ${tm(({ colors }) => colors.toolsBoxShadow1)}, - -6px 2px 10px ${tm(({ colors }) => colors.toolsBoxShadow2)}; - } - - & svg { - width: 48px; - height: 48px; - transition: all 0.2s ease-out; - border-radius: 8px; - padding: 8px; - box-shadow: 0 1px 2px ${tm(({ colors }) => colors.sliderButtonHoverShadow)}; - - &.active { - transform-origin: center; - transform: scale(1.15); - box-shadow: 0 1px 2px ${tm(({ colors }) => colors.transparent)}; - padding: 0px; - } - } - - ${media.md} { - & svg { - width: 72px; - height: 72px; - &.active { - width: 72px; - height: 72px; - padding: 0px; - transform: scale(1); - } - } - } - .dark { - display: none; - } - - ${tmSelectors.dark} { - .light { - display: none; - } - .dark { - display: inline; - } - &.active { - box-shadow: 0px 1px 8px ${tm(({ colors }) => colors.toolsBoxShadowDark)}; - } - & svg { - box-shadow: 0px 1px 8px ${tm(({ colors }) => colors.toolsBoxShadowDark)}; - &.active { - box-shadow: 0 1px 2px ${tm(({ colors }) => colors.transparent)}; - } - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - .light { - display: none; - } - .dark { - display: inline; - } - &.active { - box-shadow: 0px 1px 8px ${tm(({ colors }) => colors.toolsBoxShadowDark)}; - } - & svg { - box-shadow: 0px 1px 8px ${tm(({ colors }) => colors.toolsBoxShadowDark)}; - &.active { - box-shadow: 0 1px 2px ${tm(({ colors }) => colors.transparent)}; - } - } - } - } -`; - -const ButtonNameContainer = styled.div` - margin-left: 16px; -`; - -const ButtonCompanyName = styled.span` - font-size: 14px; - font-family: ChivoLight, sans-serif; - color: ${tm(({ colors }) => colors.neutral600)}; - font-weight: 800; - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral600)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral600)}; - } - } -`; - -const ButtonToolName = styled.span` - height: 24px; - font-size: 15px; - font-family: ChivoLight, sans-serif; - color: ${tm(({ colors }) => colors.neutral900)}; - line-height: 24px; - font-weight: 800; - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } -`; - -const DescriptionContainer = styled.div` - margin-top: 52px; - padding: 0 24px; - - ${media.md} { - width: 50%; - padding: 0 50px; - } -`; - -const DescriptionHeaderContainer = styled.div` - display: flex; - flex-direction: column; - align-items: flex-start; - margin-bottom: 16px; - font-family: ChivoLight, sans-serif; - font-weight: 600; - - ${media.md} { - flex-direction: row; - } -`; - -const DescriptionTitle = styled.h3` - margin-bottom: 8px; - font-size: 24px; - white-space: nowrap; - line-height: 32px; - color: ${tm(({ colors }) => colors.neutral600)}; - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral600)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral600)}; - } - } -`; - -const DescriptionTitleTool = styled.span` - color: ${tm(({ colors }) => colors.neutral900)}; - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } -`; - -const DescriptionMottoContainer = styled.div` - padding: 0 12px; - height: 27px; - font-size: 13px; - text-transform: uppercase; - line-height: 27px; - letter-spacing: 1px; - font-family: ChivoLight, sans-serif; - font-weight: 600; - color: ${tm(({ colors }) => colors.neutral600)}; - border-radius: 8px 0; - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral600)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral600)}; - } - } - - &.runner { - background-color: ${tm(({ colors }) => colors.mottoRunnerBackground)}; - } - - &.network { - background-color: ${tm(({ colors }) => colors.mottoNetworkBackground)}; - } - - &.ignition { - background-color: ${tm(({ colors }) => colors.mottoIgnitionBackground)}; - } - - &.vscode { - background-color: ${tm(({ colors }) => colors.mottoVscodeBackground)}; - } - - ${media.md} { - margin-left: 24px; - } -`; - -const DescriptionText = styled.p` - margin-bottom: 24px; - width: 100%; - font-size: 15px; - line-height: 28px; - font-family: ChivoLight, sans-serif; - color: ${tm(({ colors }) => colors.neutral600)}; - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral600)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral600)}; - } - } -`; - -const DescriptionLink = styled.a` - position: relative; - font-size: 15px; - font-weight: 500; - color: ${tm(({ colors }) => colors.neutral600)}; - &:hover { - opacity: 0.8; - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral600)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral600)}; - } - } - - &:after { - content: ""; - position: absolute; - width: 7px; - height: 7px; - background: ${tm(({ colors }) => colors.transparent)}; - border-top: 1px solid ${tm(({ colors }) => colors.neutral600)}; - border-left: 1px solid ${tm(({ colors }) => colors.neutral600)}; - right: -18px; - top: calc(50% - 3px); - transform: rotate(135deg); - transition: all 0.1s ease-in-out; - ${tmSelectors.dark} { - border-color: ${tmDark(({ colors }) => colors.neutral600)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - border-color: ${tmDark(({ colors }) => colors.neutral600)}; - } - } - } -`; - -const ToolsBlockStyled = { - Container, - ToolsIconsBlock, - IconsBlockTitle, - ButtonsContainer, - ButtonContainer, - ButtonNameContainer, - ButtonCompanyName, - ButtonToolName, - DescriptionContainer, - DescriptionHeaderContainer, - DescriptionTitle, - DescriptionTitleTool, - DescriptionMottoContainer, - DescriptionText, - DescriptionLink, -}; - -export default ToolsBlockStyled; diff --git a/docs/src/components/landingBlocks/ToolsBlock.tsx b/docs/src/components/landingBlocks/ToolsBlock.tsx deleted file mode 100644 index e45c498f65..0000000000 --- a/docs/src/components/landingBlocks/ToolsBlock.tsx +++ /dev/null @@ -1,184 +0,0 @@ -import { useRouter } from "next/router"; -import React, { useEffect, useState } from "react"; -import { toolRegExp } from "../../config"; - -import Section from "../Section"; -import { Tools } from "../ui/types"; -import ToolsBlockStyled from "./ToolsBlock.styled"; - -const { - Container, - ButtonContainer, - ButtonNameContainer, - ButtonCompanyName, - ButtonToolName, - ButtonsContainer, - DescriptionContainer, - DescriptionHeaderContainer, - DescriptionTitle, - DescriptionMottoContainer, - DescriptionTitleTool, - DescriptionText, - ToolsIconsBlock, - IconsBlockTitle, - DescriptionLink, -} = ToolsBlockStyled; - -interface InfoItem { - icon: React.FC; - iconDark: React.FC; - title: string; - value: Tools; - mottos: string[]; - description: string; - link: string; -} -interface BlockProps { - content: { - title: string; - companyName: string; - infoItems: InfoItem[]; - }; -} - -interface ToolProps { - content: - | { - icon: React.FC; - iconDark: React.FC; - title: string; - value: Tools; - mottos: string[]; - description: string; - link: string; - } - | undefined; - companyName: string; -} - -const ToolDescription = ({ content, companyName }: ToolProps) => { - const [currentMotto, setCurrentMotto] = useState( - (content && content.mottos[0]) || "" - ); - const [currentMottoClassname, setCurrentMottoClassname] = useState("runner"); - - useEffect(() => { - const timer = setTimeout(() => { - if (currentMotto && content) { - let currentIndex = content.mottos.findIndex( - (item) => item === currentMotto - ); - if (currentIndex + 1 === content.mottos.length) { - currentIndex = 0; - } else { - currentIndex += 1; - } - setCurrentMotto(content.mottos[currentIndex]); - } - }, 2000); - return () => { - clearTimeout(timer); - }; - // eslint-disable-next-line - }, [currentMotto]); - - useEffect(() => { - if (content) { - setCurrentMotto(content.mottos[0]); - switch (content.value) { - case Tools.RUNNER: { - setCurrentMottoClassname("runner"); - break; - } - case Tools.NETWORK: { - setCurrentMottoClassname("network"); - break; - } - case Tools.IGNITION: { - setCurrentMottoClassname("ignition"); - break; - } - case Tools.SOLIDITY: { - setCurrentMottoClassname("vscode"); - break; - } - default: { - setCurrentMottoClassname("runner"); - } - } - } - }, [content]); - - return content ? ( - - - - {companyName} - {` ${content.title}`} - - - # {currentMotto} - - -
    - {content.description} - Learn more -
    -
    - ) : null; -}; - -const ToolsBlock = ({ content }: BlockProps) => { - const [selectedTool, setSelectedTool] = useState(Tools.RUNNER); - const router = useRouter(); - - useEffect(() => { - const queryTool = toolRegExp.exec(router.asPath); - if (!queryTool) return; - const tool = queryTool[0].replace("tool=", "") as Tools; - setSelectedTool(tool); - }, [router.asPath]); - - return ( -
    - - - {content.title} - - {content.infoItems.map((button) => ( - setSelectedTool(button.value)} - key={button.value} - className={selectedTool === button.value ? "active" : ""} - > - - - - {content.companyName} -
    - {button.title} -
    -
    - ))} -
    -
    - item.value === selectedTool - )} - companyName={content.companyName} - /> -
    -
    - ); -}; - -export default ToolsBlock; diff --git a/docs/src/components/landingBlocks/TrustedTeamsBlock.stories.tsx b/docs/src/components/landingBlocks/TrustedTeamsBlock.stories.tsx deleted file mode 100644 index 940240a906..0000000000 --- a/docs/src/components/landingBlocks/TrustedTeamsBlock.stories.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from "react"; - -import TrustedTeamsBlock from "./TrustedTeamsBlock"; -import homepageContent from "../../content/home"; - -export default { - title: "Landing Blocks/Trusted teams", -}; - -export const Default = () => ( - -); diff --git a/docs/src/components/landingBlocks/TrustedTeamsBlock.tsx b/docs/src/components/landingBlocks/TrustedTeamsBlock.tsx deleted file mode 100644 index 0cdc6b3a68..0000000000 --- a/docs/src/components/landingBlocks/TrustedTeamsBlock.tsx +++ /dev/null @@ -1,216 +0,0 @@ -import React, { useMemo } from "react"; -import { styled } from "linaria/react"; -import Image from "next/image"; - -import { - TrustedTeamsLogos, - TrustedTeamsLogosDark, -} from "../../assets/trustedTeamsLogos/logos"; - -import { media, tm, tmDark, tmSelectors } from "../../themes"; -import Section from "../Section"; - -interface Props { - content: { title: string }; -} - -const Container = styled.section` - width: 100%; - margin-bottom: 120px; - display: flex; - flex-direction: column; - overflow: hidden; - ${media.md} { - margin-top: 40px; - } -`; - -const Title = styled.h2` - padding: 16px 20px; - margin-bottom: 48px; - text-align: center; - font-size: 28px; - line-height: 32px; - font-weight: 400; - letter-spacing: -0.01em; - font-family: ChivoBold, sans-serif; - font-weight: normal; - color: ${tm(({ colors }) => colors.neutral900)}; - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } - - ${media.md} { - margin-bottom: 88px; - font-size: 45px; - line-height: 50px; - letter-spacing: initial; - } -`; - -const LogosContainer = styled.div` - display: flex; - flex-direction: column; - &.dark { - display: none; - } - ${tmSelectors.dark} { - &.dark { - display: flex; - } - &.light { - display: none; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - &.dark { - display: flex; - } - &.light { - display: none; - } - } - } -`; - -const LogosRowContainer = styled.div` - display: flex; - width: 10000px; - - &:nth-child(-n + 3) { - display: none; - } - - ${media.md} { - &:nth-child(-n + 3) { - display: initial; - } - &:nth-last-child(-n + 5) { - display: none; - } - } -`; - -const LogosSubrowContainer = styled.div` - height: 72px; - display: flex; - align-items: center; - animation-duration: 50s; - animation-name: marquee; - animation-timing-function: linear; - animation-iteration-count: infinite; - animation-direction: initial; - float: left; - - &[data-reverted="true"] { - animation-direction: reverse; - } - - &.changed-speed { - animation-duration: 32s; - } - - ${media.md} { - height: 67px; - margin-bottom: 32px; - } - - .image-wrapper { - width: 100%; - margin: 0 20px; - height: 67px; - - ${media.md} { - height: initial; - margin: 0 50px; - } - } - - @keyframes marquee { - 0% { - transform: translateX(0); - } - - 100% { - transform: translateX(-100%); - } - } -`; - -const createLogosRows = ( - logosArray: Array<{ img: string; alt: string }>, - rowsAmount: number -) => { - const logosInRowAmount = Math.floor(logosArray.length / rowsAmount); - const logosRows = []; - - for (let i = 0; i < rowsAmount; i += 1) { - const rowImages = logosArray - .slice( - i * logosInRowAmount, - (i + 1) * logosInRowAmount - // eslint-disable-next-line - ) - .map((logo) => ( -
    - {logo.alt} -
    - )); - - logosRows.push( - - - {rowImages} - - - {rowImages} - - - ); - } - return logosRows; -}; - -const TrustedTeamsBlock = ({ content }: Props) => { - const threeRows = useMemo(() => createLogosRows(TrustedTeamsLogos, 3), []); - const fiveRows = useMemo(() => createLogosRows(TrustedTeamsLogos, 5), []); - - const threeRowsDark = useMemo( - () => createLogosRows(TrustedTeamsLogosDark, 3), - [] - ); - const fiveRowsDark = useMemo( - () => createLogosRows(TrustedTeamsLogosDark, 5), - [] - ); - - return ( -
    - - {content.title} - - {threeRows} - {fiveRows} - - - {threeRowsDark} - {fiveRowsDark} - - -
    - ); -}; - -export default TrustedTeamsBlock; diff --git a/docs/src/components/landingBlocks/VibrantCommunityBlock.stories.tsx b/docs/src/components/landingBlocks/VibrantCommunityBlock.stories.tsx deleted file mode 100644 index 0b73ca4c51..0000000000 --- a/docs/src/components/landingBlocks/VibrantCommunityBlock.stories.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from "react"; - -import VibrantCommunityBlock from "./VibrantCommunityBlock"; -import homepageContent from "../../content/home"; - -export default { - title: "Landing Blocks/Vibrant community", -}; - -export const Default = () => ( - -); diff --git a/docs/src/components/landingBlocks/VibrantCommunityBlock.tsx b/docs/src/components/landingBlocks/VibrantCommunityBlock.tsx deleted file mode 100644 index 9fa23b0258..0000000000 --- a/docs/src/components/landingBlocks/VibrantCommunityBlock.tsx +++ /dev/null @@ -1,228 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import Image from "next/image"; - -import { media, tm, tmDark, tmSelectors } from "../../themes"; -import CTA from "../ui/CTA"; -import Section from "../Section"; -import { CTAType } from "../ui/types"; - -interface Props { - content: { - title: string; - text: string; - imageUrl: string; - imageDarkUrl: string; - cta: CTAType; - }; -} - -const CardWrapper = styled.section` - margin: 96px 24px 0; - - ${media.md} { - margin: 0 75px 50px 85px; - } -`; - -const Container = styled.div` - padding-top: 72%; - width: 100%; - display: flex; - position: relative; - flex-direction: column; - ${media.md} { - padding: 0; - flex-direction: row-reverse; - justify-content: space-between; - padding: 0 150px; - } - box-shadow: 0 6px 50px ${tm(({ colors }) => colors.vibrantBoxShadow)}; - background-color: ${tm(({ colors }) => colors.vibrantBackground)}; - ${tmSelectors.dark} { - box-shadow: 0 6px 50px ${tmDark(({ colors }) => colors.vibrantBoxShadow)}; - background-color: ${tmDark(({ colors }) => colors.vibrantBackground)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - box-shadow: 0 6px 50px ${tmDark(({ colors }) => colors.vibrantBoxShadow)}; - background-color: ${tmDark(({ colors }) => colors.vibrantBackground)}; - } - } -`; - -const Wrapper = styled.div` - display: flex; - flex-direction: column; - ${media.md} { - width: 477px; - margin: 110px 0 40px; - } -`; - -const ImageContainer = styled.div` - width: 110%; - height: 100%; - position: absolute; - height: auto; - transform: translateX(-4%); - top: -16px; - & .img { - position: relative !important; - height: unset !important; - } - & span { - padding: 0 !important; - } - - ${media.md} { - margin-top: 43px; - width: 530px; - max-height: none; - height: 366px; - position: relative; - top: 0; - left: 0; - transform: scale(1); - } - &.dark { - display: none; - } - ${tmSelectors.dark} { - &.dark { - display: block; - } - &.light { - display: none; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - &.dark { - display: block; - } - &.light { - display: none; - } - } - } -`; - -const Title = styled.h2` - margin-top: 36px; - margin-bottom: 24px; - text-align: center; - font-size: 20px; - line-height: 24px; - text-transform: uppercase; - letter-spacing: 0.2em; - font-weight: 400; - color: ${tm(({ colors }) => colors.neutral900)}; - ${media.md} { - margin-top: 0px; - text-align: left; - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } -`; - -const Text = styled.p` - margin: 0 8px 32px; - text-align: center; - font-size: 18px; - line-height: 28px; - font-weight: 400; - font-family: ChivoLight, sans-serif; - color: ${tm(({ colors }) => colors.neutral600)}; - - ${media.md} { - margin: 0 0 82px; - text-align: left; - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral600)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tm(({ colors }) => colors.neutral600)}; - } - } -`; - -const ButtonWrapper = styled.div` - width: 232px; - margin-bottom: 48px; - align-self: center; - font-size: 15px; - line-height: 24px; - font-weight: 400; - font-family: ChivoRegular, sans-serif; - color: ${tm(({ colors }) => colors.neutral900)}; - & > a { - font-size: 15px; - } - - ${media.md} { - align-self: start; - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tm(({ colors }) => colors.neutral900)}; - } - } -`; - -const VibrantCommunityBlock = ({ content }: Props) => { - return ( -
    - - - - Vibrant community image - - - Vibrant community image - - - {content.title} - {content.text} - - - {content.cta.title} - - - - - -
    - ); -}; - -export default VibrantCommunityBlock; diff --git a/docs/src/components/landingBlocks/WhyHardhatBlock.stories.tsx b/docs/src/components/landingBlocks/WhyHardhatBlock.stories.tsx deleted file mode 100644 index 94a3a4c031..0000000000 --- a/docs/src/components/landingBlocks/WhyHardhatBlock.stories.tsx +++ /dev/null @@ -1,12 +0,0 @@ -import React from "react"; - -import homepageContent from "../../content/home"; -import WhyHardhatBlock from "./WhyHardhatBlock"; - -export default { - title: "Landing Blocks/Why Hardhat", -}; - -export const Default = () => ( - -); diff --git a/docs/src/components/landingBlocks/WhyHardhatBlock.tsx b/docs/src/components/landingBlocks/WhyHardhatBlock.tsx deleted file mode 100644 index 76a1081314..0000000000 --- a/docs/src/components/landingBlocks/WhyHardhatBlock.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; - -import Section from "../Section"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; - -type Props = React.PropsWithChildren<{ - content: { title: string }; -}>; - -const Container = styled.section` - width: 100%; - position: relative; - display: flex; - flex-direction: column; - border-left: 1px solid ${tm(({ colors }) => colors.neutral400)}; - padding-top: 52px; - ${media.md} { - border-left: unset; - border-top: 1px solid ${tm(({ colors }) => colors.neutral400)}; - } - ${tmSelectors.dark} { - border-color: ${tmDark(({ colors }) => colors.neutral400)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - border-color: ${tmDark(({ colors }) => colors.neutral400)}; - } - } -`; - -const Title = styled.h2` - position: absolute; - padding: 24px; - background-color: ${tm(({ colors }) => colors.neutral0)}; - color: ${tm(({ colors }) => colors.neutral900)}; - left: 0; - top: 0; - transform: translateY(-50%); - text-transform: uppercase; - font-size: 20px; - font-style: normal; - font-weight: 400; - line-height: 24px; - letter-spacing: 0.2em; - margin-bottom: 32px; - ${media.md} { - left: 50%; - transform: translate(-50%, -50%); - font-size: 24px; - } - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } -`; - -const TopBrackets = styled.div` - position: absolute; - top: 0; - left: 24px; - width: calc(100% - 24px); - height: 32px; - border-top: 1px solid ${tm(({ colors }) => colors.neutral400)}; - border-left: 1px solid ${tm(({ colors }) => colors.neutral400)}; - border-right: 1px solid ${tm(({ colors }) => colors.neutral400)}; - ${media.md} { - height: 36px; - border-top: none; - width: 100%; - border-top: none; - left: 0; - } - ${tmSelectors.dark} { - border-color: ${tmDark(({ colors }) => colors.neutral400)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - border-color: ${tmDark(({ colors }) => colors.neutral400)}; - } - } -`; -const BottomBrackets = styled.div` - position: absolute; - left: 0px; - bottom: 0; - width: 32px; - height: 32px; - border-bottom: 1px solid ${tm(({ colors }) => colors.neutral400)}; - ${media.md} { - display: none; - } -`; - -const WhyHardhatBlock = ({ content, children }: Props) => { - return ( -
    - - - {content.title} - {children} - - -
    - ); -}; - -export default WhyHardhatBlock; diff --git a/docs/src/components/mdxComponents/Admonition.tsx b/docs/src/components/mdxComponents/Admonition.tsx deleted file mode 100644 index 0d90f98b34..0000000000 --- a/docs/src/components/mdxComponents/Admonition.tsx +++ /dev/null @@ -1,93 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import { NextComponentType } from "next"; -import { tm, tmDark, tmSelectors, media } from "../../themes"; - -const StyledAdmonition = styled.div` - display: flex; - flex-direction: column; - width: 100%; - margin: 16px 0; - padding: 16px 24px; - background-color: ${tm(({ colors }) => colors.tipBackgroundColor)}; - border-left: 0.5rem solid ${tm(({ colors }) => colors.tipBorderColor)}; - font-size: 14px; - font-weight: 400; - line-height: 1.7; - color: ${tm(({ colors }) => colors.neutral800)}; - & .title { - font-size: 16px; - font-weight: 700; - } - &.warning { - & .title { - color: ${tm(({ colors }) => colors.warningColorTitle)}; - } - & p { - color: ${tm(({ colors }) => colors.warningColorText)}; - } - border-color: ${tm(({ colors }) => colors.warningBorderColor)}; - background-color: ${tm(({ colors }) => colors.warningBackgroundColor)}; - } - - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.tipBackgroundColor)}; - color: ${tmDark(({ colors }) => colors.neutral900)}; - &.warning { - & .title { - color: ${tmDark(({ colors }) => colors.warningColorTitle)}; - } - & p { - color: ${tmDark(({ colors }) => colors.warningColorText)}; - } - border-color: ${tmDark(({ colors }) => colors.warningBorderColor)}; - background-color: ${tmDark( - ({ colors }) => colors.warningBackgroundColor - )}; - } - } - - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.tipBackgroundColor)}; - color: ${tmDark(({ colors }) => colors.neutral900)}; - &.warning { - & .title { - color: ${tmDark(({ colors }) => colors.warningColorTitle)}; - } - & p { - color: ${tmDark(({ colors }) => colors.warningColorText)}; - } - border-color: ${tmDark(({ colors }) => colors.warningBorderColor)}; - background-color: ${tmDark( - ({ colors }) => colors.warningBackgroundColor - )}; - } - } - } -`; - -const Tip: NextComponentType = ({ children }) => { - return ( - -

    TIP

    - {children} -
    - ); -}; - -const Warning: NextComponentType = ({ children }) => { - return ( - -

    WARNING

    - {children} -
    - ); -}; - -const Admonition = { - Tip, - Warning, -}; - -export default Admonition; diff --git a/docs/src/components/mdxComponents/Admonitions.stories.tsx b/docs/src/components/mdxComponents/Admonitions.stories.tsx deleted file mode 100644 index 8845f8386f..0000000000 --- a/docs/src/components/mdxComponents/Admonitions.stories.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from "react"; -import Admonition from "./Admonition"; -import { mdWrapper } from "../../../.storybook/common-decorators"; - -export default { - title: "MDX components/Admonition", - decorators: [mdWrapper], -}; - -export const Tip = () => ( - - Hardhat will let you know how, but, in case you missed it, you can install - them with - -); - -export const Warning = () => ( - - Do not send mainnet Ether to the addresses above. Those addresses are - deterministic: they are the same for all Hardhat users. Accordingly, the - private keys for these addresses are well known, so there are probably bots - monitoring those addresses on mainnet, waiting to withdraw any funds sent to - them. If you add any of these accounts to a wallet (eg Metamask), be very - careful to avoid sending any mainnet Ether to them: consider naming the - account something like Hardhat - Unsafe in order to prevent any mistakes. - -); diff --git a/docs/src/components/mdxComponents/CodeBlocks.stories.tsx b/docs/src/components/mdxComponents/CodeBlocks.stories.tsx deleted file mode 100644 index 6113bbb803..0000000000 --- a/docs/src/components/mdxComponents/CodeBlocks.stories.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from "react"; -import CodeBlocks from "./CodeBlocks"; -import { mdWrapper } from "../../../.storybook/common-decorators"; - -export default { - title: "MDX components/CodeBlocks", - decorators: [mdWrapper], -}; - -export const Code = () => console.log(1); - -export const Pre = () => ( - - - {` - $ npx hardhat - 888 888 888 888 888 - 888 888 888 888 888 - 888 888 888 888 888 - 8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888 - 888 888 "88b 888P" d88" 888 888 "88b "88b 888 - 888 888 .d888888 888 888 888 888 888 .d888888 888 - 888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. - 888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 - - Welcome to Hardhat v2.0.8 - - ? What do you want to do? … - ❯ Create a sample project - Create an advanced sample project - Create an advanced sample project that uses TypeScript - Create an empty hardhat.config.js - Quit - `} - - -); diff --git a/docs/src/components/mdxComponents/CodeBlocks.tsx b/docs/src/components/mdxComponents/CodeBlocks.tsx deleted file mode 100644 index 1ad8d9b3d5..0000000000 --- a/docs/src/components/mdxComponents/CodeBlocks.tsx +++ /dev/null @@ -1,138 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; - -export interface CodeProps { - children: string | JSX.Element[] | JSX.Element; -} - -export interface PreProps { - children: React.ReactElement; - className: string; -} - -const StyledCode = styled.code` - padding: 4px 8px; - background-color: ${tm(({ colors }) => colors.codeBackground)}; - border-radius: 3px; - font-size: 13.6px; - font-weight: 400; - line-height: 1; - color: ${tm(({ colors }) => colors.codeColor)}; - letter-spacing: 0.05em; - - &[data-language=""] { - font-family: source-code-pro, Menlo, Monaco, Consolas, Courier New, - monospace; - font-weight: normal; - } - - h1 &, - h2 &, - h3 &, - h4 &, - h5 & { - font-size: inherit; - font-family: inherit; - font-weight: inherit; - line-height: inherit; - } - - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.codeBlockBackground)}; - color: ${tmDark(({ colors }) => colors.codeColor)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.codeBlockBackground)}; - color: ${tmDark(({ colors }) => colors.codeColor)}; - } - } -`; - -const StyledPre = styled.pre` - margin: 16px 0; - padding: 20px 24px; - background-color: ${tm(({ colors }) => colors.codeBlockBackground)}; - border-radius: 6px; - overflow: auto; - border: 1px solid ${tm(({ colors }) => colors.transparent)}; - & code { - padding: 0; - color: ${tm(({ colors }) => colors.preCodeColor)}; - line-height: 1.4; - font-size: 0.85em; - font-family: "Menlo", monospace; - font-weight: 300; - } - - & .remark-highlight-code-line { - display: block; - min-width: 100%; - background-color: ${tm(({ colors }) => colors.codeLineHighlight)}; - position: relative; - &::after { - content: " "; - width: 1.2em; - position: absolute; - top: 0; - right: -1.2em; - background-color: ${tm(({ colors }) => colors.codeLineHighlight)}; - } - &::before { - content: " "; - width: 1.2em; - position: absolute; - top: 0; - left: -1.2em; - background-color: ${tm(({ colors }) => colors.codeLineHighlight)}; - } - } - - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.codeBlockBackground)}; - border: 1px solid ${tmDark(({ colors }) => colors.codeBlockBorder)}; - & code { - color: ${tmDark(({ colors }) => colors.preCodeColor)}; - } - } - - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.codeBlockBackground)}; - border: 1px solid ${tmDark(({ colors }) => colors.codeBlockBorder)}; - & code { - color: ${tmDark(({ colors }) => colors.preCodeColor)}; - } - } - } -`; - -const ContentWrapper = styled.span` - position: relative; - width: max-content; - min-width: 100%; - pre > code & { - display: block; - } -`; - -const Code = ({ children }: CodeProps) => { - return ( - - {children} - - ); -}; - -const Pre = ({ children, className }: PreProps) => { - return {children}; -}; - -const CodeBlocks = { - Code, - Pre, -}; - -export default CodeBlocks; diff --git a/docs/src/components/mdxComponents/HorizontalRule.tsx b/docs/src/components/mdxComponents/HorizontalRule.tsx deleted file mode 100644 index ea04172e2a..0000000000 --- a/docs/src/components/mdxComponents/HorizontalRule.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; - -export interface Props { - children: string; -} - -const StyledHorizontalRule = styled.ul` - margin: 8px 0; - border-top: 1px solid ${tm(({ colors }) => colors.neutral400)}; - - ${tmSelectors.dark} { - border-top: 1px solid ${tmDark(({ colors }) => colors.neutral400)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - border-top: 1px solid ${tmDark(({ colors }) => colors.neutral400)}; - } - } -`; - -const HorizontalRule = ({ children }: Props) => { - return {children}; -}; - -export default HorizontalRule; diff --git a/docs/src/components/mdxComponents/Lists.stories.tsx b/docs/src/components/mdxComponents/Lists.stories.tsx deleted file mode 100644 index 6fe6d7ae74..0000000000 --- a/docs/src/components/mdxComponents/Lists.stories.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from "react"; -import OrderedList from "./OrderedList"; -import UnorderedList from "./UnorderedList"; -import { mdWrapper } from "../../../.storybook/common-decorators"; - -export default { - title: "MDX components/Lists", - decorators: [mdWrapper], -}; - -export const Ordered = () => ( - -
  • Lorem ipsum dolor sit amet consectetur adipisicing elit..
  • -
  • Lorem ipsum dolor sit amet consectetur elit.
  • -
  • Lorem ipsum dolor sit amet adipisicing elit.
  • -
  • Lorem ipsum dolor sit amet consectetur adipisicing elit.
  • -
  • Lorem dolor sit consectetur adipisicing elit.
  • -
    -); -export const Unordered = () => ( - -
  • Lorem ipsum dolor sit amet consectetur adipisicing elit..
  • -
  • Lorem ipsum dolor sit amet consectetur elit.
  • -
  • Lorem ipsum dolor sit amet adipisicing elit.
  • -
  • Lorem ipsum dolor sit amet consectetur adipisicing elit.
  • -
  • Lorem dolor sit consectetur adipisicing elit.
  • -
    -); diff --git a/docs/src/components/mdxComponents/MDImage.stories.tsx b/docs/src/components/mdxComponents/MDImage.stories.tsx deleted file mode 100644 index 70d79aa798..0000000000 --- a/docs/src/components/mdxComponents/MDImage.stories.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import React from "react"; -import MDImage from "./MDImage"; -import { mdWrapper } from "../../../.storybook/common-decorators"; - -export default { - title: "MDX components/Media", - decorators: [mdWrapper], -}; - -export const Image = () => ( - -); -export const Gif = () => ; diff --git a/docs/src/components/mdxComponents/MDImage.tsx b/docs/src/components/mdxComponents/MDImage.tsx deleted file mode 100644 index 9f83f67624..0000000000 --- a/docs/src/components/mdxComponents/MDImage.tsx +++ /dev/null @@ -1,65 +0,0 @@ -// @ts-nocheck -import React from "react"; -import Image from "next/image"; -import { styled } from "linaria/react"; - -export interface Props { - src: string; - alt: string; -} - -// TODO: solve the issue with badges -const ImageContainer = styled.div` - max-width: 100%; - position: relative; - width: ${({ width }) => width}; - img { - width: ${({ width }) => width}; - height: auto; - } - & .md-img { - position: relative !important; - height: unset !important; - } - & span { - padding: 0 !important; - } - - span & div { - width: 120px !important; - } -`; - -const isShellBadge = (src: string): boolean => /img\.shields\.io/.test(src); -const isHardhatBadge = (alt: string): boolean => alt === "hardhat"; - -const calcImgWidth = ({ isShellBdg, isHardhatBdg }) => { - if (isHardhatBdg) return "140px"; - if (isShellBdg) return "80px"; - return null; -}; - -const MDImage = ({ src, alt }: Props) => { - const isHardhatBdg = isHardhatBadge(alt); - const isShellBdg = isShellBadge(src); - - return ( - - {alt} - - ); -}; - -export default MDImage; diff --git a/docs/src/components/mdxComponents/MDLink.stories.tsx b/docs/src/components/mdxComponents/MDLink.stories.tsx deleted file mode 100644 index 47564b0838..0000000000 --- a/docs/src/components/mdxComponents/MDLink.stories.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import React from "react"; -import MDLink from "./MDLink"; -import { mdWrapper } from "../../../.storybook/common-decorators"; -import Paragraph from "./Paragraph"; - -export default { - title: "MDX components/Links", - decorators: [mdWrapper], -}; - -export const External = () => ( - - Here is a link to - hardhat.org - -); -export const Internal = () => ( - - Here is a link to - some internal path - -); diff --git a/docs/src/components/mdxComponents/MDLink.tsx b/docs/src/components/mdxComponents/MDLink.tsx deleted file mode 100644 index c3324b222b..0000000000 --- a/docs/src/components/mdxComponents/MDLink.tsx +++ /dev/null @@ -1,157 +0,0 @@ -import React, { ReactElement } from "react"; -import { styled } from "linaria/react"; -import Link from "next/link"; -import { useRouter } from "next/router"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; -import ExternalLinkIcon from "../../assets/icons/external-link-icon"; - -export interface Props { - children: string | ReactElement; - href: string; -} - -const StyledMdLinkContainer = styled.span` - & > a { - color: ${tm(({ colors }) => colors.link)}; - } - margin: 0 2px; - cursor: pointer; - &:hover { - text-decoration: underline; - } - - & > a { - display: inline-flex; - align-items: center; - } - - & .hardhat-badge + svg { - margin-left: -30px; - } - - & code { - color: ${tm(({ colors }) => colors.link)}; - } - & svg { - margin-left: 2px; - stroke: ${tmDark(({ colors }) => colors.neutral800)}; - } - - ${tmSelectors.dark} { - & svg { - stroke: ${tmDark(({ colors }) => colors.neutral800)}; - } - & code { - color: ${tm(({ colors }) => colors.link)}; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - & svg { - stroke: ${tmDark(({ colors }) => colors.neutral800)}; - } - & code { - color: ${tm(({ colors }) => colors.link)}; - } - } - } -`; - -const getAbsoluteHrefFromAbsolutePath = (href: string): string => { - return ( - href - // the lookahead is to prevent links like /indexing.md from being broken - .replace(/\/index(?=\.)/, "") - // remove the .md/.mdx extension but preserve the anchor - .replace(/\.mdx?(#.*)?$/, "$1") - ); -}; - -const getAbsoluteHrefFromRelativePath = (href: string, currentHref: string) => { - const pathSegments = currentHref - .split("/") - .filter((segment) => segment !== ""); - const pathSegmentsCount = pathSegments.length; - - let hrefSegments = href.split("/").filter((segment) => segment !== "."); - const upperLevelsCount = hrefSegments.filter( - (segment) => segment === ".." - ).length; - - // remove the ".." segments after counting them - hrefSegments = hrefSegments.filter((segment) => segment !== ".."); - - const baseSegmentsCount = Math.max( - pathSegmentsCount - 1 - upperLevelsCount, - 0 - ); - - const baseSegments = pathSegments.slice(0, baseSegmentsCount); - - const newSegments = ["", ...baseSegments, ...hrefSegments]; - - return getAbsoluteHrefFromAbsolutePath(newSegments.join("/")); -}; - -const renderLinkByType = ({ - children, - href, - isExternalLink, - isAnchor, - isAbsoluteLink, - currentHref, -}: Props & { - isExternalLink: boolean; - isAnchor: boolean; - isAbsoluteLink: boolean; - currentHref: string; -}) => { - if (isExternalLink) { - return ( - - {children} - - - ); - } - if (isAnchor) { - return {children}; - } - if (isAbsoluteLink) { - return ( - - {/* eslint-disable-next-line */} - {children} - - ); - } - - return ( - - {/* eslint-disable-next-line */} - {children} - - ); -}; - -const MDLink = ({ children, href }: Props) => { - const router = useRouter(); - const isExternalLink = href.startsWith("http"); - const isAbsoluteLink = href.startsWith("/"); - const isAnchor = href.startsWith("#"); - - return ( - - {renderLinkByType({ - href, - children, - isAnchor, - isExternalLink, - isAbsoluteLink, - currentHref: router.asPath, - })} - - ); -}; - -export default MDLink; diff --git a/docs/src/components/mdxComponents/OrderedList.tsx b/docs/src/components/mdxComponents/OrderedList.tsx deleted file mode 100644 index d6f8e7c2bb..0000000000 --- a/docs/src/components/mdxComponents/OrderedList.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; - -export interface Props { - children: JSX.Element[] | JSX.Element; -} - -const StyledOrderedList = styled.ol` - padding-left: 1.2em; - margin-top: 16px; - font-weight: normal; - line-height: 1.7; - color: ${tm(({ colors }) => colors.neutral800)}; - - & code { - line-height: 1.2; - } - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - } -`; - -const OrderedList = ({ children }: Props) => { - return {children}; -}; - -export default OrderedList; diff --git a/docs/src/components/mdxComponents/Paragraph.tsx b/docs/src/components/mdxComponents/Paragraph.tsx deleted file mode 100644 index dbd8e485e3..0000000000 --- a/docs/src/components/mdxComponents/Paragraph.tsx +++ /dev/null @@ -1,31 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; - -import { media, tm, tmDark, tmSelectors } from "../../themes"; - -export interface Props { - children: string | JSX.Element[] | JSX.Element; -} - -const StyledP = styled.p` - margin: 16px 0; - line-height: 1.7; - font-size: 16px; - color: ${tm(({ colors }) => colors.neutral800)}; - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - } -`; - -const Paragraph = ({ children }: Props) => { - return {children}; -}; - -export default Paragraph; diff --git a/docs/src/components/mdxComponents/Tab.tsx b/docs/src/components/mdxComponents/Tab.tsx deleted file mode 100644 index 23571949f5..0000000000 --- a/docs/src/components/mdxComponents/Tab.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React, { useContext } from "react"; -import { styled } from "linaria/react"; -import { GlobalTabsContext } from "../../global-tabs"; - -export interface ITab { - children: JSX.Element[] | JSX.Element; - value: string; - type: string; -} - -const StyledTab = styled.div<{ value: string; selectedTab: string }>` - display: ${({ value, selectedTab }) => - value === selectedTab ? "block" : "none"}; -`; - -const Tab = ({ children, value, type }: ITab) => { - const { tabsState } = useContext(GlobalTabsContext); - const selectedTab = tabsState[type]; - - return ( - - {children} - - ); -}; - -export default Tab; diff --git a/docs/src/components/mdxComponents/Table.stories.tsx b/docs/src/components/mdxComponents/Table.stories.tsx deleted file mode 100644 index 2381c068a0..0000000000 --- a/docs/src/components/mdxComponents/Table.stories.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import React from "react"; -import Table from "./Table"; -import { mdWrapper } from "../../../.storybook/common-decorators"; - -export default { - title: "MDX components/Table", - decorators: [mdWrapper], -}; - -export const MDTable = () => ( - - - - - - - - - - - - - - - -
    ExampleExample
    Lorem ipsum Lorem ipsum, dolor sit amet consectetur adipisicing
    Lorem ipsum Lorem ipsum, dolor sit amet consectetur adipisicing
    -); diff --git a/docs/src/components/mdxComponents/Table.tsx b/docs/src/components/mdxComponents/Table.tsx deleted file mode 100644 index 7b61bd88ae..0000000000 --- a/docs/src/components/mdxComponents/Table.tsx +++ /dev/null @@ -1,44 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; - -export interface Props { - children: JSX.Element[] | JSX.Element; -} - -const StyledTable = styled.table` - margin: 16px 0; - width: 100%; - border-collapse: collapse; - color: ${tm(({ colors }) => colors.neutral800)}; - border-color: ${tm(({ colors }) => colors.neutral800)}; - overflow-x: auto; - & thead { - vertical-align: middle; - } - & th { - font-weight: bold; - } - & th, - & td { - border: 1px solid ${tm(({ colors }) => colors.tableBorder)}; - padding: 9.6px 16px; - color: inherit; - } - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - } -`; - -const Table = ({ children }: Props) => { - return {children}; -}; - -export default Table; diff --git a/docs/src/components/mdxComponents/TabsGroup.tsx b/docs/src/components/mdxComponents/TabsGroup.tsx deleted file mode 100644 index 9247364faf..0000000000 --- a/docs/src/components/mdxComponents/TabsGroup.tsx +++ /dev/null @@ -1,120 +0,0 @@ -import React, { useContext, useMemo } from "react"; -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; -import { generateTabsGroupType, GlobalTabsContext } from "../../global-tabs"; - -export interface ITabsGroup { - children: React.ReactNode[]; - options: string; -} - -const StyledTabButton = styled.div<{ value: string }>` - padding: 6px 10px; - border-radius: 2px; - font-size: 10px; - line-height: 15px; - height: 27px; - letter-spacing: 0.05em; - cursor: pointer; - color: ${tm(({ colors }) => colors.neutral600)}; - background-color: ${tm(({ colors }) => colors.tabBackground)}; - &:hover { - background-color: ${tm(({ colors }) => colors.tabBackgroundHover)}; - color: ${tm(({ colors }) => colors.neutral400)}; - } - &[data-selected="true"] { - background-color: ${tm(({ colors }) => colors.tabBackgroundSelected)}; - color: ${tm(({ colors }) => colors.neutral400)}; - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral600)}; - background-color: ${tmDark(({ colors }) => colors.tabBackground)}; - &:hover { - background-color: ${tmDark(({ colors }) => colors.tabBackgroundHover)}; - color: ${tmDark(({ colors }) => colors.neutral400)}; - } - &[data-selected="true"] { - background-color: ${tmDark(({ colors }) => colors.tabBackgroundSelected)}; - color: ${tmDark(({ colors }) => colors.neutral400)}; - } - } - - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral600)}; - background-color: ${tmDark(({ colors }) => colors.tabBackground)}; - &:hover { - background-color: ${tmDark(({ colors }) => colors.tabBackgroundHover)}; - color: ${tmDark(({ colors }) => colors.neutral400)}; - } - &[data-selected="true"] { - background-color: ${tmDark( - ({ colors }) => colors.tabBackgroundSelected - )}; - color: ${tmDark(({ colors }) => colors.neutral400)}; - } - } - } -`; - -const StyledTabsContainer = styled.div` - display: flex; - width: 100%; - overflow-x: scroll; - &::-webkit-scrollbar { - display: none; - } - & > div { - margin-right: 8px; - &:last-child { - margin-right: unset; - } - } -`; - -const StyledTabsGroup = styled.div<{ selectedTab: string }>` - margin-top: 28px; - width: 100%; - position: relative; -`; - -const TabsGroup = ({ children, options }: ITabsGroup) => { - const { tabsState, changeTab } = useContext(GlobalTabsContext); - const type = useMemo(() => generateTabsGroupType(options), [options]); - const selectedTab = tabsState[type]; - const childrenWithProps = React.Children.map(children, (child) => { - // Checking isValidElement is the safe way and avoids a typescript - // error too. - if (React.isValidElement(child)) { - return React.cloneElement(child, { type }); - } - return child; - }); - - return ( - - - {options - .split(",") - .map((option) => option.trim()) - .map((option: string) => { - return ( - { - changeTab(type, option); - }} - > - {option} - - ); - })} - - {childrenWithProps} - - ); -}; - -export default TabsGroup; diff --git a/docs/src/components/mdxComponents/Title.stories.tsx b/docs/src/components/mdxComponents/Title.stories.tsx deleted file mode 100644 index 6f327388b2..0000000000 --- a/docs/src/components/mdxComponents/Title.stories.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from "react"; -import Title from "./Title"; -import { mdWrapper } from "../../../.storybook/common-decorators"; - -export default { - title: "MDX components/Headings", - decorators: [mdWrapper], -}; - -export const H1 = () => Lorem Ipsum; -export const H2 = () => Lorem Ipsum; -export const H3 = () => Lorem Ipsum; -export const H4 = () => Lorem Ipsum; -export const H5 = () => Lorem Ipsum; diff --git a/docs/src/components/mdxComponents/Title.tsx b/docs/src/components/mdxComponents/Title.tsx deleted file mode 100644 index c7b445b198..0000000000 --- a/docs/src/components/mdxComponents/Title.tsx +++ /dev/null @@ -1,270 +0,0 @@ -import React, { ReactElement } from "react"; -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; -import MDLink from "./MDLink"; - -export interface Props { - children: ReactElement | string; -} - -const StyledH1 = styled.h1` - margin-top: 48px; - margin-bottom: 16px; - font-size: 32px; - font-weight: 600; - line-height: 1.25; - letter-spacing: 0.5px; - color: ${tm(({ colors }) => colors.neutral800)}; - & .hash { - margin-left: -30px; - margin-right: 7px; - opacity: 0; - cursor: pointer; - color: ${tm(({ colors }) => colors.accent700)}; - } - &:hover .hash { - opacity: 1; - - &:hover { - text-decoration: underline; - } - } - ${tmSelectors.dark} { - border-bottom-color: ${tmDark(({ colors }) => colors.border)}; - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - border-bottom-color: ${tmDark(({ colors }) => colors.border)}; - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - } -`; - -const StyledH2 = styled.h2` - display: block; - padding-top: 40px; - padding-bottom: 16px; - border-bottom: 1px solid ${tm(({ colors }) => colors.neutral400)}; - font-weight: 600; - font-size: 24px; - line-height: 1.25; - letter-spacing: 0.5px; - color: ${tm(({ colors }) => colors.neutral800)}; - & .hash { - margin-left: -24px; - opacity: 0; - cursor: pointer; - color: ${tm(({ colors }) => colors.accent700)}; - } - &:hover .hash { - opacity: 1; - &:hover { - text-decoration: underline; - } - } - ${tmSelectors.dark} { - border-bottom-color: ${tmDark(({ colors }) => colors.border)}; - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - border-bottom-color: ${tmDark(({ colors }) => colors.border)}; - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - } -`; - -const StyledH3 = styled.h3` - margin-top: 32px; - font-weight: 600; - font-size: 21.6px; - line-height: 1.25; - letter-spacing: 0.5px; - color: ${tm(({ colors }) => colors.neutral800)}; - & .hash { - margin-left: -24px; - margin-right: 8px; - opacity: 0; - cursor: pointer; - color: ${tm(({ colors }) => colors.accent700)}; - } - &:hover .hash { - opacity: 1; - &:hover { - text-decoration: underline; - } - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - } - & > span:hover { - text-decoration: inherit; - } - & a { - font-size: inherit; - font-family: inherit; - font-weight: inherit; - line-height: inherit; - color: inherit; - } -`; -const StyledH4 = styled.h4` - font-size: 16px; - margin-top: 32px; - font-weight: 600; - font-size: 16px; - line-height: 1.25; - letter-spacing: 0.5px; - color: ${tm(({ colors }) => colors.neutral800)}; - & .hash { - margin-left: -16px; - margin-right: 4px; - opacity: 0; - cursor: pointer; - color: ${tm(({ colors }) => colors.accent700)}; - } - &:hover .hash { - opacity: 1; - &:hover { - text-decoration: underline; - } - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - } -`; -const StyledH5 = styled.h5` - margin-top: 24px; - font-weight: 600; - font-size: 13.2px; - line-height: 1.25; - letter-spacing: 0.5px; - color: ${tm(({ colors }) => colors.neutral800)}; - & .hash { - margin-left: -16px; - margin-right: 4px; - opacity: 0; - cursor: pointer; - color: ${tm(({ colors }) => colors.accent700)}; - } - &:hover .hash { - opacity: 1; - &:hover { - text-decoration: underline; - } - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - } -`; - -const buildIdFromChildren = function getId( - children: string | ReactElement -): string { - if (typeof children === "string") { - return children.toString().toLowerCase().replace(/\s+/g, "-"); - } - if (Array.isArray(children)) { - return children - .map((child) => { - return getId(child); - }) - .join("-"); - } - - return getId(children.props.children); -}; - -const H1 = ({ children }: Props): JSX.Element => { - return ( - - - # - {children} - - - ); -}; - -const H2 = ({ children }: Props) => { - return ( - - - # {children} - - - ); -}; - -const H3 = ({ children }: Props) => { - if (typeof children !== "string" && children.type === MDLink) { - return ( - - # - {children} - - ); - } - - return ( - - - # - {children} - - - ); -}; - -const H4 = ({ children }: Props) => { - return ( - - - # - {children} - - - ); -}; - -const H5 = ({ children }: Props) => { - return ( - - - # - {children} - - - ); -}; - -const Title = { - H1, - H2, - H3, - H4, - H5, -}; - -export default Title; diff --git a/docs/src/components/mdxComponents/UnorderedList.tsx b/docs/src/components/mdxComponents/UnorderedList.tsx deleted file mode 100644 index aefc9ab857..0000000000 --- a/docs/src/components/mdxComponents/UnorderedList.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; - -export interface Props { - children: JSX.Element[] | JSX.Element; -} - -const StyledUnorderedList = styled.ul` - padding-left: 1.2em; - margin-top: 16px; - line-height: 1.7; - color: ${tm(({ colors }) => colors.neutral800)}; - - & code { - line-height: 1.2; - } - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral800)}; - } - } -`; - -const UnorderedList = ({ children }: Props) => { - return {children}; -}; - -export default UnorderedList; diff --git a/docs/src/components/types.ts b/docs/src/components/types.ts deleted file mode 100644 index 2712f1b58e..0000000000 --- a/docs/src/components/types.ts +++ /dev/null @@ -1,34 +0,0 @@ -export interface ISeo { - title: string; - description: string; -} - -interface IDocumentationSidebarSectionChild { - label: string; - href: string; -} -interface IDocumentationSidebarSection { - label: string; - href?: string; - type: "single" | "group"; - children?: IDocumentationSidebarSectionChild[]; -} - -export interface NavOption { - href: string; - label: string; -} - -export interface FooterNavigation { - next?: NavOption | false; - prev?: NavOption | false; - lastEditDate: string; - editLink: string; -} - -export type IDocumentationSidebarStructure = IDocumentationSidebarSection[]; - -export interface IFooterNavigation { - href: string; - label: string; -} diff --git a/docs/src/components/ui/Banner.tsx b/docs/src/components/ui/Banner.tsx deleted file mode 100644 index a0322210b2..0000000000 --- a/docs/src/components/ui/Banner.tsx +++ /dev/null @@ -1,137 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import { breakpoints, media, tm, tmDark, tmSelectors } from "../../themes"; -import useWindowSize, { WindowSizeState } from "../../hooks/useWindowSize"; -import { BannerProps, DefaultBannerProps } from "./types"; - -const BannerContainer = styled.section` - font-family: ChivoRegular, sans-serif; - user-select: none; - z-index: 100; - width: 100%; - height: 40px; - display: flex; - padding: 8px; - flex-direction: column; - justify-content: center; - align-items: center; - background-color: ${tm(({ colors }) => colors.neutral900)}; - color: ${tm(({ colors }) => colors.neutral0)}; - font-size: 13px; - font-weight: 400; - line-height: 15px; - letter-spacing: 0.03em; - white-space: nowrap; - cursor: pointer; - & span { - margin-right: 2px; - } - ${media.md} { - font-size: 15px; - line-height: 12px; - } - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.neutral900)}; - color: ${tmDark(({ colors }) => colors.neutral0)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.neutral900)}; - color: ${tmDark(({ colors }) => colors.neutral0)}; - } - } -`; - -const BracesContainer = styled.div` - display: flex; - flex-wrap: nowrap; - align-items: baseline; - & > .braces { - color: ${tm(({ colors }) => colors.accent900)}; - display: inline; - transition: color ease-out 0.5s; - margin: 0 4px; - } - & .reversed { - transform: rotate(180deg); - } - & .text { - ${media.md} { - padding: 0px 16px; - } - } -`; - -const Brace = styled.div<{ - fullAnimationDuration: number; - braceNumber: number; -}>` - display: inline; - animation: highlight ease-out ${(props) => `${props.fullAnimationDuration}s`}; - animation-iteration-count: 3; - animation-delay: ${(props) => `${props.braceNumber * 0.5}s`}; - @keyframes highlight { - 10% { - opacity: 0; - } - - 20% { - opacity: 1; - } - } ; -`; - -const getBracesCount = (windowSize: WindowSizeState) => { - if (windowSize.width >= breakpoints.md) return 6; - if (windowSize.width >= breakpoints.sm) return 3; - return 2; -}; - -const BracesAnimation: React.FC> = ({ - children, -}) => { - const windowSize = useWindowSize(); - const bracesCount = getBracesCount(windowSize); - - const bracesString = Array(bracesCount) - .fill(">") - .map((brace: string, index: number) => { - return ( - - {brace} - - ); - }); - - return ( - -
    {bracesString}
    -
    {children}
    -
    {bracesString}
    -
    - ); -}; - -export const DefaultBanner = ({ content }: DefaultBannerProps) => { - const windowSize = useWindowSize(); - const isDesktop = breakpoints.md <= windowSize.width; - return isDesktop ? ( - {content.text} - ) : ( - {content.shortText} - ); -}; - -const Banner = ({ content, renderContent }: BannerProps) => { - return ( - - {renderContent({ content })} - - ); -}; - -export default Banner; diff --git a/docs/src/components/ui/CTA.stories.tsx b/docs/src/components/ui/CTA.stories.tsx deleted file mode 100644 index 340bf6d990..0000000000 --- a/docs/src/components/ui/CTA.stories.tsx +++ /dev/null @@ -1,60 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import CTA from "./CTA"; - -export default { - title: "UI components/CTA", -}; - -const Row = styled.div` - display: flex; - justify-content: flex-start; - column-gap: 50px; - - h4 { - margin: 50px 0 30px; - } -`; - -const onClick = () => null; - -export const Buttons = () => ( -
    - -

    Links

    -
    - - Primary CTA - - Primary CTA - - - Secondary CTA - - - Secondary CTA - - - -

    Buttons

    -
    - - Primary CTA - - Primary CTA - - - Secondary CTA - - - Secondary CTA - - -
    -); - -export const Secondary = () => ( - - secondary button - -); diff --git a/docs/src/components/ui/CTA.tsx b/docs/src/components/ui/CTA.tsx deleted file mode 100644 index 56e1accd7d..0000000000 --- a/docs/src/components/ui/CTA.tsx +++ /dev/null @@ -1,112 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; - -const A = styled.a` - display: inline-flex; - justify-content: center; - align-items: center; - padding: 10px 22px; - border: none; - border-radius: 4px; - width: fit-content; - font-size: 12px; - font-weight: 500; - line-height: 24px; - letter-spacing: 0; - white-space: nowrap; - text-align: center; - color: ${tm(({ colors }) => colors.neutral900)}; - background-color: ${tm(({ colors }) => colors.accent800)}; - transition: all ease-out 0.3s; - cursor: pointer; - &:hover { - background-color: ${tm(({ colors }) => colors.accent300)}; - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.accent300)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.accent300)}; - } - } - } - ${media.md} { - font-size: 15px; - line-height: 24px; - letter-spacing: 0; - text-align: center; - padding: 12px 28px; - } - - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.accent800)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.accent800)}; - } - } - - &.secondary { - width: 100%; - border: 1px solid ${tm(({ colors }) => colors.neutral700)}; - text-align: center; - background-color: ${tm(({ colors }) => colors.transparent)}; - transition: 0.3s; - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - border-color: ${tmDark(({ colors }) => colors.neutral700)}; - background-color: ${tmDark(({ colors }) => colors.transparent)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - border-color: ${tmDark(({ colors }) => colors.neutral700)}; - background-color: ${tmDark(({ colors }) => colors.transparent)}; - } - } - - &:hover { - border-color: ${tm(({ colors }) => colors.transparent)}; - background-color: ${tm(({ colors }) => colors.secondaryCTAHover)}; - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.secondaryCTAHover)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.secondaryCTAHover)}; - } - } - } - } - - &.full-padding { - padding: 12px 28px; - } -`; - -type Props = React.PropsWithChildren<{ - href?: string; - variant?: string; - onClick?: () => void; -}>; - -const CTA = ({ children, href, variant = "", onClick }: Props) => { - if ((href === "" || href === undefined || href === null) && !onClick) { - throw new Error("CTA should have a href prop or a onClick prop"); - } - return ( - - {children} - - ); -}; - -export default CTA; diff --git a/docs/src/components/ui/DesktopMenu.tsx b/docs/src/components/ui/DesktopMenu.tsx deleted file mode 100644 index b925d571e4..0000000000 --- a/docs/src/components/ui/DesktopMenu.tsx +++ /dev/null @@ -1,371 +0,0 @@ -import React, { useState } from "react"; -import { styled } from "linaria/react"; -import { useRouter } from "next/router"; -import Link from "next/link"; -import { MenuProps, MenuItemType, SocialsItem } from "./types"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; -import Searching from "../Searching"; - -const MenuContainer = styled.section` - font-family: ChivoRegular, sans-serif; - user-select: none; - display: none; - background-color: ${tm(({ colors }) => colors.transparent)}; - - ${media.md} { - display: flex; - align-items: center; - justify-content: space-evenly; - margin-left: -130px; - } -`; - -const MenuList = styled.ul` - display: flex; - list-style-type: none; - align-items: center; - margin-right: 65px; -`; - -const MenuItem = styled.li` - margin-left: 32px; - padding: 8px 0; - position: relative; - &:first-child { - margin-left: unset; - } -`; - -const MenuButton = styled.a` - text-transform: uppercase; - text-align: center; - border: none; - color: ${tm(({ colors }) => colors.neutral900)}; - background-color: ${tm(({ colors }) => colors.transparent)}; - font-size: 15px; - line-height: 15px; - letter-spacing: 0.07em; - position: relative; - cursor: pointer; - &:after { - transition: all ease-in-out 0.2s; - position: absolute; - bottom: -8px; - left: 0; - content: " "; - width: 0; - height: 1px; - background-color: ${tm(({ colors }) => colors.neutral900)}; - } - &:hover { - &:after { - width: 100%; - } - } - &[data-current="true"] { - &:after { - width: 100%; - } - } - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - &:after { - background-color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - &:after { - background-color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } - } -`; - -const MenuSocialsList = styled.ul` - min-width: 80px; - width: 80px; - display: flex; - height: 32px; - align-items: center; - list-style-type: none; - justify-content: space-between; -`; - -const SocialLink = styled.a` - display: flex; - align-items: center; - & svg { - fill: ${tm(({ colors }) => colors.neutral900)}; - ${tmSelectors.dark} { - fill: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - fill: ${tmDark(({ colors }) => colors.neutral900)}; - } - } - } - &:hover svg { - cursor: pointer; - opacity: 0.8; - } - &:focus svg { - cursor: pointer; - opacity: 0.5; - } -`; - -const SocialLinksItem = styled.li` - display: flex; - align-items: center; - justify-content: center; - & svg { - width: 22px; - height: 22px; - } - &[data-mobile="true"] { - width: 30px; - height: 30px; - } -`; - -const MenuItemDropDownWrapper = styled.div` - width: 494px; - height: 200px; - position: absolute; - top: 25px; - left: 50%; - transform: translateX(-50%); -`; - -const MenuItemDropdown = styled.div` - width: 494px; - height: 176px; - box-shadow: 0px 9px 28px 8px rgba(0, 0, 0, 0.05); - filter: drop-shadow(0px 6px 50px rgba(10, 11, 13, 0.41)); - border-radius: 4px; - background-color: ${tm(({ colors }) => colors.neutral0)}; - padding: 24px 32px; - position: relative; - top: 25px; - left: 50%; - transform: translateX(-50%); - display: flex; - flex-wrap: wrap; - z-index: 1; - & svg { - border-radius: 4px; - width: 42px; - height: 42px; - } - &::after { - z-index: -1; - position: absolute; - top: -6px; - left: 50%; - transform: translateX(-50%) rotate(45deg); - transform-origin: center; - content: " "; - width: 16px; - height: 16px; - background-color: inherit; - } - - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.neutral0)}; - } - } -`; - -const DropdownItem = styled.a` - width: 214px; - height: 58px; - padding: 10.5px 20.5px; - display: flex; - align-items: center; - .icon.dark { - display: none; - } - - ${tmSelectors.dark} { - .light { - display: none; - } - .dark { - display: inline; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - .light { - display: none; - } - .dark { - display: inline; - } - } - } -`; - -const ButtonNameContainer = styled.div` - display: flex; - align-items: center; - margin-left: 12px; - position: relative; - color: ${tm(({ colors }) => colors.neutral900)}; - &:after { - transition: all ease-in-out 0.2s; - position: absolute; - bottom: -8px; - left: 0; - content: " "; - width: 0; - height: 1px; - background-color: ${tm(({ colors }) => colors.neutral900)}; - } - ${DropdownItem}:hover > &:after { - width: 100%; - } - - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - &:after { - background-color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - &:after { - background-color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } - } -`; - -const ButtonCompanyName = styled.span` - font-size: 15px; - font-family: ChivoLight, sans-serif; - color: ${tm(({ colors }) => colors.neutral600)}; - font-weight: 800; -`; - -const ButtonToolName = styled.span` - margin-left: 4px; - font-size: 15px; - font-family: ChivoLight, sans-serif; - color: inherit; - line-height: 24px; - font-weight: 800; - white-space: nowrap; -`; - -export const SocialsList = ({ - socialsItems, - isMobile = false, -}: { - socialsItems: SocialsItem[]; - isMobile?: boolean; -}) => { - return ( - - {socialsItems.map((social: SocialsItem) => { - const { Icon } = social; - return ( - - - - - - ); - })} - - ); -}; - -const DesktopMenu = ({ menuItems, socialsItems }: MenuProps) => { - const router = useRouter(); - const [shownDropdown, setShownDropdown] = useState(null); - - return ( - - - - - - - {menuItems.map((menuItem: MenuItemType) => { - const isSelected = - menuItem.href === "/" - ? router?.asPath === menuItem.href - : router?.asPath.includes(menuItem.href); - return ( - { - if (!menuItem.subItems) return; - setShownDropdown(menuItem.label); - }} - onMouseLeave={() => { - if (!menuItem.subItems) return; - setShownDropdown(null); - }} - key={menuItem.label} - > - - - {menuItem.label} - - - {menuItem.subItems && shownDropdown === menuItem.label && ( - - - {menuItem.subItems.map((subItem) => { - return ( - - - {subItem.icon && ( - - )} - {subItem.iconDark && ( - - )} - - - {subItem.prefix} - - {subItem.label} - - - - ); - })} - - - )} - - ); - })} - - - - ); -}; - -export default DesktopMenu; diff --git a/docs/src/components/ui/FeatureCard.tsx b/docs/src/components/ui/FeatureCard.tsx deleted file mode 100644 index 2ca726d4f8..0000000000 --- a/docs/src/components/ui/FeatureCard.tsx +++ /dev/null @@ -1,240 +0,0 @@ -import React from "react"; -import Image from "next/image"; -import { styled } from "linaria/react"; -import { CTAType } from "./types"; -import CTA from "./CTA"; -import useWindowSize from "../../hooks/useWindowSize"; -import { breakpoints, media, tm, tmDark, tmSelectors } from "../../themes"; - -interface ArticleType { - title: string; - text: string; -} - -interface ContentProps { - mobileImgDark: StaticImageData; - desktopImgDark: StaticImageData; - mobileImg: StaticImageData; - desktopImg: StaticImageData; - cta: CTAType; - articleOne: ArticleType; - articleTwo: ArticleType; -} - -interface Props { - content: ContentProps; - isReversed?: boolean; -} - -const Container = styled.section` - width: 100%; - position: relative; - display: flex; - flex-direction: column; - padding: 24px 0 24px 24px; - overflow: hidden; - ${media.md} { - overflow: visible; - flex-direction: row; - padding: 0; - margin-bottom: 128px; - &[data-reverse="true"] { - flex-direction: row-reverse; - } - } -`; - -const ImageContainer = styled.div` - margin-bottom: 16px; - position: relative; - width: 100%; - padding-top: 80%; - overflow: hidden; - ${media.smd} { - padding-top: 40%; - } - ${media.md} { - padding-top: unset; - overflow: visible; - } -`; - -const ImageWrapper = styled.div` - position: absolute; - top: 20%; - left: 50%; - width: 100%; - transform: translateX(-50%); - height: 300px; - display: flex; - justify-content: center; - align-items: center; - ${media.smd} { - width: unset; - } - - & > span { - transform: scale(1.5); - } - - ${media.md} { - width: 116%; - top: 0; - right: -16%; - left: unset; - height: auto; - transform: translateX(-10%); - & > span { - transform: none; - } - - &[data-reverse="true"] { - left: 20%; - right: unset; - } - } - &.dark { - display: none; - } - ${tmSelectors.dark} { - &.dark { - display: block; - } - &.light { - display: none; - } - } - ${media.mqDark} { - ${tmSelectors.auto} { - &.dark { - display: block; - } - &.light { - display: none; - } - } - } -`; - -const ArticleStyled = styled.article` - margin-bottom: 24px; - width: 100%; - display: flex; - flex-direction: column; - padding: unset; - ${media.md} { - padding: 32px 0; - margin-bottom: unset; - } -`; - -const ContentContainer = styled.div` - width: 100%; - display: flex; - flex-direction: column; - margin-top: 16px; - ${media.md} { - margin-top: unset; - &[data-reverse="false"] { - margin-left: 46px; - } - } -`; - -const Title = styled.h3` - font-family: ChivoBold, sans-serif; - font-weight: normal; - font-size: 28px; - line-height: 32px; - letter-spacing: -0.01em; - margin-bottom: 24px; - color: ${tm(({ colors }) => colors.neutral900)}; - ${media.md} { - font-size: 42px; - line-height: 45px; - letter-spacing: 0.5px; - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } -`; - -const Text = styled.p` - font-family: ChivoLight, sans-serif; - font-size: 18px; - line-height: 28px; - letter-spacing: 0; - color: ${tm(({ colors }) => colors.neutral600)}; - ${media.md} { - font-size: 18px; - line-height: 28px; - letter-spacing: 0; - } - ${tmSelectors.dark} { - color: ${tmDark(({ colors }) => colors.neutral600)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - color: ${tmDark(({ colors }) => colors.neutral600)}; - } - } -`; - -const CTAWrapper = styled.div` - margin-top: 8px; - ${media.md} { - margin-top: 40px; - } -`; - -const Article = ({ title, text }: ArticleType) => { - return ( - - {title} - {text} - - ); -}; - -const FeatureCard = ({ content, isReversed = false }: Props) => { - const { - mobileImg, - desktopImg, - cta, - articleOne, - articleTwo, - mobileImgDark, - desktopImgDark, - } = content; - const windowSize = useWindowSize(); - const isDesktop = breakpoints.md <= windowSize.width; - const imgPath = isDesktop ? desktopImg : mobileImg; - const imgPathDark = isDesktop ? desktopImgDark : mobileImgDark; - - return ( - - - - Feature card picture - - - Feature card picture - - - -
    -
    - - {cta.title} - - - - ); -}; - -export default FeatureCard; diff --git a/docs/src/components/ui/Hamburger.tsx b/docs/src/components/ui/Hamburger.tsx deleted file mode 100644 index 9031851a7f..0000000000 --- a/docs/src/components/ui/Hamburger.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import React from "react"; -import { styled } from "linaria/react"; -import { media, tm, tmDark, tmSelectors } from "../../themes"; - -interface HamburgerProps { - isOpen: boolean; - onClick: () => void; -} - -const HamburgerContainer = styled.button` - width: 44px; - height: 32px; - display: flex; - flex-direction: column; - justify-content: space-between; - padding: 8px; - border: none; - border-radius: 4px; - background-color: ${tm(({ colors }) => colors.transparent)}; - cursor: pointer; - ${media.md} { - display: none; - } -`; - -const HamburgerLine = styled.div<{ isOpen: boolean }>` - background-color: ${tm(({ colors }) => colors.neutral900)}; - height: 2px; - width: 28px; - transform-origin: left; - user-select: none; - transition: all 0.25s ease-in-out; - &.mid { - width: 19px; - transition: all 0.1s ease-out; - } - &.top { - transform: ${({ isOpen }: { isOpen: boolean }) => - isOpen ? "rotate(45deg) translate(1px, -5px)" : "none"}; - } - &.mid { - opacity: ${({ isOpen }: { isOpen: boolean }) => (isOpen ? "0" : "1")}; - } - &.bot { - transform: ${({ isOpen }: { isOpen: boolean }) => - isOpen ? "rotate(-45deg) translate(1px, 5px)" : "none"}; - } - - ${tmSelectors.dark} { - background-color: ${tmDark(({ colors }) => colors.neutral900)}; - } - ${media.mqDark} { - ${tmSelectors.auto} { - background-color: ${tmDark(({ colors }) => colors.neutral900)}; - } - } -`; - -const Hamburger = ({ onClick, isOpen }: HamburgerProps) => { - return ( - onClick()} aria-label="navigation-menu"> - - - - - ); -}; - -export default Hamburger; diff --git a/docs/src/components/ui/types.ts b/docs/src/components/ui/types.ts deleted file mode 100644 index 941862dd89..0000000000 --- a/docs/src/components/ui/types.ts +++ /dev/null @@ -1,65 +0,0 @@ -import React from "react"; - -export enum NavigationPagesPaths { - HOME = "/", - TOOLS = "/#tools", - PLUGINS = "/plugins", - DOCUMENTATION = "/docs", - TUTORIAL = "/tutorial", -} -export interface MenuItemType { - label: string; - href: NavigationPagesPaths | string; - subItems?: MenuItemType[]; - prefix?: string; - icon?: React.FC; - iconDark?: React.FC; -} - -export enum SocialsEnum { - GITHUB = "GITHUB", - TWITTER = "TWITTER", - DISCORD = "DISCORD", -} - -export interface SocialsItem { - name: SocialsEnum; - href: string; - Icon: React.FC; -} - -export interface MenuProps { - menuItems: MenuItemType[]; - isOpen?: boolean; - socialsItems: SocialsItem[]; - isDocumentation?: boolean; -} - -export interface CTAType { - title: string; - url: string; -} - -export enum Tools { - RUNNER = "RUNNER", - IGNITION = "IGNITION", - NETWORK = "NETWORK", - SOLIDITY = "SOLIDITY", -} - -interface DefaultBannerContent { - text: string; - shortText: string; - href: string; -} -export interface BannerProps { - content: DefaultBannerContent; - renderContent: ({ - content, - }: { - content: DefaultBannerContent; - }) => JSX.Element; -} -export interface DefaultBannerProps { - content: DefaultBannerContent; -} diff --git a/docs/src/config.ts b/docs/src/config.ts deleted file mode 100644 index ea1caf8246..0000000000 --- a/docs/src/config.ts +++ /dev/null @@ -1,148 +0,0 @@ -import path from "path"; -import { - MenuItemType, - NavigationPagesPaths, - SocialsEnum, -} from "./components/ui/types"; -import GitHubLogo from "./assets/socials/gh-logo"; -import TwitterLogo from "./assets/socials/tw-logo"; -import DiscordLogo from "./assets/socials/dc-logo"; -import SolidityIcon from "./assets/tools/solidity"; -import RunnerIcon from "./assets/tools/runner"; -import NetworkIcon from "./assets/tools/network"; -import RunnerIconDark from "./assets/tools/runner-dark"; -import NetworkIconDark from "./assets/tools/network-dark"; -import SolidityIconDark from "./assets/tools/solidity-dark"; -// TODO: Re-enable Ignition section -// import IgnitionIcon from "./assets/tools/ignition"; -// import IgnitionIconDark from "./assets/tools/ignition-dark"; - -export const SOCIALS_LINKS = { - [SocialsEnum.GITHUB]: "https://github.com/NomicFoundation/hardhat", - [SocialsEnum.TWITTER]: "https://twitter.com/HardhatHQ", - [SocialsEnum.DISCORD]: "/discord", -}; - -export const BANNER_LINK = "https://nomic.foundation/hiring"; - -export const PRIVACY_POLICY_PATH = "/privacy-policy.html"; - -export const bannerContent = { - text: "Join the Hardhat team! Nomic Foundation is hiring", - shortText: "Join the Hardhat team! We are hiring", - href: BANNER_LINK, -}; - -export const DOCS_PATH = path.join(process.cwd(), "src/content/"); -export const DOCS_LANDING_PATH = path.join( - process.cwd(), - "src/content/docs-landing" -); -export const PLUGINS_PATH = path.join( - process.cwd(), - "src/content/hardhat-runner/plugins" -); -export const TEMP_PATH = path.join(process.cwd(), "temp/"); -export const REPO_URL = - "https://github.com/NomicFoundation/hardhat/edit/main/docs/src/content/"; - -// Regular expression to find tool in query string. -export const toolRegExp = /tool=[A-Z_]+/; - -export const menuItemsList: MenuItemType[] = [ - { - label: "Home", - href: NavigationPagesPaths.HOME, - }, - { - label: "Tools", - href: "/#tools", - subItems: [ - { - prefix: "Hardhat", - label: "Runner", - href: "/hardhat-runner", - icon: RunnerIcon, - iconDark: RunnerIconDark, - }, - // TODO: Re-enable Ignition section - // { - // prefix: "Hardhat", - // label: "Ignition", - // href: "/?tool=IGNITION#tools", - // icon: IgnitionIcon, - // iconDark: IgnitionIconDark, - // }, - { - prefix: "Hardhat", - label: "Network", - href: "/hardhat-network", - icon: NetworkIcon, - iconDark: NetworkIconDark, - }, - { - prefix: "Hardhat", - label: "VSCode", - href: "/hardhat-vscode", - icon: SolidityIcon, - iconDark: SolidityIconDark, - }, - ], - }, - { - label: "Plugins", - href: "/hardhat-runner/plugins", - }, - { - label: "Documentation", - href: "/docs", - }, - { - label: "Tutorial", - href: NavigationPagesPaths.TUTORIAL, - }, -]; - -export enum Tools { - RUNNER = "RUNNER", - // TODO: Re-enable Ignition section - // IGNITION = "IGNITION", - NETWORK = "NETWORK", - SOLIDITY = "SOLIDITY", -} - -export const socialsItems = [ - { - name: SocialsEnum.GITHUB, - href: SOCIALS_LINKS[SocialsEnum.GITHUB], - Icon: GitHubLogo, - }, - { - name: SocialsEnum.TWITTER, - href: SOCIALS_LINKS[SocialsEnum.TWITTER], - Icon: TwitterLogo, - }, - { - name: SocialsEnum.DISCORD, - href: SOCIALS_LINKS[SocialsEnum.DISCORD], - Icon: DiscordLogo, - }, -]; - -export enum DirInfoConfigKeys { - SECTION_TYPE = "section-type", - SECTION_TITLE = "section-title", - SECTION_URL = "section-url", - ORDER = "order", -} - -export enum LayoutsConfigKeys { - TITLE = "title", - FOLDERS = "folders", -} - -export const GDPR = { - title: "We value your privacy", - text: "We use cookies to enhance your browsing experience and analyze our traffic. By clicking “Accept All”, you consent to our use of cookies.", - readMoreHref: "/privacy-policy.html", -}; diff --git a/docs/src/content/docs-landing/_dirinfo.yaml b/docs/src/content/docs-landing/_dirinfo.yaml deleted file mode 100644 index 9ec3f9e8a0..0000000000 --- a/docs/src/content/docs-landing/_dirinfo.yaml +++ /dev/null @@ -1 +0,0 @@ -section-type: hidden diff --git a/docs/src/content/docs-landing/index.md b/docs/src/content/docs-landing/index.md deleted file mode 100644 index 027a089138..0000000000 --- a/docs/src/content/docs-landing/index.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Documentation -description: Documentation about Hardhat, the Ethereum development environment ---- - -Hardhat is a development environment for Ethereum software. It consists of different components for editing, compiling, debugging and deploying your smart contracts and dApps, all of which work together to create a complete development environment. - -To get started check out these sections: - -- [General overview](/hardhat-runner) -- [Quick start guide](/hardhat-runner/docs/getting-started/index.md#quick-start) -- [Step-by-step tutorial](/tutorial) - -## Browse by component - -:::tip - -If you are in doubt about which component you are looking for, you can start [here.](/hardhat-runner) - -::: - -### Hardhat Runner - -Hardhat Runner is the main component you interact with when using Hardhat. It's a flexible and extensible task runner that helps you manage and automate the recurring tasks inherent to developing smart contracts and dApps. [Learn more.](/hardhat-runner) - -### Hardhat Network - -Hardhat comes built-in with Hardhat Network, a local Ethereum network node designed for development. It allows you to deploy your contracts, run your tests and debug your code, all within the confines of your local machine. [Learn more.](/hardhat-network) - -### Hardhat for Visual Studio Code - -Hardhat for Visual Studio Code is a VS Code extension that adds language support for Solidity and provides editor integration for Hardhat projects. [Learn more.](/hardhat-vscode) - -### Hardhat Chai Matchers - -Hardhat Chai Matchers adds Ethereum-specific capabilities to the [Chai](https://www.chaijs.com/) assertion library, making your smart contract tests easy to write and read. Among other things, you can assert that a contract fired certain events, or that it exhibited a specific revert, or that a transaction resulted in specific changes to a wallet's Ether or token balance. [Learn more.](/hardhat-chai-matchers) - -### Hardhat Network Helpers - -Hardhat Network Helpers provides a convenient JavaScript interface to the JSON-RPC functionality of Hardhat Network. [Learn more.](/hardhat-network-helpers) diff --git a/docs/src/content/hardhat-chai-matchers/_dirinfo.yaml b/docs/src/content/hardhat-chai-matchers/_dirinfo.yaml deleted file mode 100644 index 9ec3f9e8a0..0000000000 --- a/docs/src/content/hardhat-chai-matchers/_dirinfo.yaml +++ /dev/null @@ -1 +0,0 @@ -section-type: hidden diff --git a/docs/src/content/hardhat-chai-matchers/docs/_dirinfo.yaml b/docs/src/content/hardhat-chai-matchers/docs/_dirinfo.yaml deleted file mode 100644 index 1e80258175..0000000000 --- a/docs/src/content/hardhat-chai-matchers/docs/_dirinfo.yaml +++ /dev/null @@ -1,7 +0,0 @@ -section-type: group -section-title: Hardhat Chai Matchers -order: - - title: Overview - href: /overview - - /migrate-from-waffle - - /reference diff --git a/docs/src/content/hardhat-chai-matchers/docs/migrate-from-waffle.md b/docs/src/content/hardhat-chai-matchers/docs/migrate-from-waffle.md deleted file mode 100644 index 485704db0d..0000000000 --- a/docs/src/content/hardhat-chai-matchers/docs/migrate-from-waffle.md +++ /dev/null @@ -1,97 +0,0 @@ -# Migrating from Waffle - -If you want to replace Waffle with Hardhat Chai Matchers, we recommend you [migrate to the Hardhat Toolbox](/hardhat-runner/docs/guides/migrating-from-hardhat-waffle). If for some reason you want to migrate without using the Toolbox, read on. - -## How to migrate - -The `@nomicfoundation/hardhat-chai-matchers` plugin is meant to be a drop-in replacement for the `@nomiclabs/hardhat-waffle` plugin. To migrate, follow these instructions: - -1. Uninstall the `@nomiclabs/hardhat-waffle` and `ethereum-waffle` packages: - - ::::tabsgroup{options="npm 7+,npm 6,yarn"} - - :::tab{value="npm 7+"} - - ``` - npm uninstall @nomiclabs/hardhat-waffle ethereum-waffle - ``` - - ::: - - :::tab{value="npm 6"} - - ``` - npm uninstall @nomiclabs/hardhat-waffle ethereum-waffle - ``` - - ::: - - :::tab{value=yarn} - - ``` - yarn remove @nomiclabs/hardhat-waffle ethereum-waffle - ``` - - ::: - - :::: - -2. Then install the Hardhat Chai Matchers plugin: - - ::::tabsgroup{options="npm 7+,npm 6,yarn"} - - :::tab{value="npm 7+"} - - ``` - npm install --save-dev @nomicfoundation/hardhat-chai-matchers - ``` - - ::: - - :::tab{value="npm 6"} - - ``` - npm install --save-dev @nomicfoundation/hardhat-chai-matchers - ``` - - ::: - - :::tab{value=yarn} - - ``` - yarn add --dev @nomicfoundation/hardhat-chai-matchers - ``` - - ::: - - :::: - -3. In your Hardhat config, import the Hardhat Chai Matchers plugin and remove the `hardhat-waffle` one: - - ::::tabsgroup{options=TypeScript,JavaScript} - - :::tab{value=TypeScript} - - ```diff - - import "@nomiclabs/hardhat-waffle"; - + import "@nomicfoundation/hardhat-chai-matchers"; - ``` - - ::: - - :::tab{value=JavaScript} - - ```diff - - require("@nomiclabs/hardhat-waffle"); - + require("@nomicfoundation/hardhat-chai-matchers"); - ``` - - ::: - - :::: - -:::tip - -Looking for a replacement for Waffle's `loadFixture`? You can find our version of it in [Hardhat Network Helpers](/hardhat-network-helpers/docs/reference#fixtures). - -::: diff --git a/docs/src/content/hardhat-chai-matchers/docs/other-components/_dirinfo.yaml b/docs/src/content/hardhat-chai-matchers/docs/other-components/_dirinfo.yaml deleted file mode 100644 index 2a4a770f9e..0000000000 --- a/docs/src/content/hardhat-chai-matchers/docs/other-components/_dirinfo.yaml +++ /dev/null @@ -1,11 +0,0 @@ -section-type: group -section-title: Other Hardhat components -order: - - href: /../../../hardhat-runner/docs - title: Hardhat Runner - - href: /../../../hardhat-network/docs - title: Hardhat Network - - href: /../../../hardhat-vscode/docs - title: Hardhat VSCode - - href: /../../../hardhat-network-helpers/docs - title: Hardhat Network Helpers diff --git a/docs/src/content/hardhat-chai-matchers/docs/overview.md b/docs/src/content/hardhat-chai-matchers/docs/overview.md deleted file mode 100644 index a61f57b0c8..0000000000 --- a/docs/src/content/hardhat-chai-matchers/docs/overview.md +++ /dev/null @@ -1,241 +0,0 @@ ---- -title: Hardhat Chai Matchers -description: Hardhat Chai Matchers is a Hardhat plugin that builds on top of Chai, extending it with Ethereum-related assertion utilities. ---- - -# Overview - -[@nomicfoundation/hardhat-chai-matchers](https://www.npmjs.com/package/@nomicfoundation/hardhat-chai-matchers) adds Ethereum-specific capabilities to the [Chai](https://www.chaijs.com/) assertion library, making your smart contract tests easy to write and read. - -Among other things, you can assert that a contract fired certain events, or that it exhibited a specific revert, or that a transaction resulted in specific changes to a wallet's Ether or token balance. - -## Installation - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm install --save-dev @nomicfoundation/hardhat-chai-matchers -``` - -::: - -:::tab{value="npm 6"} - -``` -npm install --save-dev @nomicfoundation/hardhat-chai-matchers -``` - -::: - -:::tab{value=yarn} - -``` -yarn add --dev @nomicfoundation/hardhat-chai-matchers -``` - -::: - -:::: - -## How can I use it? - -Simply `require("@nomicfoundation/hardhat-chai-matchers")` in your Hardhat config and then the assertions will be available in your code. - -A few other helpers, such as argument predicates and panic code constants, must be imported explicitly. These are discussed below. - -## Why would I want to use it? - -### Events - -You can easily write tests to verify that your contract emitted a certain event. For example, `await expect(contract.call()).to.emit(contract, "Event")` would detect the event emitted by the following Solidity code: - -```solidity -contract C { - event Event(); - function call () public { - emit Event(); - } -} -``` - -Note that the `await` is required before an `expect(...).to.emit(...)`, because the verification requires the retrieval of the event logs from the Ethereum node, which is an asynchronous operation. Without that initial `await`, your test may run to completion before the Ethereum transaction even completes. - -Also note that the first argument to `emit()` is the contract which emits the event. If your contract calls another contract, and you want to detect an event from the inner contract, you need to pass in the inner contract to `emit()`. - -#### Events with Arguments - -Solidity events can contain arguments, and you can assert the presence of certain argument values in an event that was emitted. For example, to assert that an event emits a certain unsigned integer value: - - -```js -await expect(contract.call()) - .to.emit(contract, "Uint") - .withArgs(3); -``` - -Sometimes you may want to assert the value of the second argument of an event, but you want to permit any value for the first argument. This is easy with `withArgs` because it supports not just specific values but also _predicates_. For example, to skip checking the first argument but assert the value of the second: - -```js -const { anyValue } = require("@nomicfoundation/hardhat-chai-matchers/withArgs"); -await expect(contract.call()) - .to.emit(contract, "TwoUints") - .withArgs(anyValue, 3); -``` - -Predicates are simply functions that, when called, indicate whether the value should be considered successfully matched or not. The function will receive the value as its input, but it need not use it. For example, the `anyValue` predicate is simply `() => true`. - -This package provides the predicates `anyValue` and `anyUint`, but you can easily create your own: - - -```js -function isEven(x: BigNumber): boolean { - return x.mod(2).isZero(); -} - -await expect(contract.emitUint(2)) - .to.emit(contract, "Uint") - .withArgs(isEven); -``` - -### Reverts - -You can also easily write tests that assert whether a contract call reverted (or not) and what sort of error data to expect along with the revert. - -The most simple case asserts that a revert happened: - -```js -await expect(contract.call()).to.be.reverted; -``` - -Or, conversely, that one didn't: - -```js -await expect(contract.call()).not.to.be.reverted; -``` - -A revert may also include some error data, such as a string, a [panic code](https://docs.soliditylang.org/en/v0.8.14/control-structures.html#panic-via-assert-and-error-via-require), or a [custom error](https://docs.soliditylang.org/en/v0.8.14/contracts.html#errors-and-the-revert-statement), and this package provides matchers for all of them. - -The `revertedWith` matcher allows you to assert that a revert's error data does or doesn't match a specific string: - -```js -await expect(contract.call()).to.be.revertedWith("Some revert message"); -await expect(contract.call()).not.to.be.revertedWith("Another revert message"); -``` - -The `revertedWithPanic` matcher allows you to assert that a revert did or didn't occur with a specific [panic code](https://docs.soliditylang.org/en/v0.8.14/control-structures.html#panic-via-assert-and-error-via-require). You can match a panic code via its integer value (including via hexadecimal notation, such as `0x12`) or via the `PANIC_CODES` dictionary exported from this package: - -```js -const { PANIC_CODES } = require("@nomicfoundation/hardhat-chai-matchers/panic"); - -await expect(contract.divideBy(0)).to.be.revertedWithPanic( - PANIC_CODES.DIVISION_BY_ZERO -); - -await expect(contract.divideBy(1)).not.to.be.revertedWithPanic( - PANIC_CODES.DIVISION_BY_ZERO -); -``` - -You can omit the panic code in order to assert that the transaction reverted with _any_ panic code. - -The `revertedWithCustomError` matcher allows you to assert that a transaction reverted with a specific [custom error](https://docs.soliditylang.org/en/v0.8.14/contracts.html#errors-and-the-revert-statement): - -```js -await expect(contract.call()).to.be.revertedWithCustomError( - contract, - "SomeCustomError" -); -``` - -Just as with events, the first argument to this matcher must specify the contract that defines the custom error. If you're expecting an error from a nested call to a different contract, then you'll need to pass that different contract as the first argument. - -Further, just as events can have arguments, so too can custom error objects, and, just as with events, you can assert the values of these arguments. To do this, use the same `.withArgs()` matcher, and the same predicate system: - -```js -await expect(contract.call()) - .to.be.revertedWithCustomError(contract, "SomeCustomError") - .withArgs(anyValue, "some error data string"); -``` - -Finally, you can assert that a call reverted without any error data (neither a reason string, nor a panic code, nor a custom error): - -```js -await expect(contract.call()).to.be.revertedWithoutReason(); -``` - -### Big Numbers - -Working with Ethereum smart contracts in JavaScript can be annoying due Ethereum's 256-bit native integer size. Contracts returning integer values can yield numbers greater than JavaScript's maximum safe integer value, and writing assertions about the expectations of such values can be difficult without prior familiarity with the 3rd-party big integer library used by your web3 framework. - -This package enhances the standard numerical equality matchers (`equal`, `above`, `within`, etc) such that you can seamlessly mix and match contract return values with regular `Number`s. For example: - -```js -expect(await token.balanceOf(someAddress)).to.equal(1); -``` - -These matchers support not just [ethers' `BigNumber`](https://docs.ethers.io/v5/single-page/#/v5/api/utils/bignumber/) and the native JavaScript `Number`, but also [`BigInt`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt), [bn.js](https://github.com/indutny/bn.js/), and [bignumber.js](https://github.com/MikeMcl/bignumber.js/). - -### Balance Changes - -Oftentimes, a transaction you're testing will be expected to have some effect on a wallet's balance, either its balance of Ether or its balance of some ERC-20 token. Another set of matchers allows you to verify that a transaction resulted in such a balance change: - -```js -await expect(() => - sender.sendTransaction({ to: someAddress, value: 200 }) -).to.changeEtherBalance(sender, "-200"); - -await expect(token.transfer(account, 1)).to.changeTokenBalance( - token, - account, - 1 -); -``` - -Further, you can also check these conditions for multiple addresses at the same time: - -```js -await expect(() => - sender.sendTransaction({ to: receiver, value: 200 }) -).to.changeEtherBalances([sender, receiver], [-200, 200]); - -await expect(token.transferFrom(sender, receiver, 1)).to.changeTokenBalances( - token, - [sender, receiver], - [-1, 1] -); -``` - -### Miscellaneous String Checks - -Sometimes you may also need to verify that hexadecimal string data is appropriate for the context it's used in. A handful of other matchers help you with this: - -The `properHex` matcher asserts that the given string consists only of valid hexadecimal characters and that its length (the number of hexadecimal digits) matches its second argument: - -```js -expect("0x1234").to.be.properHex(4); -``` - -The `properAddress` matcher asserts that the given string is a hexadecimal value of the proper length (40 hexadecimal digits): - -```js -expect("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266").to.be.a.properAddress; -``` - -The `properPrivateKey` matcher asserts that the given string is a hexadecimal value of the proper length: - -```js -expect("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80").to - .be.a.properPrivateKey; -``` - -Finally, the `hexEqual` matcher accepts two hexadecimal strings and compares their numerical values, regardless of leading zeroes or upper/lower case digits: - -```js -expect("0x00012AB").to.hexEqual("0x12ab"); -``` - -## Dig Deeper - -For a full listing of all of the matchers supported by this package, see [the reference documentation](./reference.md). diff --git a/docs/src/content/hardhat-chai-matchers/docs/reference.md b/docs/src/content/hardhat-chai-matchers/docs/reference.md deleted file mode 100644 index 42f99a9c64..0000000000 --- a/docs/src/content/hardhat-chai-matchers/docs/reference.md +++ /dev/null @@ -1,267 +0,0 @@ -# Reference - -This is the reference for the Hardhat Chai Matchers plugin. This is a [chai](https://www.chaijs.com/) plugin that adds new assertion capabilities for testing smart contracts. - -## Numbers - -When `@nomicfoundation/hardhat-chai-matchers` is used, equality comparisons of numbers will work even if the numbers are represented by different types. This means that assertions like this: - -```ts -expect(await token.totalSupply()).to.equal(1_000_000); -``` - -will work. These assertions don't normally work because the value returned by `totalSupply()` is an [ethers BigNumber](https://docs.ethers.io/v5/single-page/#/v5/api/utils/bignumber/), and an instance of a `BigNumber` will always be different than a plain number. - -The supported types are: - -- Plain javascript numbers -- [BigInts](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt) -- [Ethers BigNumbers](https://docs.ethers.io/v5/single-page/#/v5/api/utils/bignumber/) -- [`bn.js`](https://github.com/indutny/bn.js/) instances -- [`bignumber.js`](https://github.com/MikeMcl/bignumber.js/) instances - -This also works when deep-equal comparisons of arrays or objects are performed: - -```ts -expect(await contract.getRatio()).to.deep.equal([100, 55]); -``` - -## Reverted transactions - -Several matchers are included to assert that a transaction reverted, and the reason of the revert. - -### `.reverted` - -Assert that a transaction reverted for any reason, without checking the cause of the revert: - -```ts -await expect(token.transfer(address, 0)).to.be.reverted; -``` - -### `.revertedWith` - -Assert that a transaction reverted with a specific reason string: - -```ts -await expect(token.transfer(address, 0)).to.be.revertedWith( - "transfer value must be positive" -); -``` - -You can also use regular expressions: - -```ts -await expect(token.transfer(address, 0)).to.be.revertedWith( - /AccessControl: account .* is missing role .*/ -); -``` - -### `.revertedWithCustomError` - -Assert that a transaction reverted with a specific [custom error](https://docs.soliditylang.org/en/v0.8.14/contracts.html#errors-and-the-revert-statement): - -```ts -await expect(token.transfer(address, 0)).to.be.revertedWithCustomError( - token, - "InvalidTransferValue" -); -``` - -The first argument must be the contract that defines the error. - -If the error has arguments, the `.withArgs` matcher can be added: - -```ts -await expect(token.transfer(address, 0)) - .to.be.revertedWithCustomError(token, "InvalidTransferValue") - .withArgs(0); -``` - -See the [`.withArgs`](#.withargs) matcher entry to learn more. - -### `.revertedWithPanic` - -Assert that a transaction reverted with a [panic code](https://docs.soliditylang.org/en/v0.8.14/control-structures.html#panic-via-assert-and-error-via-require): - -```ts -await expect(token.transfer(address, 0)).to.be.revertedWithPanic(); -``` - -An optional argument can be passed to assert that a specific panic code was thrown: - -```ts -await expect(token.transfer(address, 0)).to.be.revertedWithPanic(0x12); -``` - -You can also import and use the `PANIC_CODES` dictionary: - -```ts -import { PANIC_CODES } from "@nomicfoundation/hardhat-chai-matchers/panic"; - -await expect(token.transfer(address, 0)).to.be.revertedWithPanic( - PANIC_CODES.DIVISION_BY_ZERO -); -``` - -### `.revertedWithoutReason` - -Assert that a transaction reverted without returning a reason: - -```ts -await expect(token.transfer(address, 0)).to.be.revertedWithoutReason(); -``` - -This matcher differs from `.reverted` in that it will fail if the transaction reverts with a reason string, custom error or panic code. Examples of Solidity expressions that revert without a reason are `require(false)` (without the reason string) and `assert(false)` before Solidity v0.8.0. This also happens for out-of-gas errors. - -## Events - -### `.emit` - -Assert that a transaction emits a specific event: - -```ts -await expect(token.transfer(address, 100)).to.emit(token, "Transfer"); -``` - -The first argument must be the contract that emits the event. - -If the event has arguments, the `.withArgs` matcher can be added: - -```ts -await expect(token.transfer(address, 0)) - .to.be.revertedWithCustomError(token, "InvalidTransferValue") - .withArgs(100); -``` - -See the [`.withArgs`](#.withargs) matcher entry to learn more. - -## Balance change - -These matchers can be used to assert how a given transaction affects the ether balance, or an ERC20 token balance, of a specific address. - -All these matchers assume that the given transaction is the only transaction mined in its block. - -### `.changeEtherBalance` - -Assert that the ether balance of an address changed by a specific amount: - -```ts -await expect( - sender.sendTransaction({ to: receiver, value: 1000 }) -).to.changeEtherBalance(sender, -1000); -``` - -This matcher ignores the fees of the transaction, but you can include them with the `includeFee` option: - -```ts -await expect( - sender.sendTransaction({ to: receiver, value: 1000 }) -).to.changeEtherBalance(sender, -22000, { includeFee: true }); -``` - -### `.changeTokenBalance` - -Assert that an ERC20 token balance of an address changed by a specific amount: - -```ts -await expect(token.transfer(receiver, 1000)).to.changeTokenBalance( - token, - sender, - -1000 -); -``` - -The first argument must be the contract of the token. - -### `.changeEtherBalances` - -Like `.changeEtherBalance`, but allows checking multiple addresses at the same time: - -```ts -await expect( - sender.sendTransaction({ to: receiver, value: 1000 }) -).to.changeEtherBalances([sender, receiver], [-1000, 1000]); -``` - -### `.changeTokenBalances` - -Like `.changeTokenBalance`, but allows checking multiple addresses at the same time: - -```ts -await expect(token.transfer(receiver, 1000)).to.changeTokenBalances( - token, - [sender, receiver], - [-1000, 1000] -); -``` - -## Other matchers - -### `.withArgs` - -Can be used after a `.emit` or a `.revertedWithCustomError` matcher to assert the values of the event/error's arguments: - -```ts -// events -await expect(token.transfer(address, 0)) - .to.be.revertedWithCustomError(token, "InvalidTransferValue") - .withArgs(100); - -// errors -await expect(token.transfer(address, 0)) - .to.be.revertedWithCustomError(token, "InvalidTransferValue") - .withArgs(0); -``` - -If you don't care about the value of one of the arguments, you can use the `anyValue` predicate: - -```ts -import { anyValue } from "@nomicfoundation/hardhat-chai-matchers/withArgs"; - -await expect(factory.create(9999)) - .to.emit(factory, "Created") - .withArgs(anyValue, 9999); -``` - -Predicates are just functions that return true if the value is correct, and return false if it isn't, so you can create your own predicates: - -```ts -function isEven(x: BigNumber): boolean { - return x.mod(2).isZero(); -} - -await expect(token.transfer(100)).to.emit(token, "Transfer").withArgs(isEven); -``` - -### `.properAddress` - -Assert that the given string is a proper address: - -```ts -expect("0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266").to.be.properAddress; -``` - -### `.properPrivateKey` - -Assert that the given string is a proper private key: - -```ts -expect("0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80").to - .be.properPrivateKey; -``` - -### `.properHex` - -Assert that the given string is a proper hexadecimal string of a specific length: - -```ts -expect("0x1234").to.be.properHex(4); -``` - -### `.hexEqual` - -Assert that the given strings hexadecimal strings correspond to the same numerical value: - -```ts -expect("0x00012AB").to.hexEqual("0x12ab"); -``` diff --git a/docs/src/content/hardhat-network-helpers/_dirinfo.yaml b/docs/src/content/hardhat-network-helpers/_dirinfo.yaml deleted file mode 100644 index 9ec3f9e8a0..0000000000 --- a/docs/src/content/hardhat-network-helpers/_dirinfo.yaml +++ /dev/null @@ -1 +0,0 @@ -section-type: hidden diff --git a/docs/src/content/hardhat-network-helpers/docs/_dirinfo.yaml b/docs/src/content/hardhat-network-helpers/docs/_dirinfo.yaml deleted file mode 100644 index 4695387b0c..0000000000 --- a/docs/src/content/hardhat-network-helpers/docs/_dirinfo.yaml +++ /dev/null @@ -1,6 +0,0 @@ -section-type: group -section-title: Hardhat Network Helpers -order: - - title: Overview - href: /overview - - /reference diff --git a/docs/src/content/hardhat-network-helpers/docs/other-components/_dirinfo.yaml b/docs/src/content/hardhat-network-helpers/docs/other-components/_dirinfo.yaml deleted file mode 100644 index de33f52bc1..0000000000 --- a/docs/src/content/hardhat-network-helpers/docs/other-components/_dirinfo.yaml +++ /dev/null @@ -1,11 +0,0 @@ -section-type: group -section-title: Other Hardhat components -order: - - href: /../../../hardhat-runner/docs - title: Hardhat Runner - - href: /../../../hardhat-network/docs - title: Hardhat Network - - href: /../../../hardhat-vscode/docs - title: Hardhat VSCode - - href: /../../../hardhat-chai-matchers/docs - title: Hardhat Chai Matchers diff --git a/docs/src/content/hardhat-network-helpers/docs/overview.md b/docs/src/content/hardhat-network-helpers/docs/overview.md deleted file mode 100644 index 5730f9a16d..0000000000 --- a/docs/src/content/hardhat-network-helpers/docs/overview.md +++ /dev/null @@ -1,80 +0,0 @@ ---- -title: Hardhat Network Helpers -description: Hardhat Network Helpers is a library that provides a set of utility functions to interact with the Hardhat Network. ---- - -# Overview - -[@nomicfoundation/hardhat-network-helpers](https://www.npmjs.com/package/@nomicfoundation/hardhat-network-helpers) provides a convenient JavaScript interface to the JSON-RPC functionality of [Hardhat Network](/hardhat-network). - -Hardhat Network exposes its custom functionality primarily through its JSON-RPC API. See the extensive set of methods available in [its reference documentation](/hardhat-network/docs/reference#hardhat-network-methods). However, for easy-to-read tests and short scripts, interfacing with the JSON-RPC API is too noisy, requiring a verbose syntax and extensive conversions of both input and output data. - -This package provides convenience functions for quick and easy interaction with Hardhat Network. Facilities include the ability to mine blocks up to a certain timestamp or block number, the ability to manipulate attributes of accounts (balance, code, nonce, storage), the ability to impersonate specific accounts, and the ability to take and restore snapshots. - -## Installation - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm install --save-dev @nomicfoundation/hardhat-network-helpers -``` - -::: - -:::tab{value="npm 6"} - -``` -npm install --save-dev @nomicfoundation/hardhat-network-helpers -``` - -::: - -:::tab{value=yarn} - -``` -yarn add --dev @nomicfoundation/hardhat-network-helpers -``` - -::: - -:::: - -## Usage - -To use a network helper, simply import it where you want to use it: - -::::tabsgroup{options=TypeScript,JavaScript} - -:::tab{value=TypeScript} - -```ts -import { mine } from "@nomicfoundation/hardhat-network-helpers"; - -async function main() { - // instantly mine 1000 blocks - await mine(1000); -} -``` - -::: - -:::tab{value=JavaScript} - -```js -const { mine } = require("@nomicfoundation/hardhat-network-helpers"); - -async function main() { - // instantly mine 1000 blocks - await mine(1000); -} -``` - -::: - -:::: - -Since this is not a Hardhat plugin, you don’t need to import the whole package in your config. You can simply import each specific helper function where you need to use them. - -For a full listing of all the helpers provided by this package, see [the reference documentation](./reference). diff --git a/docs/src/content/hardhat-network-helpers/docs/reference.md b/docs/src/content/hardhat-network-helpers/docs/reference.md deleted file mode 100644 index 19562c8a5f..0000000000 --- a/docs/src/content/hardhat-network-helpers/docs/reference.md +++ /dev/null @@ -1,318 +0,0 @@ -# Reference - -This is the reference for the Hardhat Network Helpers library. This library contains utility functions to interact with the Hardhat Network in an easier and safer way. - -## Mining blocks - -### `mine([blocks], [options])` - -Mines a specified number of blocks at a given interval. - -Parameters: - -- `blocks`: Number of blocks to mine. Defaults to 1. -- `options.interval`: Configures the interval (in seconds) between the timestamps of each mined block. Defaults to 1. - -Example: - -```ts -// mine a new block -await helpers.mine(); - -// mine several blocks -await helpers.mine(1000); - -// mine several blocks with a given interval between their timestamps -await helpers.mine(1000, { interval: 15 }); -``` - -### `mineUpTo(blockNumber)` - -Mines new blocks until the latest block number is `blockNumber`. - -Parameters: - -- `blockNumber`: Must be greater than the latest block's number. - -Example: - -```ts -await helpers.mineUpTo(1234); -``` - -## Manipulating accounts - -### `setBalance(address, balance)` - -Sets the balance for the given address. - -Parameters: - -- `address`: The address whose balance will be edited. -- `balance`: The new balance to set for the given address, in wei. - -Example: - -```ts -await helpers.setBalance(address, 100n ** 18n); -``` - -### `setCode(address, code)` - -Modifies the contract bytecode stored at an account's address. - -Parameters: - -- `address`: The address where the given code should be stored. -- `code`: The code to store. - -Example: - -```ts -await helpers.setCode(address, "0x1234..."); -``` - -### `setNonce(address, nonce)` - -Modifies an account's nonce by overwriting it. - -Parameters: - -- `address`: The address whose nonce is to be changed. -- `nonce`: The new nonce. - -Example: - -```ts -await helpers.setNonce(address, 100); -``` - -### `setStorageAt(address, index, value)` - -Writes a single position of an account's storage. - -Parameters: - -- `address`: The address where the code should be stored. -- `index`: The index in storage. -- `value`: The value to store. - -Example: - -```ts -await helpers.setStorageAt(address, storageSlot, newValue); -``` - -### `getStorageAt(address, index, [block])` - -Retrieves the data located at the given address, index, and block number. - -Parameters: - -- `address`: The address to retrieve storage from. -- `index`: The position in storage. -- `block`: The block number, or one of `"latest"`, `"earliest"`, or `"pending"`. Defaults to `"latest"`. - -Returns: A string containing the hexadecimal value retrieved. - -Example: - -```ts -await helpers.getStorageAt(address, storageSlot); -``` - -### `impersonateAccount(address)` - -Allows Hardhat Network to sign subsequent transactions as the given address. - -Parameters: - -- `address`: The address to impersonate. - -Example: - -```ts -await helpers.impersonateAccount(address); -``` - -### `stopImpersonatingAccount(address)` - -Stops Hardhat Network from impersonating the given address. - -Parameters: - -- `address`: The address to stop impersonating. - -Example: - -```ts -await helpers.stopImpersonatingAccount(address); -``` - -## Time helpers - -### `latest()` - -Returns the timestamp of the latest block. - -Example: - -```ts -await helpers.time.latest(); -``` - -### `latestBlock()` - -Returns the number of the latest block. - -Example: - -```ts -await helpers.time.latestBlock(); -``` - -### `increase(amountInSeconds)` - -Mines a new block whose timestamp is `amountInSeconds` after the latest block's timestamp. - -Parameters: - -- `amountInSeconds`: Number of seconds to increase the next block's timestamp by. - -Returns: The timestamp of the mined block. - -Example: - -```ts -// advance time by one hour and mine a new block -await helpers.time.increase(3600); -``` - -### `increaseTo(timestamp)` - -Mines a new block whose timestamp is `timestamp`. - -Parameters: - -- `timestamp`: Must be bigger than the latest block's timestamp. - -Example: - -```ts -await helpers.time.increaseTo(newTimestamp); -``` - -### `setNextBlockTimestamp(timestamp)` - -Sets the timestamp of the next block but doesn't mine one. - -Parameters: - -- `timestamp`: Can be `Date` or [Epoch seconds](https://en.wikipedia.org/wiki/Unix_time). Must be greater than the latest block's timestamp. - -Example: - -```ts -// set the timestamp of the next block but don't mine a new block -await helpers.time.setNextBlockTimestamp(newTimestamp); -``` - -## Snapshots - -### `takeSnapshot()` - -Takes a snapshot of the state of the blockchain at the current block. - -Returns: An object with a `restore` method that can be used to reset the network to the state in the snapshot. - -Example: - -```ts -// take a snapshot of the current state of the blockchain -const snapshot = await helpers.takeSnapshot(); - -// after doing some changes, you can restore to the state of the snapshot -await snapshot.restore(); -``` - -## Fixtures - -### `loadFixture()` - -Useful in tests for setting up the desired state of the network. - -Executes the given function and takes a snapshot of the blockchain. Upon subsequent calls to `loadFixture` with the same function, rather than executing the function again, the blockchain will be restored to that snapshot. - -_Warning_: don't use `loadFixture` with an anonymous function, otherwise the function will be executed each time instead of using snapshots: - -- Correct usage: `loadFixture(deployTokens)` -- Incorrect usage: `loadFixture(async () => { ... })` - -Parameters: - -- `fixture`: The function that will be used to set up the fixture. - -Example: - -```ts -async function deployContractsFixture() { - const token = await Token.deploy(...); - const exchange = await Exchange.deploy(...); - - return { token, exchange }; -} - -it("test", async function () { - const { token, exchange } = await loadFixture(deployContractsFixture); - - // use token and exchanges contracts -}) -``` - -## Other helpers - -### `dropTransaction(txHash)` - -Removes the given transaction from the mempool, if it exists. - -Parameters: - -- `txHash`: Transaction hash to be removed from the mempool. - -Returns: `true` if successful, otherwise `false`. - -Throws: if the transaction was already mined. - -Example: - -```ts -await helpers.dropTransaction( - "0x1010101010101010101010101010101010101010101010101010101010101010" -); -``` - -### `setNextBlockBaseFeePerGas(baseFeePerGas)` - -Sets the base fee of the next block. - -Parameters: - -- `baseFeePerGas`: The new base fee to use. - -### `setPrevRandao(prevRandao)` - -Sets the PREVRANDAO value of the next block. - -Parameters: - -- `prevRandao`: The new PREVRANDAO value to use. - -## Other helpers - -### `reset([url], [blockNumber])` - -Resets the Hardhat Network. The result of calling this method depends on which arguments are provided: - -- If a `url` and a `blockNumber` are passed, the network will be reset to a forked state using that URL and block number. -- If no `blockNumber` is provided, the network will be reset to a forked state using the latest block number that can be forked with a low probability of being reorged. -- If the function is called without arguments, the network will be reset to a local, non-forked state. diff --git a/docs/src/content/hardhat-network/_dirinfo.yaml b/docs/src/content/hardhat-network/_dirinfo.yaml deleted file mode 100644 index 9ec3f9e8a0..0000000000 --- a/docs/src/content/hardhat-network/_dirinfo.yaml +++ /dev/null @@ -1 +0,0 @@ -section-type: hidden diff --git a/docs/src/content/hardhat-network/docs/_dirinfo.yaml b/docs/src/content/hardhat-network/docs/_dirinfo.yaml deleted file mode 100644 index c5337958cf..0000000000 --- a/docs/src/content/hardhat-network/docs/_dirinfo.yaml +++ /dev/null @@ -1,8 +0,0 @@ -section-type: group -section-title: Hardhat Network -order: - - title: Overview - href: /overview - - /guides/forking-other-networks - - /explanation/mining-modes - - /reference diff --git a/docs/src/content/hardhat-network/docs/explanation/mining-modes.md b/docs/src/content/hardhat-network/docs/explanation/mining-modes.md deleted file mode 100644 index 3a2a7a6b29..0000000000 --- a/docs/src/content/hardhat-network/docs/explanation/mining-modes.md +++ /dev/null @@ -1,75 +0,0 @@ -# Mining Modes - -Hardhat Network can be configured to **automine** blocks, immediately upon receiving each transaction, or it can be configured for **interval mining**, where a new block is mined periodically, incorporating as many pending transactions as possible. - -You can use one of these modes, both or neither. By default, only the automine mode is enabled. - -When automine is disabled, every sent transaction is added to the mempool, which contains all the transactions that could be mined in the future. By default, Hardhat Network's mempool follows the same rules as Geth. This means, among other things, that transactions are prioritized by fees paid to the miner (and then by arrival time), and that invalid transactions are dropped. In addition to the default mempool behavior, an [alternative FIFO behavior is also available](../reference/index.md#transaction-ordering). - -When automine is disabled, pending transactions can be queried via the `eth_getBlockByNumber` RPC method (with `"pending"` as the block number argument), they can be removed using the `hardhat_dropTransaction` RPC method, and they can be replaced by submitting a new transaction with the same nonce but with a 10+% increase in fees paid to the miner. - -If neither mining mode is enabled, no new blocks will be mined, but you can manually mine new blocks using the `evm_mine` RPC method. This will generate a new block that will include as many pending transactions as possible. - -## Mempool behavior - -When automine is disabled, every sent transaction is added to the mempool, which contains all the transactions that could be mined in the future. By default, Hardhat Network's mempool follows the same rules as Geth. This means, among other things, that: - -- Transactions with a higher gas price are included first -- If two transactions can be included and both are offering the miner the same total fees, the one that was received first is included first -- If a transaction is invalid (for example, its nonce is lower than the nonce of the address that sent it), the transaction is dropped. - -You can get the list of pending transactions that will be included in the next block by using the "pending" block tag: - -```js -const pendingBlock = await network.provider.send("eth_getBlockByNumber", [ - "pending", - false, -]); -``` - -### Mining transactions in FIFO order - -The way Hardhat Network's mempool orders transactions is customizable. By default, they are prioritized following Geth's rules, but you can enable a FIFO behavior instead, which ensures that transactions are added to blocks in the same order they are sent, and which is useful to recreate blocks from other networks. - -You can enable the FIFO behavior in your config with: - -```json -networks: { - hardhat: { - mining: { - mempool: { - order: "fifo" - } - } - } -} -``` - -## Removing and replacing transactions - -Transactions in the mempool can be removed using the [`dropTransaction`]() network helper: - -```js -const txHash = "0xabc..."; -await helpers.dropTransaction(txHash); -``` - -You can also replace a transaction by sending a new one with the same nonce as the one that it's already in the mempool but with a higher gas price. Keep in mind that, like in Geth, for this to work the new gas/fees prices have to be at least 10% higher than the gas price of the current transaction. - -## Configuring Mining Modes - -See [the Mining Modes configuration reference](../reference/index.md#mining-modes) to understand what to put in your Hardhat config file. - -### Using RPC methods - -You can change the mining behavior at runtime using two RPC methods: `evm_setAutomine` and `evm_setIntervalMining`. For example, to disable automining: - -```js -await network.provider.send("evm_setAutomine", [false]); -``` - -And to enable interval mining: - -```js -await network.provider.send("evm_setIntervalMining", [5000]); -``` diff --git a/docs/src/content/hardhat-network/docs/guides/forking-other-networks.md b/docs/src/content/hardhat-network/docs/guides/forking-other-networks.md deleted file mode 100644 index e987e66e87..0000000000 --- a/docs/src/content/hardhat-network/docs/guides/forking-other-networks.md +++ /dev/null @@ -1,237 +0,0 @@ -# Forking other networks - -You can start an instance of Hardhat Network that forks mainnet. This means that it will simulate having the same state as mainnet, but it will work as a local development network. That way you can interact with deployed protocols and test complex interactions locally. - -To use this feature you need to connect to an archive node. We recommend using [Infura] or [Alchemy]. - -## Forking from mainnet - -The easiest way to try this feature is to start a node from the command line: - -::::tabsgroup{options=Infura,Alchemy} - -:::tab{value=Infura} - -``` -npx hardhat node --fork https://mainnet.infura.io/v3/ -``` - -::: - -:::tab{value=Alchemy} - -``` -npx hardhat node --fork https://eth-mainnet.g.alchemy.com/v2/ - -``` - -::: - -:::: - -You can also configure Hardhat Network to always do this: - -::::tabsgroup{options=Infura,Alchemy} - -:::tab{value=Infura} - -```js -networks: { - hardhat: { - forking: { - url: "https://mainnet.infura.io/v3/", - } - } -} -``` - -::: - -:::tab{value=Alchemy} - -```js -networks: { - hardhat: { - forking: { - url: "https://eth-mainnet.g.alchemy.com/v2/", - } - } -} -``` - -::: - -:::: - -(Note that you'll need to replace the `` component of the URL with your personal Infura or Alchemy API key.) - -By accessing any state that exists on mainnet, Hardhat Network will pull the data and expose it transparently as if it was available locally. - -## Pinning a block - -Hardhat Network will by default fork from a recent mainnet block. While this might be practical depending on the context, to set up a test suite that depends on forking we recommend forking from a specific block number. - -There are two reasons for this: - -- The state your tests run against may change between runs. This could cause your tests or scripts to behave differently. -- Pinning enables caching. Every time data is fetched from mainnet, Hardhat Network caches it on disk to speed up future access. If you don't pin the block, there's going to be new data with each new block and the cache won't be useful. We measured up to 20x speed improvements with block pinning. - -**You will need access to a node with archival data for this to work.** This is why we recommend [Infura] or [Alchemy], since their free plans include archival data. - -To pin the block number: - -::::tabsgroup{options=Infura,Alchemy} - -:::tab{value=Infura} - -```js -networks: { - hardhat: { - forking: { - url: "https://mainnet.infura.io/v3/", - blockNumber: 14390000 - } - } -} -``` - -::: - -:::tab{value=Alchemy} - -```js -networks: { - hardhat: { - forking: { - url: "https://eth-mainnet.g.alchemy.com/v2/", - blockNumber: 14390000 - } - } -} -``` - -::: - -:::: - -If you are using the `node` task, you can also specify a block number with the `--fork-block-number` flag: - -::::tabsgroup{options=Infura,Alchemy} - -:::tab{value=Infura} - -``` -npx hardhat node --fork https://mainnet.infura.io/v3/ --fork-block-number 14390000 -``` - -::: - -:::tab{value=Alchemy} - -``` -npx hardhat node --fork https://eth-mainnet.g.alchemy.com/v2/ --fork-block-number 14390000 -``` - -::: - -:::: - -## Custom HTTP headers - -You can add extra HTTP headers that will be used in any request made to the forked node. One reason to do this is for authorization: instead of including your credentials in the URL, you can use a bearer token via a custom HTTP header: - -```js -networks: { - hardhat: { - forking: { - url: "https://ethnode.example.com", - httpHeaders: { - "Authorization": "Bearer " - } - } - } -} -``` - -## Impersonating accounts - -Hardhat Network allows you to impersonate any address. This lets you send transactions from that account even if you don't have access to its private key. - -The easiest way to do this is with the `ethers.getImpersonatedSigner` method, which is added to the `ethers` object by the [`hardhat-ethers`](/hardhat-runner/plugins/nomiclabs-hardhat-ethers) plugin: - -```js -const impersonatedSigner = await ethers.getImpersonatedSigner("0x1234567890123456789012345678901234567890"); -await impersonatedSigner.sendTransaction(...); -``` - -Alternatively, you can use the [`impersonateAccount`]() helper and then obtain the signer for that address: - -```js -const helpers = require("@nomicfoundation/hardhat-network-helpers"); - -const address = "0x1234567890123456789012345678901234567890"; -await helpers.impersonateAccount(address); -const impersonatedSigner = await ethers.getSigner(address); -``` - -## Customizing Hardhat Network's behavior - -Once you've got a local instance of the mainnet chain state, setting that state to the specific needs of your tests is likely the next step. For this, you can use our [Hardhat Network Helpers](/hardhat-network-helpers) library, which allows you to do things like manipulating the time of the network or modify the balance of an account. - -## Resetting the fork - -You can reset the network with the [`reset`]() network helper: - -```js -const helpers = require("@nomicfoundation/hardhat-network-helpers"); - -await helpers.reset(url, blockNumber); -``` - -Both the `url` and the `blockNumber` can be different to the ones that are currently being used by the fork. - -To reset the network to a local, non-forked state, call the helper without any arguments: - -```ts -await helpers.reset(); -``` - -## Using a custom hardfork history - -If you're forking an unusual network, and if you want to execute EVM code in the context of a historical block retrieved from that network, then you will need to configure Hardhat Network to know which hardforks to apply to which blocks. (If you're forking a well-known network, Hardhat Network will automatically choose the right hardfork for the execution of your EVM code, based on known histories of public networks, so you can safely ignore this section.) - -To supply Hardhat Network with a hardfork activation history for your custom chain, use the `networks.hardhat.chains` config field: - -```js -networks: { - hardhat: { - chains: { - 99: { - hardforkHistory: { - berlin: 10000000, - london: 20000000, - }, - } - } - } -} -``` - -In this context, a "historical block" is one whose number is prior to the block you forked from. If you try to run code in the context of a historical block, _without_ having a hardfork history, then an error will be thrown. The known hardfork histories of most public networks are assumed as defaults. - -If you run code in the context of a _non_-historical block, then Hardhat Network will simply use the hardfork specified by the `hardfork` field on its config, eg `networks: { hardhat: { hardfork: "london" } }`, rather than consulting the hardfork history configuration. - -See also [the `chains` entry in the Hardhat Network configuration reference](../reference/#chains). - -## Troubleshooting - -### "Project ID does not have access to archive state" - -When using a node that doesn't have archival data, you will only have access to the state of the blockchain from recent blocks. To avoid this problem, you can use either a local archive node or a service that provides archival data, like [Infura] or [Alchemy]. - -## See also - -For full details on what's supported, see [the Hardhat Network Config Reference](../reference/#config). - -[infura]: https://infura.io -[alchemy]: https://alchemy.com diff --git a/docs/src/content/hardhat-network/docs/metamask-issue/_dirinfo.yaml b/docs/src/content/hardhat-network/docs/metamask-issue/_dirinfo.yaml deleted file mode 100644 index 9ec3f9e8a0..0000000000 --- a/docs/src/content/hardhat-network/docs/metamask-issue/_dirinfo.yaml +++ /dev/null @@ -1 +0,0 @@ -section-type: hidden diff --git a/docs/src/content/hardhat-network/docs/metamask-issue/index.md b/docs/src/content/hardhat-network/docs/metamask-issue/index.md deleted file mode 100644 index ade466ab9b..0000000000 --- a/docs/src/content/hardhat-network/docs/metamask-issue/index.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -next: false -prev: false ---- - -# MetaMask chainId issue - -If you are using MetaMask with Hardhat Network, you might get an error like this when you send a transaction: - -``` -Incompatible EIP155-based V 2710 and chain id 31337. See the second parameter of the Transaction constructor to set the chain id. -``` - -This is because MetaMask mistakenly assumes all networks in `http://127.0.0.1:8545` to have a chain id of `1337`, but Hardhat uses a different number by default. **Please upvote [the MetaMask issue about it](https://github.com/MetaMask/metamask-extension/issues/10290) if you want this fixed.** - -In the meantime, consider using an alternative wallet that doesn't have this problem, like [Coinbase Wallet](https://www.coinbase.com/wallet). - -If you want to use MetaMask, you can work around this issue by setting the `chainId` of Hardhat Network to `1337` in your Hardhat config: - -``` -networks: { - hardhat: { - chainId: 1337 - }, -} -``` - -Note that if your setup or any of your plugins depends on the chain id being `31337`, you might need to clean your cache or make further adaptations in your config. diff --git a/docs/src/content/hardhat-network/docs/other-components/_dirinfo.yaml b/docs/src/content/hardhat-network/docs/other-components/_dirinfo.yaml deleted file mode 100644 index 2abe014d46..0000000000 --- a/docs/src/content/hardhat-network/docs/other-components/_dirinfo.yaml +++ /dev/null @@ -1,11 +0,0 @@ -section-type: group -section-title: Other Hardhat components -order: - - href: /../../../hardhat-runner/docs - title: Hardhat Runner - - href: /../../../hardhat-vscode/docs - title: Hardhat VSCode - - href: /../../../hardhat-chai-matchers/docs - title: Hardhat Chai Matchers - - href: /../../../hardhat-network-helpers/docs - title: Hardhat Network Helpers diff --git a/docs/src/content/hardhat-network/docs/overview/index.md b/docs/src/content/hardhat-network/docs/overview/index.md deleted file mode 100644 index 4ef156214c..0000000000 --- a/docs/src/content/hardhat-network/docs/overview/index.md +++ /dev/null @@ -1,179 +0,0 @@ ---- -title: Hardhat Network -description: Hardhat Network is a local Ethereum node designed for development. It allows you to deploy your contracts, run your tests and debug your code. ---- - -# Hardhat Network - - - -Hardhat comes built-in with Hardhat Network, a local Ethereum network node designed for development. It allows you to deploy your contracts, run your tests and debug your code, all within the confines of your local machine. - -## How does it work? - -It runs as either an in-process or stand-alone daemon, servicing JSON-RPC and WebSocket requests. - -By default, it mines a block with each transaction that it receives, in order and with no delay. - -It's backed by the `@ethereumjs/vm` EVM implementation, the same one used by ganache, Remix and Ethereum Studio. - -## How can I use it? - -By default, if you're using Hardhat, then you're already using Hardhat Network. - -When Hardhat executes your tests, scripts or tasks, an in-process Hardhat Network node is started automatically, and all of Hardhat's plugins (ethers.js, web3.js, Waffle, Truffle, etc) will connect directly to this node's provider. - -There's no need to make any changes to your tests or scripts. - -Hardhat Network is simply another network. If you wanted to be explicit, you could run, for example, `npx hardhat run --network hardhat scripts/my-script.js`. - -### Running stand-alone in order to support wallets and other software - -Alternatively, Hardhat Network can run in a stand-alone fashion so that external clients can connect to it. This could be a wallet, your Dapp front-end, or a script. To run Hardhat Network in this way, run: - -``` -$ npx hardhat node -Started HTTP and WebSocket JSON-RPC server at http://127.0.0.1:8545/ - -Accounts -======== -Account #0: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 (10000 ETH) -Private Key: 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80 - -Account #1: 0x70997970c51812dc3a010c7d01b50e0d17dc79c8 (10000 ETH) -Private Key: 0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d -... -``` - -This will start Hardhat Network, and expose it as a JSON-RPC and WebSocket server. - -Then, just connect your wallet or application to `http://127.0.0.1:8545`. - -If you want to connect Hardhat to this node, you just need to run using `--network localhost`. - -:::warning - -_Do not send mainnet Ether to the account addresses shown by `hardhat node`_. Those addresses and private keys are deterministic: they are the same for _all_ Hardhat users. Accordingly, those private keys are well known, so there are probably bots monitoring these addresses on mainnet, waiting to withdraw any funds sent to them. If you add any of those accounts to a wallet (eg Metamask), be very careful to avoid sending any mainnet Ether to them: consider naming the account something like "Hardhat - Unsafe" in order to prevent any mistakes. - -::: - -## Why would I want to use it? - -### Solidity stack traces - -Hardhat Network has first-class Solidity support. It always knows which smart contracts are being run, what they do exactly and why they fail. - -If a transaction or call fails, Hardhat Network will throw an exception. This exception will have a combined JavaScript and Solidity stack trace: stack traces that start in JavaScript/TypeScript up to your call to the contract, and continue with the full Solidity call stack. - -This is an example of a Hardhat Network exception using `TruffleContract`: - -``` -Error: Transaction reverted: function selector was not recognized and there's no fallback function - at ERC721Mock. (contracts/mocks/ERC721Mock.sol:9) - at ERC721Mock._checkOnERC721Received (contracts/token/ERC721/ERC721.sol:334) - at ERC721Mock._safeTransferFrom (contracts/token/ERC721/ERC721.sol:196) - at ERC721Mock.safeTransferFrom (contracts/token/ERC721/ERC721.sol:179) - at ERC721Mock.safeTransferFrom (contracts/token/ERC721/ERC721.sol:162) - at TruffleContract.safeTransferFrom (node_modules/@nomiclabs/truffle-contract/lib/execute.js:157:24) - at Context. (test/token/ERC721/ERC721.behavior.js:321:26) -``` - -The last two lines correspond to the JavaScript test code that executed a failing transaction. The rest is the Solidity stack trace. This way you know exactly why your tests aren't passing. - -### Automatic error messages - -Hardhat Network always knows why your transaction or call failed, and it uses this information to make debugging your contracts easier. - -When a transaction fails without a reason, Hardhat Network will create a clear error message in the following cases: - -- Calling a non-payable function with ETH - -- Sending ETH to a contract without a payable fallback or receive function - -- Calling a non-existent function when there's no fallback function - -- Calling a function with incorrect parameters - -- Calling an external function that doesn't return the right amount of data - -- Calling an external function on a non-contract account - -- Failing to execute an external call because of its parameters (e.g. trying to send too much ETH) - -- Calling a library without `DELEGATECALL` - -- Incorrectly calling a precompiled contract - -- Trying to deploy a contract that exceeds the bytecode size limit imposed by [EIP-170](https://eips.ethereum.org/EIPS/eip-170) - -### `console.log` - -Hardhat Network allows you to print logging messages and contract variables by calling `console.log()` from your Solidity code. - -To use it, you simply import `hardhat/console.sol` and call it. It implements the same formatting options that can be found in Node.js' [`console.log`](https://nodejs.org/dist/latest-v12.x/docs/api/console.html#console_console_log_data_args), which in turn uses [`util.format`](https://nodejs.org/dist/latest-v12.x/docs/api/util.html#util_util_format_format_args). For example: `console.log("Changing owner from %s to %s", currentOwner, newOwner)`. - -It always works, regardless of the call or transaction failing or being successful. And, because it's implemented in standard Solidity, it works with _any_ tool or library, emitting log entries where it's fully supported — Hardhat Network, Remix, and Tenderly — and falling back gracefully to a no-op everywhere else — Remix, Waffle, Truffle, etc — though it does consume a small amount of gas on live networks. - -You can see an example in the Sample Project. Follow the steps in [Quick Start](/hardhat-runner/docs/getting-started/index.md#quick-start) to try it out. You can also refer to more details in [the reference documentation](./reference/index.md#console.log). - -### Mainnet forking - -Hardhat Network has the ability to copy the state of the mainnet blockchain into your local environment, including all balances and deployed contracts. This is known as "forking mainnet." - -In a local environment forked from mainnet, you can execute transactions to invoke mainnet-deployed contracts, or interact with the network in any other way that you would with mainnet. In addition, you can do anything supported by a non-forked Hardhat Network: see console logs, get stack traces, or use the default accounts to deploy new contracts. - -More generally, Hardhat Network can be used to fork **any** network, not just mainnet. Even further, Hardhat Network can be used to fork **any EVM-compatible blockchain**, not just Ethereum. - -There are other things you can do with a forked Hardhat Network. Check [our guide](guides/forking-other-networks.md) to learn more. - -### Mining modes - -Hardhat Network can be configured to **automine** blocks, immediately upon receiving each transaction, or it can be configured for **interval mining**, where a new block is mined periodically, incorporating as many pending transactions as possible. - -You can use one of these modes, both or neither. By default, only the automine mode is enabled. - -If neither mining mode is enabled, no new blocks will be mined, but you can manually mine new blocks using the `evm_mine` RPC method. This will generate a new block that will include as many pending transactions as possible. - -For more details on mining modes and mempool behavior, see [Mining Modes](explanation/mining-modes.md). - -### Logging - -Hardhat Network uses its tracing infrastructure to offer rich logging that will help you develop and debug smart contracts. - -For example, a successful transaction and a failed call would look like this: - -``` -eth_sendTransaction - Contract deployment: Greeter - Contract address: 0x8858eeb3dfffa017d4bce9801d340d36cf895ccf - Transaction: 0x7ea2754e53f09508d42bd3074046f90595bedd61fcdf75a4764453454733add0 - From: 0xc783df8a850f42e7f7e57013759c285caa701eb6 - Value: 0 ETH - Gas used: 568851 of 2844255 - Block: #2 - Hash: 0x4847b316b12170c576999183da927c2f2056aa7d8f49f6e87430e6654a56dab0 - - console.log: - Deploying a Greeter with greeting: Hello, world! - -eth_call - Contract call: Greeter#greet - From: 0xc783df8a850f42e7f7e57013759c285caa701eb6 - - Error: VM Exception while processing transaction: revert Not feeling like it - at Greeter.greet (contracts/Greeter.sol:14) - at process._tickCallback (internal/process/next_tick.js:68:7) -``` - -This logging is enabled by default when using Hardhat Network's node (i.e. `npx hardhat node`), but disabled when using the in-process Hardhat Network provider. See [Hardhat Network's config](./reference#config) to learn more about how to control its logging. - -### The `debug_traceTransaction` method - -You can get debug traces of already-mined transactions using the `debug_traceTransaction` RPC method. The returned object has a detailed description of the transaction execution, including a list of steps describing each executed opcode and the state of the EVM at that point. - -If you are using [mainnet forking](guides/forking-other-networks.html) with an archive node, you can get traces of transactions from the remote network even if the node you are using doesn't support `debug_traceTransaction`. - -For more details, see [the reference documentation for this method](./reference/index.md#debug-tracetransaction). - -## Dig deeper - -This has been just a high-level explanation of what Hardhat Network is. To dig deeper, see [the Reference documentation](./reference/index.md). diff --git a/docs/src/content/hardhat-network/docs/reference/index.md b/docs/src/content/hardhat-network/docs/reference/index.md deleted file mode 100644 index 45dde36436..0000000000 --- a/docs/src/content/hardhat-network/docs/reference/index.md +++ /dev/null @@ -1,721 +0,0 @@ -# Reference - -## Supported hardforks - -- byzantium -- constantinople -- petersburg -- istanbul -- muirGlacier -- berlin -- london -- arrowGlacier -- grayGlacier -- merge -- shanghai - -## Config - -### Supported Fields - -You can set the following fields on the `networks.hardhat` config: - -#### `chainId` - -The chain ID number used by Hardhat Network's blockchain. Default value: `31337`. - -#### `from` - -The address to use as default sender. If not present the first account of the Hardhat Network is used. - -#### `gas` - -Its value should be `"auto"` or a number. If a number is used, it will be the gas limit used by default in every transaction. If `"auto"` is used, the gas limit will be automatically estimated. Default value: the same value as `blockGasLimit`. - -Note that when using `ethers` this value will not be applied. - -#### `gasPrice` - -Its value should be `"auto"` or a number (in wei). This parameter behaves like `gas`. Default value: `"auto"`. - -Note that when using `ethers` this value will not be applied. - -#### `gasMultiplier` - -A number used to multiply the results of gas estimation to give it some slack due to the uncertainty of the estimation process. Default value: `1`. - -Note that when using `ethers` this value will not be applied. - -#### `accounts` - -This field can be configured as one of these: - -- An object describing an [HD wallet](#hd-wallet-config). This is the default. It can have any of the following fields: - - `mnemonic`: a 12 or 24 word mnemonic phrase as defined by BIP39. Default value: `"test test test test test test test test test test test junk"` - - `initialIndex`: The initial index to derive. Default value: `0`. - - `path`: The HD parent of all the derived keys. Default value: `"m/44'/60'/0'/0"`. - - `count`: The number of accounts to derive. Default value: `20`. - - `accountsBalance`: string with the balance (in wei) assigned to every account derived. Default value: `"10000000000000000000000"` (10000 ETH). - - `passphrase`: The passphrase for the wallet. Default value: empty string. -- An array of the initial accounts that the Hardhat Network will create. Each of them must be an object with `privateKey` and `balance` fields. - -#### `blockGasLimit` - -The block gas limit to use in Hardhat Network's blockchain. Default value: `30_000_000` - -#### `hardfork` - -This setting changes how Hardhat Network works, to mimic Ethereum's mainnet at a given hardfork. It must be one of `"byzantium"`, `"constantinople"`, `"petersburg"`, `"istanbul"`, `"muirGlacier"`, `"berlin"`, `"london"`, `"arrowGlacier"`, `"grayGlacier"`, `"merge"` and `"shanghai"`. Default value: `"shanghai"` - -#### `throwOnTransactionFailures` - -A boolean that controls if Hardhat Network throws on transaction failures. If this value is `true`, Hardhat Network will throw [combined JavaScript and Solidity stack traces](../index.md#solidity-stack-traces) on transaction failures. If it is `false`, it will return the failing transaction hash. In both cases the transactions are added into the blockchain. Default value: `true` - -#### `throwOnCallFailures` - -A boolean that controls if Hardhat Network throws on call failures. If this value is `true`, Hardhat Network will throw [combined JavaScript and Solidity stack traces](../index.md#solidity-stack-traces) when a call fails. If it is `false`, it will return the call's `return data`, which can contain a revert reason. Default value: `true` - -#### `loggingEnabled` - -A boolean that controls if Hardhat Network logs every request or not. Default value: `false` for the in-process Hardhat Network provider, `true` for the Hardhat Network backed JSON-RPC server (i.e. the `node` task). - -#### `initialDate` - -An optional string setting the date of the blockchain. Valid values are [Javascript's date time strings](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/parse#Date_Time_String_Format). Default value: the current date and time if not forking another network. When forking another network, the timestamp of the block you forked from, plus one second, is used. - -#### `allowUnlimitedContractSize` - -An optional boolean that disables the contract size limit imposed by the [EIP 170](https://eips.ethereum.org/EIPS/eip-170). Default value: `false` - -#### `allowBlocksWithSameTimestamp` - -A boolean to allow mining blocks that have the same timestamp. This is not allowed by default because Ethereum's consensus rules specify that each block should have a different timestamp. Default value: `false` - -#### `forking` - -An object that describes the [forking](./guides/forking-other-networks.md) configuration that can have the following fields: - -- `url`: a URL that points to a JSON-RPC node with state that you want to fork off. There's no default value for this field. It must be provided for the fork to work. -- `blockNumber`: an optional number to pin which block to fork from. If no value is provided, the latest block is used. -- `enabled`: an optional boolean to switch on or off the fork functionality. Default value: `true` if `url` is set, `false` otherwise. - -#### `chains` - -An object that configures chain-specific options. Each key is a number representing a chain ID, and each value is an object configuring the chain with that ID. In the inner object, the following fields are supported: - -- `hardforkHistory`: an object whose keys are strings representing hardfork names (eg `"london"`, `"berlin"`) and whose values are numbers specifying the block at which that hardfork was activated. - -The default value includes configurations for several well known chains (eg mainnet, chain ID `1`); using this field is only useful when forking unusual networks. The user may override the defaults for some chain ID's while leaving the defaults in place for other chain ID's. Overriding the default for a chain ID will replace the entire configuration for that chain. - -For more details, see [Using a custom hardfork history](./guides/forking-other-networks.md#using-a-custom-hardfork-history). - -#### `minGasPrice` - -The minimum `gasPrice` that a transaction must have. This field must not be present if the `"hardfork"` is `"london"` or a later one. Default value: `"0"`. - -#### `initialBaseFeePerGas` - -The `baseFeePerGas` of the first block. Note that when forking a remote network, the "first block" is the one immediately after the block you forked from. This field must not be present if the `"hardfork"` is not `"london"` or a later one. Default value: `"1000000000"` if not forking. When forking a remote network, if the remote network uses EIP-1559, the first local block will use the right `baseFeePerGas` according to the EIP, otherwise `"10000000000"` is used. - -- `coinbase`: The address used as coinbase in new blocks. Default value: `"0xc014ba5ec014ba5ec014ba5ec014ba5ec014ba5e"`. - -### Mining modes - -You can configure the mining behavior under your Hardhat Network settings: - -```js -networks: { - hardhat: { - mining: { - auto: false, - interval: 5000 - } - } -} -``` - -In this example, automining is disabled and interval mining is set so that a new block is generated every 5 seconds. You can also configure interval mining to generate a new block after a random delay: - -```js -networks: { - hardhat: { - mining: { - auto: false, - interval: [3000, 6000] - } - } -} -``` - -In this case, a new block will be mined after a random delay of between 3 and 6 seconds. For example, the first block could be mined after 4 seconds, the second block 5.5 seconds after that, and so on. - -See also [Mining Modes](./explanation/mining-modes.md). - -#### Manual mining - -You can disable both mining modes like this: - -```js -networks: { - hardhat: { - mining: { - auto: false, - interval: 0 - } - } -} -``` - -This means that no new blocks will be mined by the Hardhat Network, but you can manually mine new blocks using the `evm_mine` RPC method. This will generate a new block that will include as many pending transactions as possible. - -#### Transaction ordering - -Hardhat Network can sort mempool transactions in two different ways. How they are sorted will alter which transactions from the mempool get included in the next block, and in which order. - -The first ordering mode, called `"priority"`, mimics Geth's behavior. This means that it prioritizes transactions based on the fees paid to the miner. This is the default. - -The second ordering mode, called `"fifo"`, keeps the mempool transactions sorted in the order they arrive. - -You can change the ordering mode with: - -```json -networks: { - hardhat: { - mining: { - mempool: { - order: "fifo" - } - } - } -} -``` - -## `console.log` - -- You can use it in calls and transactions. It works with `view` functions, but not in `pure` ones. -- It always works, regardless of the call or transaction failing or being successful. -- To use it you need to import `hardhat/console.sol`. -- You can call `console.log` with up to 4 parameters in any order of following types: - - `uint` - - `string` - - `bool` - - `address` -- There's also the single parameter API for the types above, and additionally `bytes`, `bytes1`... up to `bytes32`: - - `console.logInt(int i)` - - `console.logUint(uint i)` - - `console.logString(string memory s)` - - `console.logBool(bool b)` - - `console.logAddress(address a)` - - `console.logBytes(bytes memory b)` - - `console.logBytes1(bytes1 b)` - - `console.logBytes2(bytes2 b)` - - ... - - `console.logBytes32(bytes32 b)` -- `console.log` implements the same formatting options that can be found in Node.js' [`console.log`](https://nodejs.org/dist/latest-v12.x/docs/api/console.html#console_console_log_data_args), which in turn uses [`util.format`](https://nodejs.org/dist/latest-v12.x/docs/api/util.html#util_util_format_format_args). - - Example: `console.log("Changing owner from %s to %s", currentOwner, newOwner)` -- `console.log` is implemented in standard Solidity and then detected in Hardhat Network. This makes its compilation work with any other tools (like Remix, Waffle or Truffle). -- `console.log` calls can run in other networks, like mainnet, sepolia, goerli, etc. They do nothing in those networks, but do spend a minimal amount of gas. -- `console.log` output can also be viewed for testnets and mainnet via [Tenderly](https://tenderly.co/). -- `console.log` works by sending static calls to a well-known contract address. At runtime, Hardhat Network detects calls to that address, decodes the input data to the calls, and writes it to the console. - -## Initial State - -Hardhat Network is initialized by default in this state: - -- A brand new blockchain, just with the genesis block. -- 20 accounts with 10000 ETH each, generated with the mnemonic `"test test test test test test test test test test test junk"`. Their addresses are: - - `0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266` - - `0x70997970C51812dc3A010C7d01b50e0d17dc79C8` - - `0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC` - - `0x90F79bf6EB2c4f870365E785982E1f101E93b906` - - `0x15d34AAf54267DB7D7c367839AAf71A00a2C6A65` - - `0x9965507D1a55bcC2695C58ba16FB37d819B0A4dc` - - `0x976EA74026E726554dB657fA54763abd0C3a0aa9` - - `0x14dC79964da2C08b23698B3D3cc7Ca32193d9955` - - `0x23618e81E3f5cdF7f54C3d65f7FBc0aBf5B21E8f` - - `0xa0Ee7A142d267C1f36714E4a8F75612F20a79720` - - `0xBcd4042DE499D14e55001CcbB24a551F3b954096` - - `0x71bE63f3384f5fb98995898A86B02Fb2426c5788` - - `0xFABB0ac9d68B0B445fB7357272Ff202C5651694a` - - `0x1CBd3b2770909D4e10f157cABC84C7264073C9Ec` - - `0xdF3e18d64BC6A983f673Ab319CCaE4f1a57C7097` - - `0xcd3B766CCDd6AE721141F452C550Ca635964ce71` - - `0x2546BcD3c84621e976D8185a91A922aE77ECEc30` - - `0xbDA5747bFD65F08deb54cb465eB87D40e51B197E` - - `0xdD2FD4581271e230360230F9337D5c0430Bf44C0` - - `0x8626f6940E2eb28930eFb4CeF49B2d1F2C9C1199` - -To customise it, take a look at [the configuration section](/config/index.md#hardhat-network). - -## JSON-RPC methods support - -### Standard methods - -#### `debug_traceTransaction` - -Get debug traces of already-mined transactions. - -To get a trace, call this method with the hash of the transaction as its argument: - -```js -const trace = await hre.network.provider.send("debug_traceTransaction", [ - "0x123...", -]); -``` - -You can also selectively disable some properties in the list of steps: - -```js -const trace = await hre.network.provider.send("debug_traceTransaction", [ - "0x123...", - { - disableMemory: true, - disableStack: true, - disableStorage: true, - }, -]); -``` - -##### Known limitations - -- You can't trace transactions that use a hardfork older than [Spurious Dragon](https://ethereum.org/en/history/#spurious-dragon) -- The last step of a message is not guaranteed to have a correct value in the `gasCost` property - -#### `eth_accounts` - -#### `eth_blockNumber` - -#### `eth_call` - -#### `eth_chainId` - -#### `eth_coinbase` - -#### `eth_estimateGas` - -#### `eth_gasPrice` - -#### `eth_getBalance` - -#### `eth_getBlockByHash` - -#### `eth_getBlockByNumber` - -#### `eth_getBlockTransactionCountByHash` - -#### `eth_getBlockTransactionCountByNumber` - -#### `eth_getCode` - -#### `eth_getFilterChanges` - -#### `eth_getFilterLogs` - -#### `eth_getLogs` - -#### `eth_getStorageAt` - -#### `eth_getTransactionByBlockHashAndIndex` - -#### `eth_getTransactionByBlockNumberAndIndex` - -#### `eth_getTransactionByHash` - -#### `eth_getTransactionCount` - -#### `eth_getTransactionReceipt` - -#### `eth_mining` - -#### `eth_newBlockFilter` - -#### `eth_newFilter` - -#### `eth_newPendingTransactionFilter` - -#### `eth_pendingTransactions` - -#### `eth_sendRawTransaction` - -#### `eth_sendTransaction` - -#### `eth_sign` - -#### `eth_signTypedData_v4` - -#### `eth_subscribe` - -#### `eth_syncing` - -#### `eth_uninstallFilter` - -#### `eth_unsubscribe` - -#### `net_listening` - -#### `net_peerCount` - -#### `net_version` - -#### `web3_clientVersion` - -#### `web3_sha3` - -### Hardhat network methods - -::::tip - -Most of these methods can be used more easily through the [Hardhat Network Helpers](/hardhat-network-helpers) library - -:::: - -#### `hardhat_addCompilationResult` - -Add information about compiled contracts - -#### `hardhat_dropTransaction` - -Remove a transaction from the mempool - - - -#### `hardhat_impersonateAccount` - -Hardhat Network allows you to send transactions impersonating specific account and contract addresses. - -To impersonate an account use this method, passing the address to impersonate as its parameter: - -```tsx -await hre.network.provider.request({ - method: "hardhat_impersonateAccount", - params: ["0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6"], -}); -``` - -If you are using [`hardhat-ethers`](https://github.com/NomicFoundation/hardhat/tree/main/packages/hardhat-ethers), call `getSigner` after impersonating the account: - -``` -const signer = await ethers.getSigner("0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6") -signer.sendTransaction(...) -``` - -Call [`hardhat_stopImpersonatingAccount`](#hardhat-stopimpersonatingaccount) to stop impersonating. - - - -#### `hardhat_getAutomine` - -Returns `true` if automatic mining is enabled, and `false` otherwise. See [Mining Modes](../explanation/mining-modes.md) to learn more. - -#### `hardhat_metadata` - -Returns an object with metadata about the instance of the Hardhat Network. This object contains: - -- `clientVersion`: A string identifying the version of Hardhat, for debugging purposes, not meant to be displayed to users. -- `chainId`: The chain's id. Used to sign transactions. -- `instanceId`: A 0x-prefixed hex-encoded 32 bytes id which uniquely identifies an instance/run of Hardhat Network. Running Hardhat Network more than once (even with the same version and parameters) will always result in different `instanceId`s. Running `hardhat_reset` will change the `instanceId` of an existing Hardhat Network. -- `latestBlockNumber`: The latest block's number in Hardhat Network. -- `latestBlockHash`: The latest block's hash in Hardhat Network. -- `forkedNetwork`: An object with information about the forked network. This field is only present when Hardhat Network is forking another chain. Its fields are: - - `chainId`: The chainId of the network that is being forked - - `forkBlockNumber`: The number of the block that the network forked from. - - `forkBlockHash`: The hash of the block that the network forked from. - -#### `hardhat_mine` - -Sometimes you may want to advance the latest block number of the Hardhat Network by a large number of blocks. One way to do this would be to call the `evm_mine` RPC method multiple times, but this is too slow if you want to mine thousands of blocks. The `hardhat_mine` method can mine any number of blocks at once, in constant time. (It exhibits the same performance no matter how many blocks are mined.) - -`hardhat_mine` accepts two parameters, both of which are optional. The first parameter is the number of blocks to mine, and defaults to 1. The second parameter is the interval between the timestamps of each block, _in seconds_, and it also defaults to 1. (The interval is applied only to blocks mined in the given method invocation, not to blocks mined afterwards.) - -```js -// mine 256 blocks -await hre.network.provider.send("hardhat_mine", ["0x100"]); - -// mine 1000 blocks with an interval of 1 minute -await hre.network.provider.send("hardhat_mine", ["0x3e8", "0x3c"]); -``` - -Note that most blocks mined via this method (all except for the final one) may not technically be valid blocks. Specifically, they have an invalid parent hash, the coinbase account will not have been credited with block rewards, and the `baseFeePerGas` will be incorrect. (The final block in a sequence produced by `hardhat_mine` will always be fully valid.) - -Also note that blocks created via `hardhat_mine` may not trigger new-block events, such as filters created via `eth_newBlockFilter` and WebSocket subscriptions to new-block events. - -#### `hardhat_reset` - -You can manipulate forking during runtime to reset back to a fresh forked state, fork from another block number or disable forking by calling `hardhat_reset`: - -::::tabsgroup{options=Infura,Alchemy} - -:::tab{value=Infura} - -```ts -await network.provider.request({ - method: "hardhat_reset", - params: [ - { - forking: { - jsonRpcUrl: "https://mainnet.infura.io/v3/", - blockNumber: 14390000, - }, - }, - ], -}); -``` - -::: - -:::tab{value=Alchemy} - -```ts -await network.provider.request({ - method: "hardhat_reset", - params: [ - { - forking: { - jsonRpcUrl: "https://eth-mainnet.g.alchemy.com/v2/", - blockNumber: 14390000, - }, - }, - ], -}); -``` - -::: - -:::: - -You can disable forking by passing empty params: - -```ts -await network.provider.request({ - method: "hardhat_reset", - params: [], -}); -``` - -This will reset the Hardhat Network, starting a new instance in the state described [here](#initial-state). - -#### `hardhat_setBalance` - -Modifies the balance of an account. - -For example: - -```tsx -await network.provider.send("hardhat_setBalance", [ - "0x0d2026b3EE6eC71FC6746ADb6311F6d3Ba1C000B", - "0x1000", -]); -``` - -This will result in account `0x0d20...000B` having a balance of 4096 wei. - -#### `hardhat_setCode` - -Modifies the bytecode stored at an account's address. - -For example: - -```tsx -await network.provider.send("hardhat_setCode", [ - "0x0d2026b3EE6eC71FC6746ADb6311F6d3Ba1C000B", - "0xa1a2a3...", -]); -``` - -This will result in account `0x0d20...000B` becoming a smart contract with bytecode `a1a2a3....` If that address was already a smart contract, then its code will be replaced by the specified one. - -#### `hardhat_setCoinbase` - -Sets the coinbase address to be used in new blocks. - -For example: - -```tsx -await network.provider.send("hardhat_setCoinbase", [ - "0x0d2026b3EE6eC71FC6746ADb6311F6d3Ba1C000B", -]); -``` - -This will result in account `0x0d20...000B` being used as miner/coinbase in every new block. - -#### `hardhat_setLoggingEnabled` - -Enable or disable logging in Hardhat Network - -#### `hardhat_setMinGasPrice` - -Change the minimum gas price accepted by the network (in wei) - -#### `hardhat_setNextBlockBaseFeePerGas` - -Sets the base fee of the next block. - -For example: - -```tsx -await network.provider.send("hardhat_setNextBlockBaseFeePerGas", [ - "0x2540be400", // 10 gwei -]); -``` - -This only affects the next block; the base fee will keep being updated in each subsequent block according to [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559). - -#### `hardhat_setPrevRandao` - -Sets the PREVRANDAO value of the next block. - -For example: - -```tsx -await network.provider.send("hardhat_setPrevRandao", [ - "0x1234567812345678123456781234567812345678123456781234567812345678", -]); -``` - -This only affects the next block. The PREVRANDAO of the following blocks will continue to be computed as the keccak256 hash of the previous value. - -#### `hardhat_setNonce` - -Modifies an account's nonce by overwriting it. - -For example: - -```tsx -await network.provider.send("hardhat_setNonce", [ - "0x0d2026b3EE6eC71FC6746ADb6311F6d3Ba1C000B", - "0x21", -]); -``` - -This will result in account `0x0d20...000B` having a nonce of 33. - -Throws an `InvalidInputError` if nonce is smaller than the current one. The reason for this restriction is to avoid collisions when deploying contracts using the same nonce more than once. - -You can only use this method to increase the nonce of an account; you can't set a lower value than the account's current nonce. - -#### `hardhat_setStorageAt` - -Writes a single position of an account's storage. - -For example: - -```tsx -await network.provider.send("hardhat_setStorageAt", [ - "0x0d2026b3EE6eC71FC6746ADb6311F6d3Ba1C000B", - "0x0", - "0x0000000000000000000000000000000000000000000000000000000000000001", -]); -``` - -This will set the contract's first storage position (at index `0x0`) to 1. - -The mapping between a smart contract's variables and its storage position is not straightforward except in some very simple cases. For example, if you deploy this contract: - -```solidity -contract Foo { - uint public x; -} -``` - -And you set the first storage position to 1 (as shown in the previous snippet), then calling `foo.x()` will return 1. - -The storage position index must not exceed 2^256, and the value to write must be exactly 32 bytes long. - -#### `hardhat_stopImpersonatingAccount` - -Use this method to stop impersonating an account after having previously used [`hardhat_impersonateAccount`](#hardhat-impersonateaccount), like: - -```tsx -await hre.network.provider.request({ - method: "hardhat_stopImpersonatingAccount", - params: ["0x364d6D0333432C3Ac016Ca832fb8594A8cE43Ca6"], -}); -``` - -### Special testing/debugging methods - -#### `evm_increaseTime` - -Same as Ganache. - -#### `evm_mine` - -Same as Ganache - -#### `evm_revert` - -Same as Ganache. - -#### `evm_setAutomine` - -Enables or disables, based on the single boolean argument, the automatic mining of new blocks with each new transaction submitted to the network. You can use [`hardhat_getAutomine`](#hardhat-getautomine) to get the current value. See also [Mining Modes](../explanation/mining-modes.md). - -#### `evm_setBlockGasLimit` - -#### `evm_setIntervalMining` - -Enables (with a numeric argument greater than 0) or disables (with a numeric argument equal to 0), the automatic mining of blocks at a regular interval of milliseconds, each of which will include all pending transactions. See also [Mining Modes](../explanation/mining-modes.md). - -#### `evm_setNextBlockTimestamp` - -This method works like `evm_increaseTime`, but takes the exact timestamp that you want in the next block, and increases the time accordingly. - -#### `evm_snapshot` - -Same as [Ganache](https://github.com/trufflesuite/ganache/blob/ef1858d5d6f27e4baeb75cccd57fb3dc77a45ae8/src/chains/ethereum/ethereum/RPC-METHODS.md#evm_snapshot). - -Snapshot the state of the blockchain at the current block. Takes no parameters. Returns the id of the snapshot that was created. A snapshot can only be reverted once. After a successful `evm_revert`, the same snapshot id cannot be used again. Consider creating a new snapshot after each `evm_revert` if you need to revert to the same point multiple times. - -### Unsupported methods - -#### `eth_compileLLL` - -#### `eth_compileSerpent` - -#### `eth_compileSolidity` - -#### `eth_getCompilers` - -#### `eth_getProof` - -#### `eth_getUncleByBlockHashAndIndex` - -#### `eth_getUncleByBlockNumberAndIndex` - -#### `eth_getUncleCountByBlockHash` - -#### `eth_getUncleCountByBlockNumber` - -#### `eth_getWork` - -#### `eth_hashrate` - -#### `eth_protocolVersion` - -#### `eth_signTransaction` - -#### `eth_signTypedData` - -#### `eth_signTypedData_v3` - -#### `eth_submitHashrate` - -#### `eth_submitWork` - -## Limitations - -### Supported Solidity versions - -Hardhat Network can run any smart contract, but it only understands Solidity 0.5.1 and newer. - -If you are compiling with an older version of Solidity, or using another language, you can use Hardhat Network, but Solidity stack traces won't be generated. - -### Solidity optimizer support - -Hardhat Network can work with smart contracts compiled with optimizations, but this may lead to your stack traces' line numbers being a little off. - -We recommend compiling without optimizations when testing and debugging your contracts. diff --git a/docs/src/content/hardhat-runner/_dirinfo.yaml b/docs/src/content/hardhat-runner/_dirinfo.yaml deleted file mode 100644 index 9ec3f9e8a0..0000000000 --- a/docs/src/content/hardhat-runner/_dirinfo.yaml +++ /dev/null @@ -1 +0,0 @@ -section-type: hidden diff --git a/docs/src/content/hardhat-runner/docs/_dirinfo.yaml b/docs/src/content/hardhat-runner/docs/_dirinfo.yaml deleted file mode 100644 index 9ec3f9e8a0..0000000000 --- a/docs/src/content/hardhat-runner/docs/_dirinfo.yaml +++ /dev/null @@ -1 +0,0 @@ -section-type: hidden diff --git a/docs/src/content/hardhat-runner/docs/advanced/_dirinfo.yaml b/docs/src/content/hardhat-runner/docs/advanced/_dirinfo.yaml deleted file mode 100644 index 6365297f03..0000000000 --- a/docs/src/content/hardhat-runner/docs/advanced/_dirinfo.yaml +++ /dev/null @@ -1,14 +0,0 @@ -section-type: group -section-title: Advanced -order: - - /hardhat-runtime-environment - - /artifacts - - /multiple-solidity-versions - - /create-task - - /scripts - - /building-plugins - - /hardhat-and-foundry - - /flattening - - href: /vscode-tests - title: Running tests in VS Code - - /using-esm diff --git a/docs/src/content/hardhat-runner/docs/advanced/artifacts.md b/docs/src/content/hardhat-runner/docs/advanced/artifacts.md deleted file mode 100644 index 4a2c84b991..0000000000 --- a/docs/src/content/hardhat-runner/docs/advanced/artifacts.md +++ /dev/null @@ -1,64 +0,0 @@ -# Compilation artifacts - -Compiling with Hardhat generates two files per compiled contract (not each `.sol` file): an artifact and a debug file. - -An **artifact** has all the information that is necessary to deploy and interact with the contract. These are compatible with most tools, including Truffle's artifact format. Each artifact consists of a json with the following properties: - -- `contractName`: A string with the contract's name. - -- `abi`: A [JSON description of the contract's ABI](https://solidity.readthedocs.io/en/latest/abi-spec.html#abi-json). - -- `bytecode`: A `"0x"`-prefixed hex string of the unlinked deployment bytecode. If the contract is not deployable, this has the string `"0x"`. - -- `deployedBytecode`: A `"0x"`-prefixed hex string of the unlinked runtime/deployed bytecode. If the contract is not deployable, this has the string `"0x"`. - -- `linkReferences`: The bytecode's link references object [as returned by solc](https://solidity.readthedocs.io/en/latest/using-the-compiler.html). If the contract doesn't need to be linked, this value contains an empty object. - -- `deployedLinkReferences`: The deployed bytecode's link references object [as returned by solc](https://solidity.readthedocs.io/en/latest/using-the-compiler.html). If the contract doesn't need to be linked, this value contains an empty object. - -The **debug file** has all the information that is necessary to reproduce the compilation and to debug the contracts: this includes the original solc input and output, and the solc version used to compile it. - -## Build info files - -Hardhat optimizes compilation by compiling the smallest possible set of files at a time. Files that are compiled together have the same solc input and output. Since having this in each debug file would be meaningfully wasteful, this information is deduplicated in build info files that are placed in `artifacts/build-info`. Each contract debug file contains a relative path to its build info file, and each build info file contains the solc input, solc output and the solc version used. - -You shouldn't interact with these files directly. - -## Reading artifacts - -The [HRE] has an `artifacts` object with helper methods. For example, you can get a list with the paths to all artifacts by calling `hre.artifacts.getArtifactPaths()`. - -You can also read an artifact using the name of the contract by calling `hre.artifacts.readArtifact("Bar")`, which will return the content of the artifact for the `Bar` contract. This would only work if there was just one contract named `Bar` in the whole project; it would throw an error if there were two. To disambiguate this case, you would have to use the **Fully Qualified Name** of the contract: `hre.artifacts.readArtifact("contracts/Bar.sol:Bar")`. - -## Directory structure - -The `artifacts/` directory has a structure that follows the original directory structure of the contracts. For example, if your contracts look like this: - -``` -contracts -├── Foo.sol -├── Bar.sol -└── Qux.sol -``` - -then the structure of your artifact directory would look like this: - -``` -artifacts -└── contracts -    ├── Foo.sol -    │   ├── Foo.json -    │   ├── Foo.dbg.json -    │   ├── Foo2.json -    │   └── Foo2.dbg.json -    ├── Bar.sol -    │   ├── Bar.json -    │   └── Bar.dbg.json -    └── Qux.sol -    ├── Foo.json -    └── Foo.dbg.json -``` - -Each Solidity file in your source will get a directory in the artifacts structure. Each of these directories contains one artifact (`.json`) file and one debug (`.dbg.json`) file for each _contract_ in that file. `Foo.sol`, for example, contains two contracts inside. - -Two Solidity files can have contracts with the same name, and this structure allows for that. diff --git a/docs/src/content/hardhat-runner/docs/advanced/building-plugins.md b/docs/src/content/hardhat-runner/docs/advanced/building-plugins.md deleted file mode 100644 index c1aa605b85..0000000000 --- a/docs/src/content/hardhat-runner/docs/advanced/building-plugins.md +++ /dev/null @@ -1,110 +0,0 @@ -# Building plugins - -In this section, we will explore the creation of plugins for Hardhat, which are the key component for integrating other tools and extending the built-in functionality. - -## What exactly are plugins in Hardhat? - -Plugins are bits of reusable configuration. Anything that you can do in a plugin can also be done in your config file. You can test your ideas in a config file and then move them into a plugin when ready. - -When developing a plugin the main tools available to integrate new functionality are extending the [Hardhat Runtime Environment](/advanced/hardhat-runtime-environment.md), extending the Hardhat config, defining new tasks and overriding existing ones, which are all configuration actions achieved through code. - -Some examples of things you could achieve by creating a plugin are: running a linter when the `check` task runs, using different compiler versions for different files or generating an UML diagram for your contracts. - -## Extending the Hardhat Runtime Environment - -Let’s go through the process of creating a plugin that adds new functionality to the Hardhat Runtime Environment. By doing this, we make sure our new feature is available everywhere. This means your plugin users can access it from tasks, tests, scripts, and the Hardhat console. - -The Hardhat Runtime Environment (HRE) is configured through a queue of extension functions that you can add to using the `extendEnvironment()` function. It receives one parameter which is a callback which will be executed after the HRE is initialized. If `extendEnvironment` is called multiple times, its callbacks will be executed in order. - -For example, adding the following to `hardhat.config.js`: - -```js -extendEnvironment((hre) => { - hre.hi = "Hello, Hardhat!"; -}); -``` - -Will make `hi` available everywhere where the environment is accessible. - -```js -extendEnvironment((hre) => { - hre.hi = "Hello, Hardhat!"; -}); - -task("envtest", async (args, hre) => { - console.log(hre.hi); -}); - -module.exports = {}; -``` - -Will yield: - -``` -$ npx hardhat envtest -Hello, Hardhat! -``` - -This is literally all it takes to put together a plugin for Hardhat. Now `hi` is available to be used in the Hardhat console, your tasks, tests and other plugins. - -## Using the Hardhat TypeScript plugin boilerplate - -For a complete example of a plugin you can take a look at the [Hardhat TypeScript plugin boilerplate project](https://github.com/NomicFoundation/hardhat-ts-plugin-boilerplate/). - -Plugins don't need to be written in TypeScript, but we recommend doing it, as many of our users use it. Creating a plugin in JavaScript can lead to a subpar experience for them. - -### Extending the HRE - -To learn how to successfully extend the [HRE](./hardhat-runtime-environment.md) in TypeScript, and to give your users type information about your extension, take a look at [`src/index.ts`](https://github.com/NomicFoundation/hardhat-ts-plugin-boilerplate/blob/master/src/index.ts) in the boilerplate repo and read the [Extending the HRE](./hardhat-runtime-environment.md#extending-the-hre) documentation. - -Make sure to keep the type extension in your main file, as that convention is used across different plugins. - -### Extending the Hardhat config - -The boilerplate project also has an example on how to extend the Hardhat config. - -We strongly recommend doing this in TypeScript and properly extending the config types. - -An example on how to add fields to the Hardhat config can be found in [`src/index.ts`](https://github.com/NomicFoundation/hardhat-ts-plugin-boilerplate/blob/master/src/index.ts). - -## Plugin development best practices - -### Throwing errors from your plugins - -To show better stack traces to your users when an error is meant to interrupt a task's execution, please consider throwing `HardhatPluginError` errors, which can be found in `hardhat/plugins`. - -If your error originated in your user's code, like a test or script calling one of your functions, you shouldn't use `HardhatPluginError`. - -### Optimizing your plugin for better startup time - -Keeping startup time short is vital to give a good user experience. - -To do so, Hardhat and its plugins delay any slow import or initialization until the very last moment. To do so, you can use `lazyObject`, and `lazyFunction` from `hardhat/plugins`. - -An example on how to use them is present in [`src/index.ts`](https://github.com/NomicFoundation/hardhat-ts-plugin-boilerplate/blob/master/src/index.ts). - -## Notes on dependencies - -Knowing when to use a `dependency` or a `peerDependency` can be tricky. We recommend [these](https://yarnpkg.com/blog/2018/04/18/dependencies-done-right/) [articles](https://lexi-lambda.github.io/blog/2016/08/24/understanding-the-npm-dependency-model/) to learn about their distinctions. - -If you are still in doubt, these can be helpful: - -- **Rule of thumb #1:** Hardhat MUST be a peer dependency. - -- **Rule of thumb #2:** If your plugin P depends on another plugin P2, P2 should be a peer dependency of P, and P2's peer dependencies should be peer dependencies of P. - -- **Rule of thumb #3:** If you have a non-Hardhat dependency that your users may `require()`, it should be a peer dependency. - -- **Rule of thumb #4:** Every `peerDependency` should also be a `devDependency`. - -## Hooking into the user's workflow - -To integrate into your users' existing workflow, we recommend that plugin authors override built-in tasks whenever it makes sense. - -Examples of suggested overrides are: - -- Preprocessing smart contracts should override one of the `compile` subtasks. -- Linter integrations should override the `check` task. -- Plugins generating intermediate files should override the `clean` task. - -For a list of all the built-in tasks and subtasks please take a look at [`task-names.ts`](https://github.com/NomicFoundation/hardhat/blob/main/packages/hardhat-core/src/builtin-tasks/task-names.ts) diff --git a/docs/src/content/hardhat-runner/docs/advanced/create-task.md b/docs/src/content/hardhat-runner/docs/advanced/create-task.md deleted file mode 100644 index 33c7972df1..0000000000 --- a/docs/src/content/hardhat-runner/docs/advanced/create-task.md +++ /dev/null @@ -1,327 +0,0 @@ -# Creating a task - -This guide will explore the creation of tasks in Hardhat, which are the core component used for automation. - -A task is a JavaScript async function with some associated metadata. This metadata is used by Hardhat to automate some things for you. Arguments parsing, validation, and help messages are taken care of. - -Everything you can do in Hardhat is defined as a task. The default actions that come out of the box are built-in tasks and they are implemented using the same APIs that are available to you as a user. - -To see the currently available tasks in your project, run `npx hardhat`: - -``` -$ npx hardhat -Hardhat version 2.9.10 - -Usage: hardhat [GLOBAL OPTIONS] [TASK OPTIONS] - -GLOBAL OPTIONS: - - --config A Hardhat config file. - --emoji Use emoji in messages. - --help Shows this message, or a task's help if its name is provided - --max-memory The maximum amount of memory that Hardhat can use. - --network The network to connect to. - --show-stack-traces Show stack traces. - --tsconfig A TypeScript config file. - --verbose Enables Hardhat verbose logging - --version Shows hardhat's version. - - -AVAILABLE TASKS: - - check Check whatever you need - clean Clears the cache and deletes all artifacts - compile Compiles the entire project, building all artifacts - console Opens a hardhat console - flatten Flattens and prints contracts and their dependencies - help Prints this message - node Starts a JSON-RPC server on top of Hardhat Network - run Runs a user-defined script after compiling the project - test Runs mocha tests - -To get help for a specific task run: npx hardhat help [task] -``` - -You can create additional tasks, which will appear in this list. For example, you might create a task to reset the state of a development environment, or to interact with your contracts, or to package your project. - -Let’s go through the process of creating one to interact with a smart contract. - -Tasks in Hardhat are asynchronous JavaScript functions that get access to the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md), which exposes its configuration and parameters, as well as programmatic access to other tasks and any plugin objects that may have been injected. - -For our example, we will use the [`@nomicfoundation/hardhat-toolbox`](/hardhat-runner/plugins/nomicfoundation-hardhat-toolbox), which includes the [ethers.js](https://docs.ethers.io/v5/) library to interact with our contracts. - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm install --save-dev @nomicfoundation/hardhat-toolbox -``` - -::: - -:::tab{value="npm 6"} - -``` -npm install --save-dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers -``` - -::: - -:::tab{value="yarn"} - -``` -yarn add --dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers -``` - -::: - -:::: - -Task creation code can go in `hardhat.config.js`, or whatever your configuration file is called. It’s a good place to create simple tasks. If your task is more complex, it's also perfectly valid to split the code into several files and `require` them from the configuration file. - -(If you’re writing a Hardhat plugin that adds a task, they can also be created from a separate npm package. Learn more about creating tasks through plugins in our [Building plugins section](../advanced/building-plugins.md).) - -**The configuration file is always executed on startup before anything else happens.** It's good to keep this in mind. We will load the Hardhat toolbox and add our task creation code to it. - -For this tutorial, we're going to create a task to get an account’s balance from the terminal. You can do this with the Hardhat’s config API, which is available in the global scope of `hardhat.config.js`: - -```js -require("@nomicfoundation/hardhat-toolbox"); - -task("balance", "Prints an account's balance").setAction(async () => {}); - -/** @type import('hardhat/config').HardhatUserConfig */ -module.exports = { - solidity: "0.8.9", -}; -``` - -After saving the file, you should be able to see the task in Hardhat: - -``` -$ npx hardhat -Hardhat version 2.9.10 - -Usage: hardhat [GLOBAL OPTIONS] [TASK OPTIONS] - -GLOBAL OPTIONS: - - --config A Hardhat config file. - ... - - -AVAILABLE TASKS: - - balance Prints an account's balance - check Check whatever you need - clean Clears the cache and deletes all artifacts - ... - -To get help for a specific task run: npx hardhat help [task] -``` - -Now let’s implement the functionality we want. We need to get the account address from the user. We can do this by adding a parameter to our task: - -```js -task("balance", "Prints an account's balance") - .addParam("account", "The account's address") - .setAction(async () => {}); -``` - -When you add a parameter to a task, Hardhat will handle its help messages for you: - -``` -$ npx hardhat help balance -Hardhat version 2.9.10 - -Usage: hardhat [GLOBAL OPTIONS] balance --account - -OPTIONS: - - --account The account's address - -balance: Prints an account's balance - -For global options help run: hardhat help -``` - -Let’s now get the account’s balance. The [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) will be available in the global scope. By using Hardhat’s [ether.js plugin](https://github.com/NomicFoundation/hardhat/tree/main/packages/hardhat-ethers), which is included in the Hardhat Toolbox, we get access to an ethers.js instance: - -```js -task("balance", "Prints an account's balance") - .addParam("account", "The account's address") - .setAction(async (taskArgs) => { - const balance = await ethers.provider.getBalance(taskArgs.account); - - console.log(ethers.utils.formatEther(balance), "ETH"); - }); -``` - -Finally, we can run it: - -``` -$ npx hardhat balance --account 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 -10000.0 ETH -``` - -And there you have it, your first fully functional Hardhat task, allowing you to interact with the Ethereum blockchain in an easy way. - -## Advanced usage - -You can create your own tasks in your `hardhat.config.js` file. The Config API will be available in the global environment, with functions for defining tasks. You can also import the API with `require("hardhat/config")` if you prefer to keep things explicit, and take advantage of your editor's autocomplete. - -Creating a task is done by calling the `task` function. It will return a `TaskDefinition` object, which can be used to define the task's parameters. - -The simplest task you can define is - -```js -task( - "hello", - "Prints 'Hello, World!'", - async function (taskArguments, hre, runSuper) { - console.log("Hello, World!"); - } -); -``` - -`task`'s first argument is the task name. The second one is its description, which is used for printing help messages in the CLI. The third one is an async function that receives the following arguments: - -- `taskArguments` is an object with the parsed CLI arguments of the task. In this case, it's an empty object. - -- `hre` is the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md). - -- `runSuper` is only relevant if you are overriding an existing task, which we'll learn about next. Its purpose is to let you run the original task's action. - -Defining the action's arguments is optional. The Hardhat Runtime Environment and `runSuper` will also be available in the global scope. We can rewrite our "hello" task this way: - -```js -task("hello", "Prints 'Hello, World!'", async () => { - console.log("Hello, World!"); -}); -``` - -### Tasks' action requirements - -The only requirement for writing a task is that the `Promise` returned by its action must not resolve before every async process it started is finished. - -This is an example of a task whose action doesn't meet this requirement: - -```js -task("BAD", "This task is broken", async () => { - setTimeout(() => { - throw new Error( - "This task's action returned a promise that resolved before I was thrown" - ); - }, 1000); -}); -``` - -This other task uses a `Promise` to wait for the timeout to fire: - -```js -task("delayed-hello", "Prints 'Hello, World!' after a second", async () => { - return new Promise((resolve, reject) => { - setTimeout(() => { - console.log("Hello, World!"); - resolve(); - }, 1000); - }); -}); -``` - -Manually creating a `Promise` can look challenging, but you don't have to do that if you stick to `async`/`await` and `Promise`-based APIs. For example, you can use the npm package [`delay`](https://www.npmjs.com/package/delay) for a promisified version of `setTimeout`. - -### Defining parameters - -Hardhat tasks can receive named parameters with a value (eg `--parameter-name parameterValue`), flags with no value (eg `--flag-name`), positional parameters, or variadic parameters. Variadic parameters act like JavaScript's rest parameters. The Config API `task` function returns an object with methods to define all of them. Once defined, Hardhat takes control of parsing parameters, validating them, and printing help messages. - -Adding an optional parameter to the `hello` task can look like this: - -```js -task("hello", "Prints a greeting") - .addOptionalParam("greeting", "The greeting to print", "Hello, World!") - .setAction(async ({ greeting }) => console.log(greeting)); -``` - -And would be run with `npx hardhat hello --greeting Hola`. - -#### Positional parameters restrictions - -Positional and variadic parameters don't have to be named, and have the usual restrictions of a programming language: - -- No positional parameter can follow a variadic one -- Required/mandatory parameters can't follow an optional one. - -Failing to follow these restrictions will result in an exception being thrown when loading Hardhat. - -#### Type validations - -Hardhat takes care of validating and parsing the values provided for each parameter. You can declare the type of a parameter, and Hardhat will get the CLI strings and convert them into your desired type. If this conversion fails, it will print an error message explaining why. - -A number of types are available in the Config API through a `types` object. This object is injected into the global scope before processing your `hardhat.config.js`, but you can also import it explicitly with `const { types } = require("hardhat/config")` and take advantage of your editor's autocomplete. - -An example of a task defining a type for one of its parameters is - -```js -task("hello", "Prints 'Hello' multiple times") - .addOptionalParam( - "times", - "The number of times to print 'Hello'", - 1, - types.int - ) - .setAction(async ({ times }) => { - for (let i = 0; i < times; i++) { - console.log("Hello"); - } - }); -``` - -Calling it with `npx hardhat hello --times notanumber` will result in an error. - -### Overriding tasks - -Defining a task with the same name as an existing one will override the existing one. This is useful to change or extend the behavior of built-in and plugin-provided tasks. - -Task overriding works very similarly to overriding methods when extending a class. You can set your own action, which can call the overridden one. The only restriction when overriding tasks is that you can't add or remove parameters. - -Task override order is important since actions can only call the immediately overridden definition, using the `runSuper` function. - -Overriding built-in tasks is a great way to customize and extend Hardhat. To know which tasks to override, take a look at [src/builtin-tasks](https://github.com/NomicFoundation/hardhat/tree/main/packages/hardhat-core/src/builtin-tasks). - -#### The `runSuper` function - -`runSuper` is a function available to override a task's actions. It can be received as the third argument of the task or used directly from the global object. - -This function works like [JavaScript's `super` keyword](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super): it calls the task's previously defined action. - -If the task isn't overriding a previous task definition, then calling `runSuper` will result in an error. To check whether calling it would fail, you can use the `boolean` field `runSuper.isDefined`. - -The `runSuper` function receives a single optional argument: an object with the task arguments. If this argument isn't provided, the same task arguments received by the action calling it will be used. - -### Subtasks - -Creating tasks with lots of logic makes it hard to extend or customize them. Making multiple small and focused tasks that call each other is a better way to allow for extension. If you design your tasks in this way, users that want to change only a small aspect of them can override one of your subtasks. - -For example, the `compile` task is implemented as a pipeline of several tasks. It just calls subtasks like `compile:get-source-paths`, `compile:get-dependency-graph`, and `compile:build-artifacts`. We recommend prefixing intermediate tasks with their main task and a colon. - -To avoid help messages getting cluttered with lots of intermediate tasks, you can define those using the `subtask` config API function. The `subtask` function works almost exactly like `task`. The only difference is that tasks defined with it won't be included in help messages. - -To run a subtask, or any task whatsoever, you can use the `run` function. It takes two arguments: the name of the task to be run, and an object with its arguments. - -This is an example of a task running a subtask: - -```js -task("hello-world", "Prints a hello world message").setAction( - async (taskArgs, hre) => { - await hre.run("print", { message: "Hello, World!" }); - } -); - -subtask("print", "Prints a message") - .addParam("message", "The message to print") - .setAction(async (taskArgs) => { - console.log(taskArgs.message); - }); -``` diff --git a/docs/src/content/hardhat-runner/docs/advanced/flattening.md b/docs/src/content/hardhat-runner/docs/advanced/flattening.md deleted file mode 100644 index cbc7f8cd4a..0000000000 --- a/docs/src/content/hardhat-runner/docs/advanced/flattening.md +++ /dev/null @@ -1,64 +0,0 @@ -# Flattening your contracts - -Hardhat comes with a built-in `flatten` task that lets you combine the source code of multiple Solidity files. - -## Flattening all your files - -If you use the `flatten` task without passing any other arguments, all the Solidity files in your project will be combined: - -``` -$ npx hardhat flatten -// Sources flattened with hardhat v2.12.3 https://hardhat.org - -// File contracts/Bar.sol - -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -contract Bar {} - -// File contracts/Qux.sol - -... -``` - -The result will be printed to stdout. You can create a file with the flattened sources using the `>` redirection operator: - -``` -$ npx hardhat flatten > Flattened.sol - -$ cat Flattened.sol -// Sources flattened with hardhat v2.12.3 https://hardhat.org - -// File contracts/Bar.sol - -... -``` - -## Flattening specific files - -The `flatten` task can receive a path to the file you want to flatten: - -``` -npx hardhat flatten contracts/Foo.sol -``` - -In this case, the result will contain the source code of `Foo.sol` and all its transitive dependencies (the files that it imports, and the files that those files import, and so on). - -You can also use multiple files: - -``` -npx hardhat flatten contracts/Foo.sol contracts/Bar.sol -``` - -But if `Bar.sol` is a dependency of `Foo.sol`, then the result will be the same as in the previous example. - -As explained in the previous section, you can redirect the output to some file: - -``` -npx hardhat flatten contracts/Foo.sol > Flattened.sol -``` - -## Circular dependencies - -Projects with circular dependencies cannot be flattened at the moment. If this is something you need, please upvote or comment [this issue](https://github.com/NomicFoundation/hardhat/issues/1486). diff --git a/docs/src/content/hardhat-runner/docs/advanced/hardhat-and-foundry.md b/docs/src/content/hardhat-runner/docs/advanced/hardhat-and-foundry.md deleted file mode 100644 index 189e422f32..0000000000 --- a/docs/src/content/hardhat-runner/docs/advanced/hardhat-and-foundry.md +++ /dev/null @@ -1,128 +0,0 @@ -# Integrating with Foundry - -This guide explains how to combine Hardhat and [Foundry](https://book.getfoundry.sh/) in the same project using our [`@nomicfoundation/hardhat-foundry`](/hardhat-runner/plugins/nomicfoundation-hardhat-foundry) plugin. - -## Setting up a hybrid project - -How to set up a project that combines Hardhat and Foundry depends on whether you have an existing Hardhat project or an existing Foundry project. - -### Adding Foundry to a Hardhat project - -:::tip - -Foundry relies on Git to work properly. Make sure your project is already a Git repository, or type `git init` to initialize one. - -::: - -If you have an existing Hardhat project and you want to use Foundry in it, you should follow these steps. - -First, run `forge --version` to make sure that you have Foundry installed. If you don't, go [here](https://getfoundry.sh/) to get it. - -After that, install the [`@nomicfoundation/hardhat-foundry`](/hardhat-runner/plugins/nomicfoundation-hardhat-foundry) plugin: - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm install --save-dev @nomicfoundation/hardhat-foundry -``` - -::: - -:::tab{value="npm 6"} - -``` -npm install --save-dev @nomicfoundation/hardhat-foundry -``` - -::: - -:::tab{value=yarn} - -``` -yarn add --dev @nomicfoundation/hardhat-foundry -``` - -::: - -:::: - -and import it in your Hardhat config: - -::::tabsgroup{options=TypeScript,JavaScript} - -:::tab{value=TypeScript} - -```typescript -import "@nomicfoundation/hardhat-foundry"; -``` - -::: - -:::tab{value=JavaScript} - -```javascript -require("@nomicfoundation/hardhat-foundry"); -``` - -::: - -:::: - -To complete the setup, run `npx hardhat init-foundry`. This task will create a `foundry.toml` file with the right configuration and install [`forge-std`](https://github.com/foundry-rs/forge-std). - -### Adding Hardhat to a Foundry project - -If you have an existing Foundry project and you want to use Hardhat in it, follow these steps. - -First, if you don't have a `package.json` already in your project, create one with `npm init`. - -Then install Hardhat and the [`@nomicfoundation/hardhat-foundry`](/hardhat-runner/plugins/nomicfoundation-hardhat-foundry) plugin: - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm install --save-dev hardhat @nomicfoundation/hardhat-foundry -``` - -::: - -:::tab{value="npm 6"} - -``` -npm install --save-dev hardhat @nomicfoundation/hardhat-foundry -``` - -::: - -:::tab{value=yarn} - -``` -yarn add --dev hardhat @nomicfoundation/hardhat-foundry -``` - -::: - -:::: - -After that, initialize a Hardhat project with `npx hardhat`. Choose the "Create an empty hardhat.config.js" option, and then import the plugin in `hardhat.config.js`: - -```javascript -require("@nomicfoundation/hardhat-foundry"); -``` - -You should now be able to compile your project with Hardhat and to add Hardhat scripts and tests. - -## Working with a combined setup - -Once you've set up a project as explained in the previous section, you'll be able to use both Hardhat and Foundry in it. These are some of the things you can do: - -- Write some tests [in JavaScript/TypeScript](/hardhat-runner/docs/guides/test-contracts) and run them with `npx hardhat test` -- Write other tests [in Solidity](https://book.getfoundry.sh/forge/writing-tests) and run them with `forge test` -- Compile your contracts with either `npx hardhat compile` or `forge build` -- Write a [custom Hardhat task](/hardhat-runner/docs/advanced/create-task) and execute it - -Check [our docs](/hardhat-runner/docs) and [Foundry docs](https://book.getfoundry.sh/) to learn more. diff --git a/docs/src/content/hardhat-runner/docs/advanced/hardhat-runtime-environment.md b/docs/src/content/hardhat-runner/docs/advanced/hardhat-runtime-environment.md deleted file mode 100644 index 6f9d550920..0000000000 --- a/docs/src/content/hardhat-runner/docs/advanced/hardhat-runtime-environment.md +++ /dev/null @@ -1,70 +0,0 @@ -# Hardhat Runtime Environment (HRE) - -## Overview - -The Hardhat Runtime Environment, or HRE for short, is an object containing all the functionality that Hardhat exposes when running a task, test or script. In reality, Hardhat _is_ the HRE. - -When you require Hardhat (`const hardhat = require("hardhat")`) you're getting an instance of the HRE. - -During initialization, the Hardhat configuration file essentially constructs a list of things to be added to the HRE. This includes tasks, configs and plugins. Then when tasks, tests or scripts run, the HRE is always present and available to access anything that is contained in it. - -The HRE has a role of centralizing coordination across all Hardhat components. This architecture allows for plugins to inject functionality that becomes available everywhere the HRE is accessible. - -## Using the HRE - -By default, the HRE gives you programmatic access to the task runner and the config system, and exports an [EIP1193-compatible](https://eips.ethereum.org/EIPS/eip-1193) Ethereum provider. - -Plugins can extend the HRE. For example, [hardhat-ethers](https://github.com/NomicFoundation/hardhat/tree/main/packages/hardhat-ethers) adds an Ethers.js instance to it, making it available to tasks, tests and scripts. - -### As global variables - -Before running a task, test or script, Hardhat injects the HRE into the global scope, turning all of its fields into global variables. When the task execution is completed, these global variables are removed, restoring their original value, if they had one. - -### Explicitly - -Not everyone likes magic global variables, and Hardhat doesn't force you to use them. Everything can be done explicitly in tasks, tests and scripts. - -When writing tests or scripts, you can use `require("hardhat")` to import the HRE. You can read more about this in [Accessing the HRE from outside a task](#accessing-the-hre-from-outside-a-task). - -You can import the config API explicitly when defining your tasks, and receive the HRE explicitly as an argument to your actions. You can read more about this in [Creating your own tasks](./create-task.md). - -## Accessing the HRE from outside a task - -The HRE can be used from any JavaScript or TypeScript file. To do so, you only have to import it with `require("hardhat")`. You can do this to keep more control over your development workflow, create your own tools, or to use Hardhat with other dev tools from the node.js ecosystem. - -Running test directly with [Mocha](https://www.npmjs.com/package/mocha) instead of `npx hardhat test` can be done by explicitly importing the HRE in them like this: - -```js -const hre = require("hardhat"); -const assert = require("assert"); - -describe("Hardhat Runtime Environment", function () { - it("should have a config field", function () { - assert.notEqual(hre.config, undefined); - }); -}); -``` - -This way, tests written for Hardhat are just normal Mocha tests. This enables you to run them from your favorite editor without the need of any Hardhat-specific plugin. For example, you can [run them from Visual Studio Code using Mocha Test Explorer](../advanced/vscode-tests.md). - -## Extending the HRE - -The HRE only provides the core functionality that users and plugin developers need to start building on top of Hardhat. Using it to interface directly with Ethereum in your project can be somewhat harder than expected. - -Everything gets easier when you use higher-level libraries, like [Ethers.js](https://docs.ethers.io/) or [ethereum-waffle](https://www.npmjs.com/package/ethereum-waffle), but these libraries need some initialization to work, and that could get repetitive. - -Hardhat lets you hook into the HRE construction, and extend it with new functionality. This way, you only have to initialize everything once, and your new features or libraries will be available everywhere the HRE is used. - -You can do this by adding an HRE extender into a queue. This extender is just a synchronous function that receives the HRE and adds fields to it with your new functionality. These new fields will also get [injected into the global scope during runtime](#exporting-globally). - -For example, adding an instance of [Web3.js](https://web3js.readthedocs.io/en/latest/) to the HRE can be done by installing the `web3` package and adding the following to your `hardhat.config.js`: - -```js -extendEnvironment((hre) => { - const Web3 = require("web3"); - hre.Web3 = Web3; - - // hre.network.provider is an EIP1193-compatible provider. - hre.web3 = new Web3(hre.network.provider); -}); -``` diff --git a/docs/src/content/hardhat-runner/docs/advanced/multiple-solidity-versions.md b/docs/src/content/hardhat-runner/docs/advanced/multiple-solidity-versions.md deleted file mode 100644 index e313e03b87..0000000000 --- a/docs/src/content/hardhat-runner/docs/advanced/multiple-solidity-versions.md +++ /dev/null @@ -1,44 +0,0 @@ -# Multiple Solidity versions - -Hardhat supports projects that use different, incompatible versions of solc. For example, if you have a project where some files use Solidity 0.5 and others use 0.6, you can configure Hardhat to use compiler versions compatible with those files like this: - -```js -module.exports = { - solidity: { - compilers: [ - { - version: "0.5.5", - }, - { - version: "0.6.7", - settings: {}, - }, - ], - }, -}; -``` - -This setup means that a file with a `pragma solidity ^0.5.0` will be compiled with solc 0.5.5 and a file with a `pragma solidity ^0.6.0` will be compiled with solc 0.6.7. - -It might happen that a file can be compiled with more than one of your configured compilers, for example a file with `pragma solidity >=0.5.0`. In that case, the compatible compiler with the highest version will be used (0.6.7 in this example). If you don't want that to happen, you can specify for each file which compiler should be used by using overrides: - -```js{4-7} -module.exports = { - solidity: { - compilers: [...], - overrides: { - "contracts/Foo.sol": { - version: "0.5.5", - settings: { } - } - } - } -} -``` - -In this case, `contracts/Foo.sol` will be compiled with solc 0.5.5, no matter what's inside the `solidity.compilers` entry. - -Keep in mind that: - -- Overrides are full compiler configurations, so if you have any additional settings you're using you should set them for the override as well. -- You have to use forward slashes (`/`) even if you are on Windows. diff --git a/docs/src/content/hardhat-runner/docs/advanced/scripts.md b/docs/src/content/hardhat-runner/docs/advanced/scripts.md deleted file mode 100644 index e29e47e01b..0000000000 --- a/docs/src/content/hardhat-runner/docs/advanced/scripts.md +++ /dev/null @@ -1,78 +0,0 @@ -# Writing scripts with Hardhat - -In this guide we will go through the steps of creating a script with Hardhat. For a general overview of using Hardhat refer to the [Getting started guide](../getting-started/index.md). - -You can write your own custom scripts that can use all of Hardhat's functionality. A classic use case is writing a deployment script for your smart contracts. - -There are two ways of writing a script that accesses the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md). - -## Running scripts with the Hardhat CLI - -You can write scripts that access the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md)'s properties as global variables. - -These scripts must be run through Hardhat: `npx hardhat run script.js`. - -This makes it easy to port scripts that were developed for other tools and that inject variables into the global state. - -## Standalone scripts: using Hardhat as a library - -The second option leverages Hardhat's architecture to allow for more flexibility. Hardhat has been designed as a library, allowing you to get creative and build standalone CLI tools that access your development environment. This means that by simply requiring it: - -```js -const hre = require("hardhat"); -``` - -You can get access to all your tasks and plugins. To run these scripts you simply go through node: `node script.js`. - -To try this out, let's look at [a fresh Hardhat project](../guides/project-setup.md). Run `npx hardhat` and go through the steps to create a JavaScript project. When you're done, your project directory should look like this: - -``` -$ ls -l -total 400 -drwxr-xr-x 3 fzeoli staff 96 Jul 30 15:27 contracts --rw-r--r-- 1 fzeoli staff 195 Jul 30 15:27 hardhat.config.js -drwxr-xr-x 502 fzeoli staff 16064 Jul 30 15:31 node_modules --rw-r--r-- 1 fzeoli staff 194953 Jul 30 15:31 package-lock.json --rw-r--r-- 1 fzeoli staff 365 Jul 30 15:31 package.json -drwxr-xr-x 3 fzeoli staff 96 Jul 30 15:27 scripts -drwxr-xr-x 3 fzeoli staff 96 Jul 30 15:27 test -``` - -Inside `scripts/` you will find `deploy.js`. Read through its comments to have a better idea of what it does. - -<<< @/../packages/hardhat-core/sample-projects/javascript/scripts/deploy.js - -Now run the script: - -``` -$ node scripts/deploy.js -Lock with 1 ETH deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 -``` - -By accessing the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) at the top, you are allowed to run the script in a standalone fashion. - -Hardhat always runs the compile task when it's invoked via `npx hardhat run`, but in a standalone fashion you may want to call compile manually to make sure everything is compiled. This can be done by calling `hre.run("compile")`. Add the following line at the beginning of the `main` function and re-run the script with node: - -```js -await hre.run("compile"); -``` - -``` -$ node scripts/deploy.js -Nothing to compile -Lock with 1 ETH deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 -``` - -### Hardhat arguments - -You can still pass arguments to Hardhat when running a standalone script. This is done by setting environment variables. These are: - -- `HARDHAT_NETWORK`: Sets the network to connect to. - -- `HARDHAT_SHOW_STACK_TRACES`: Enables JavaScript stack traces of expected errors. - -- `HARDHAT_VERBOSE`: Enables Hardhat verbose logging. - -- `HARDHAT_MAX_MEMORY`: Sets the maximum amount of memory that Hardhat can use. - -For example, instead of doing `npx hardhat --network localhost run script.js`, you can do `HARDHAT_NETWORK=localhost node script.js`. diff --git a/docs/src/content/hardhat-runner/docs/advanced/using-esm.md b/docs/src/content/hardhat-runner/docs/advanced/using-esm.md deleted file mode 100644 index 291a4cf4f6..0000000000 --- a/docs/src/content/hardhat-runner/docs/advanced/using-esm.md +++ /dev/null @@ -1,132 +0,0 @@ -# Using ES modules - -Node.js projects can use one of two module systems: CommonJS and ES Modules (ESM). Hardhat was designed mainly with CommonJS in mind, but in the last years adoption of ESM has been growing. - -This guide explains where you can use ESM in your Hardhat project and how to do it. - -## Hardhat support for ES modules - -You can write your scripts and tests as both CommonJS and ES modules. However, your Hardhat config, and any file imported by it, **must** be CommonJS modules. - -If your package uses ESM by default (that is, you have [`"type": "module"`](https://nodejs.org/api/packages.html#type) in your `package.json`), then your Hardhat config file must be named `hardhat.config.cjs`. - -Hardhat doesn't support [ESM in TypeScript projects](#esm-and-typescript-projects). - -## Using ES Modules in Hardhat - -The following sections explain how to use ES modules in new or existing Hardhat projects. - -### Starting an ESM-first Hardhat project - -If you want to start a Hardhat project that uses ES modules by default, first you have to initialize a Node.js project: - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm init -y -``` - -::: - -:::tab{value="npm 6"} - -``` -npm init -y -``` - -::: - -:::tab{value="yarn"} - -``` -yarn init -y -``` - -::: - -:::: - -Open the `package.json` that was created and add a `"type": "module"` entry. This will make the project use ESM by default. - -After that, install Hardhat: - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm install --save-dev hardhat -``` - -::: - -:::tab{value="npm 6"} - -``` -npm install --save-dev hardhat -``` - -::: - -:::tab{value="yarn"} - -``` -yarn add --dev hardhat -``` - -::: - -:::: - -and run `npx hardhat` to create a Hardhat project: - -``` -888 888 888 888 888 -888 888 888 888 888 -888 888 888 888 888 -8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888 -888 888 "88b 888P" d88" 888 888 "88b "88b 888 -888 888 .d888888 888 888 888 888 888 .d888888 888 -888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. -888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 - -Welcome to Hardhat v2.13.0 - -? What do you want to do? … -▸ Create a JavaScript project - Create a TypeScript project (not available for ESM projects) - Create an empty hardhat.config.cjs - Quit -``` - -Select the `Create a JavaScript project` option. This will initialize a Hardhat project where the scripts and tests are ES modules, and where the configuration has a `.cjs` extension. - -### Migrating a project to ESM - -If you have an existing Hardhat project and you want to convert it into an ESM project, follow these steps: - -1. Edit your `package.json` and add a `"type": "module"` entry. -2. Rename your `hardhat.config.js` file to `hardhat.config.cjs`. -3. Migrate all your scripts and tests from CommonJS to ESM. Alternatively, you can rename them to have a `.cjs` extension instead of `.js`. - -### Adding ESM files to an existing Hardhat project - -It's also possible to write ESM scripts and tests without making your whole project ESM by default. To do this, just create your scripts and tests with an `.mjs` extension. - -## ESM and TypeScript projects - -At the moment, it's not possible to use ESM in TypeScript projects. - -Hardhat uses [`ts-node`](https://typestrong.org/ts-node/) to run TypeScript projects, which in turn relies on Node's loader hooks. This is all experimental and the current functionality is not enough for Hardhat's needs. - -If you need this feature, please let us know in [this issue](https://github.com/NomicFoundation/hardhat/issues/3385). - -## Learn more - -To learn more about ES modules in general, check these resources: - -- [Node.js docs](https://nodejs.org/api/packages.html) -- [ES modules: A cartoon deep-dive](https://hacks.mozilla.org/2018/03/es-modules-a-cartoon-deep-dive/) -- The [Modules chapter](https://exploringjs.com/impatient-js/ch_modules.html) of "JavaScript for impatient programmers" diff --git a/docs/src/content/hardhat-runner/docs/advanced/vscode-tests.md b/docs/src/content/hardhat-runner/docs/advanced/vscode-tests.md deleted file mode 100644 index dcb5d14407..0000000000 --- a/docs/src/content/hardhat-runner/docs/advanced/vscode-tests.md +++ /dev/null @@ -1,68 +0,0 @@ -# Running tests in Visual Studio Code - -:::tip - -[Hardhat for Visual Studio Code](/hardhat-vscode) is the official Hardhat extension that adds advanced support for Solidity to VSCode. If you use Visual Studio Code, give it a try! - -::: - -You can run your tests from [Visual Studio Code](https://code.visualstudio.com) by using one of its Mocha integration extensions. We recommend using [Mocha Test Explorer](https://marketplace.visualstudio.com/items?itemName=hbenl.vscode-mocha-test-adapter). - -To use Mocha Test Explorer, you need to install it and follow these instructions. - -Install Mocha locally by running this: - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm install --save-dev mocha -``` - -::: - -:::tab{value="npm 6"} - -``` -npm install --save-dev mocha -``` - -::: - -:::tab{value=yarn} - -``` -yarn add --dev mocha -``` - -::: - -:::: - -Then, you just need to create a file named `.mocharc.json` in your project's root directory with the following contents: - -```json -{ - "require": "hardhat/register", - "timeout": 40000 -} -``` - -:::warning - -Running test directly from Visual Studio Code won't compile your contracts automatically. Make sure to compile them manually. - -::: - -## Running TypeScript tests - -If you are writing your tests in TypeScript, you should use this `.mocharc.json` instead: - -```json -{ - "require": "hardhat/register", - "timeout": 40000, - "_": ["test/**/*.ts"] -} -``` diff --git a/docs/src/content/hardhat-runner/docs/config/_dirinfo.yaml b/docs/src/content/hardhat-runner/docs/config/_dirinfo.yaml deleted file mode 100644 index 2b92f5fa94..0000000000 --- a/docs/src/content/hardhat-runner/docs/config/_dirinfo.yaml +++ /dev/null @@ -1,2 +0,0 @@ -section-type: single -section-title: Configuration diff --git a/docs/src/content/hardhat-runner/docs/config/index.md b/docs/src/content/hardhat-runner/docs/config/index.md deleted file mode 100644 index 0b818c2c6b..0000000000 --- a/docs/src/content/hardhat-runner/docs/config/index.md +++ /dev/null @@ -1,210 +0,0 @@ -# Configuration - -When Hardhat is run, it searches for the closest `hardhat.config.js` file starting from the Current Working Directory. This file normally lives in the root of your project. An empty `hardhat.config.js` is enough for Hardhat to work. - -The entirety of your Hardhat setup (i.e. your config, plugins and custom tasks) is contained in this file. - -## Available config options - -To set up your config, you have to export an object from `hardhat.config.js`. - -This object can have entries like `defaultNetwork`, [`networks`](#networks-configuration), [`solidity`](#solidity-configuration), [`paths`](#path-configuration) and [`mocha`](#mocha-configuration). For example: - -::::tabsgroup{options=Infura,Alchemy} - -:::tab{value=Infura} - -```js -module.exports = { - defaultNetwork: "sepolia", - networks: { - hardhat: { - }, - sepolia: { - url: "https://sepolia.infura.io/v3/", - accounts: [privateKey1, privateKey2, ...] - } - }, - solidity: { - version: "0.5.15", - settings: { - optimizer: { - enabled: true, - runs: 200 - } - } - }, - paths: { - sources: "./contracts", - tests: "./test", - cache: "./cache", - artifacts: "./artifacts" - }, - mocha: { - timeout: 40000 - } -} -``` - -::: - -:::tab{value=Alchemy} - -```js -module.exports = { - defaultNetwork: "sepolia", - networks: { - hardhat: { - }, - sepolia: { - url: "https://eth-sepolia.g.alchemy.com/v2/", - accounts: [privateKey1, privateKey2, ...] - } - }, - solidity: { - version: "0.5.15", - settings: { - optimizer: { - enabled: true, - runs: 200 - } - } - }, - paths: { - sources: "./contracts", - tests: "./test", - cache: "./cache", - artifacts: "./artifacts" - }, - mocha: { - timeout: 40000 - } -} -``` - -::: - -:::: - -## Networks configuration - -The `networks` config field is an optional object where network names map to their configuration. - -There are two kinds of networks in Hardhat: [JSON-RPC](https://eth.wiki/json-rpc/API) based networks, and the built-in Hardhat Network. - -You can customize which network is used by default when running Hardhat by setting the config's `defaultNetwork` field. If you omit this config, its default value is `"hardhat"`. - -### Hardhat Network - -Hardhat comes built-in with a special network called `hardhat`. When using this network, an instance of the [Hardhat Network](/hardhat-network/docs) will be automatically created when you run a task, script or test your smart contracts. - -Hardhat Network has first-class support of Solidity. It always knows which smart contracts are being run and exactly what they do and why they fail. Learn more about it [here](/hardhat-network/docs). - -See [the Hardhat Network Configuration Reference](/hardhat-network/docs/reference/#config) for details on what can be configured. - -### JSON-RPC based networks - -These are networks that connect to an external node. Nodes can be running in your computer, like Ganache, or remotely, like Infura or Alchemy. - -This kind of network is configured with objects with the following fields: - -- `url`: The url of the node. This argument is required for custom networks. - -- `chainId`: An optional number, used to validate the network Hardhat connects to. If not present, this validation is omitted. - -- `from`: The address to use as default sender. If not present the first account of the node is used. - -- `gas`: Its value should be `"auto"` or a number. If a number is used, it will be the gas limit used by default in every transaction. If `"auto"` is used, the gas limit will be automatically estimated. Default value: `"auto"`. - -- `gasPrice`: Its value should be `"auto"` or a number. This parameter behaves like `gas`. Default value: `"auto"`. - -- `gasMultiplier`: A number used to multiply the results of gas estimation to give it some slack due to the uncertainty of the estimation process. Default value: `1`. - -- `accounts`: This field controls which accounts Hardhat uses. It can use the node's accounts (by setting it to `"remote"`), a list of local accounts (by setting it to an array of hex-encoded private keys), or use an [HD Wallet](#hd-wallet-config). Default value: `"remote"`. - -- `httpHeaders`: You can use this field to set extra HTTP Headers to be used when making JSON-RPC requests. It accepts a JavaScript object which maps header names to their values. Default value: `undefined`. - -- `timeout`: Timeout in ms for requests sent to the JSON-RPC server. If the request takes longer than this, it will be cancelled. Default value: `40000` for the localhost network, `20000` for the rest. - -### HD Wallet config - -To use an [HD Wallet](https://github.com/ethereumbook/ethereumbook/blob/develop/05wallets.asciidoc#hd_wallets) with Hardhat you should set your network's `accounts` field to an object with the following fields: - -- `mnemonic`: A required string with the mnemonic phrase of the wallet. - -- `path`: The HD parent of all the derived keys. Default value: `"m/44'/60'/0'/0"`. - -- `initialIndex`: The initial index to derive. Default value: `0`. - -- `count`: The number of accounts to derive. Default value: `20`. - -- `passphrase`: The passphrase for the wallet. Default value: empty string. - -For example: - -```js -module.exports = { - networks: { - sepolia: { - url: "...", - accounts: { - mnemonic: "test test test test test test test test test test test junk", - path: "m/44'/60'/0'/0", - initialIndex: 0, - count: 20, - passphrase: "", - }, - }, - }, -}; -``` - -### Default networks object - -```js -{ - localhost: { - url: "http://127.0.0.1:8545" - }, - hardhat: { - // See its defaults - } -} -``` - -## Solidity configuration - -The `solidity` config is an optional field that can be one of the following: - -- A solc version to use, e.g. `"0.7.3"`. - -- An object which describes the configuration for a single compiler. It contains the following keys: - - - `version`: The solc version to use. - - - `settings`: An object with the same schema as the `settings` entry in the [Input JSON](https://solidity.readthedocs.io/en/v0.7.4/using-the-compiler.html#input-description). - -- An object which describes multiple compilers and their respective configurations. It contains the following: - - - `compilers`: A list of compiler configuration objects like the one above. - - - `overrides`: An optional map of compiler configuration override objects. This maps file names to compiler configuration objects. Take a look at the [compilation guide](./guides/compile-contracts.md) to learn more. - -## Path configuration - -You can customize the different paths that Hardhat uses by providing an object to the `paths` field with the following keys: - -- `root`: The root of the Hardhat project. This path is resolved from `hardhat.config.js`'s directory. Default value: the directory containing the config file. -- `sources`: The directory where your contract are stored. This path is resolved from the project's root. Default value: `'./contracts'`. -- `tests`: The directory where your tests are located. This path is resolved from the project's root. Default value: `'./test'`. - -- `cache`: The directory used by Hardhat to cache its internal stuff. This path is resolved from the project's root. Default value: `'./cache'`. -- `artifacts`: The directory where the compilation artifacts are stored. This path is resolved from the project's root. Default value: `'./artifacts'`. - -## Mocha configuration - -You can configure how your tests are run using the `mocha` entry, which accepts the same options as [Mocha](https://mochajs.org/). - -## Quickly integrating other tools from Hardhat's config - -Hardhat's config file will always run before any task, so you can use it to integrate with other tools, like importing `@babel/register`. diff --git a/docs/src/content/hardhat-runner/docs/errors/_dirinfo.yaml b/docs/src/content/hardhat-runner/docs/errors/_dirinfo.yaml deleted file mode 100644 index 9ec3f9e8a0..0000000000 --- a/docs/src/content/hardhat-runner/docs/errors/_dirinfo.yaml +++ /dev/null @@ -1 +0,0 @@ -section-type: hidden diff --git a/docs/src/content/hardhat-runner/docs/getting-started/_dirinfo.yaml b/docs/src/content/hardhat-runner/docs/getting-started/_dirinfo.yaml deleted file mode 100644 index 136d530308..0000000000 --- a/docs/src/content/hardhat-runner/docs/getting-started/_dirinfo.yaml +++ /dev/null @@ -1,9 +0,0 @@ -section-type: group -section-title: Hardhat Runner -order: - - href: "#overview" - title: Overview - - href: "#installation" - title: Installation - - href: "#quick-start" - title: Quick start diff --git a/docs/src/content/hardhat-runner/docs/getting-started/index.md b/docs/src/content/hardhat-runner/docs/getting-started/index.md deleted file mode 100644 index b1bc062deb..0000000000 --- a/docs/src/content/hardhat-runner/docs/getting-started/index.md +++ /dev/null @@ -1,324 +0,0 @@ ---- -title: Getting started with Hardhat -description: Getting started with Hardhat, a development environment to compile, deploy, test, and debug your Ethereum software ---- - -## Overview - -Hardhat is a development environment for Ethereum software. It consists of different components for editing, compiling, debugging and deploying your smart contracts and dApps, all of which work together to create a complete development environment. - -Hardhat Runner is the main component you interact with when using Hardhat. It's a flexible and extensible task runner that helps you manage and automate the recurring tasks inherent to developing smart contracts and dApps. - -Hardhat Runner is designed around the concepts of **tasks** and **plugins**. Every time you're running Hardhat from the command-line, you're running a task. For example, `npx hardhat compile` runs the built-in `compile` task. Tasks can call other tasks, allowing complex workflows to be defined. Users and plugins can override existing tasks, making those workflows customizable and extendable. - -This guide will take you through the installation of our recommended setup, but as most of Hardhat's functionality comes from plugins, you are free to customize it or choose a completely different path. - -## Installation - -:::tip - -[Hardhat for Visual Studio Code](/hardhat-vscode) is the official Hardhat extension that adds advanced support for Solidity to VSCode. If you use Visual Studio Code, give it a try! - -::: - -Hardhat is used through a local installation in your project. This way your environment will be reproducible, and you will avoid future version conflicts. - -To install it, you need to create an npm project by going to an empty folder, running `npm init`, and following its instructions. You can use another package manager, like yarn, but we recommend you use npm 7 or later, as it makes installing Hardhat plugins simpler. - -Once your project is ready, you should run - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm install --save-dev hardhat -``` - -::: - -:::tab{value="npm 6"} - -``` -npm install --save-dev hardhat -``` - -::: - -:::tab{value=yarn} - -``` -yarn add --dev hardhat -``` - -::: - -:::: - -To use your local installation of Hardhat, you need to use `npx` to run it (i.e. `npx hardhat`). - -## Quick Start - -:::tip - -If you are using Windows, we **strongly recommend** using [WSL 2](https://docs.microsoft.com/en-us/windows/wsl/about) to follow this guide. - -::: - -We will explore the basics of creating a Hardhat project with a sample contract, tests of that contract, and a script to deploy it. - -To create the sample project, run `npx hardhat` in your project folder: - -``` -$ npx hardhat -888 888 888 888 888 -888 888 888 888 888 -888 888 888 888 888 -8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888 -888 888 "88b 888P" d88" 888 888 "88b "88b 888 -888 888 .d888888 888 888 888 888 888 .d888888 888 -888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. -888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 - -👷 Welcome to Hardhat v2.9.9 👷‍ - -? What do you want to do? … -❯ Create a JavaScript project - Create a TypeScript project - Create an empty hardhat.config.js - Quit -``` - -Let’s create the JavaScript or TypeScript project and go through these steps to compile, test and deploy the sample contract. We recommend using TypeScript, but if you are not familiar with it just pick JavaScript. - -### Running tasks - -To first get a quick sense of what's available and what's going on, run `npx hardhat` in your project folder: - -``` -$ npx hardhat -Hardhat version 2.9.9 - -Usage: hardhat [GLOBAL OPTIONS] [TASK OPTIONS] - -GLOBAL OPTIONS: - - --config A Hardhat config file. - --emoji Use emoji in messages. - --help Shows this message, or a task's help if its name is provided - --max-memory The maximum amount of memory that Hardhat can use. - --network The network to connect to. - --show-stack-traces Show stack traces. - --tsconfig A TypeScript config file. - --verbose Enables Hardhat verbose logging - --version Shows hardhat's version. - - -AVAILABLE TASKS: - - check Check whatever you need - clean Clears the cache and deletes all artifacts - compile Compiles the entire project, building all artifacts - console Opens a hardhat console - coverage Generates a code coverage report for tests - flatten Flattens and prints contracts and their dependencies - help Prints this message - node Starts a JSON-RPC server on top of Hardhat Network - run Runs a user-defined script after compiling the project - test Runs mocha tests - typechain Generate Typechain typings for compiled contracts - verify Verifies contract on Etherscan - -To get help for a specific task run: npx hardhat help [task] -``` - -The list of available tasks includes the built-in ones and also those that came with any installed plugins. `npx hardhat` is your starting point to find out what tasks are available to run. - -### Compiling your contracts - -Next, if you take a look in the `contracts/` folder, you'll see `Lock.sol`: - -<<< @/../packages/hardhat-core/sample-projects/javascript/contracts/Lock.sol - -To compile it, simply run: - -``` -npx hardhat compile -``` - -If you created a TypeScript project, this task will also generate TypeScript bindings using [TypeChain](https://www.npmjs.com/package/typechain). - -### Testing your contracts - -Your project comes with tests that use [Mocha](https://mochajs.org), [Chai](https://www.chaijs.com), and [Ethers.js](https://docs.ethers.io/v5). - -If you take a look in the `test/` folder, you'll see a test file: - -::::tabsgroup{options="TypeScript,JavaScript"} - -:::tab{value="TypeScript"} - -<<< @/../packages/hardhat-core/sample-projects/typescript/test/Lock.ts - -::: - -:::tab{value="JavaScript"} - -<<< @/../packages/hardhat-core/sample-projects/javascript/test/Lock.js - -::: - -:::: - -You can run your tests with `npx hardhat test`: - -::::tabsgroup{options="TypeScript,JavaScript"} - -:::tab{value="TypeScript"} - -``` -$ npx hardhat test -Generating typings for: 2 artifacts in dir: typechain-types for target: ethers-v5 -Successfully generated 6 typings! -Compiled 2 Solidity files successfully - - - Lock - Deployment - ✔ Should set the right unlockTime (610ms) - ✔ Should set the right owner - ✔ Should receive and store the funds to lock - ✔ Should fail if the unlockTime is not in the future - Withdrawals - Validations - ✔ Should revert with the right error if called too soon - ✔ Should revert with the right error if called from another account - ✔ Shouldn't fail if the unlockTime has arrived and the owner calls it - Events - ✔ Should emit an event on withdrawals - Transfers - ✔ Should transfer the funds to the owner - - - 9 passing (790ms) -``` - -::: - -:::tab{value="JavaScript"} - -``` -$ npx hardhat test -Compiled 2 Solidity files successfully - - - Lock - Deployment - ✔ Should set the right unlockTime (610ms) - ✔ Should set the right owner - ✔ Should receive and store the funds to lock - ✔ Should fail if the unlockTime is not in the future - Withdrawals - Validations - ✔ Should revert with the right error if called too soon - ✔ Should revert with the right error if called from another account - ✔ Shouldn't fail if the unlockTime has arrived and the owner calls it - Events - ✔ Should emit an event on withdrawals - Transfers - ✔ Should transfer the funds to the owner - - - 9 passing (790ms) -``` - -::: - -:::: - -### Deploying your contracts - -Next, to deploy the contract we will use a Hardhat script. - -Inside the `scripts/` folder you will find a file with the following code: - -::::tabsgroup{options="TypeScript,JavaScript"} - -:::tab{value="TypeScript"} - -<<< @/../packages/hardhat-core/sample-projects/typescript/scripts/deploy.ts - -::: - -:::tab{value="JavaScript"} - -<<< @/../packages/hardhat-core/sample-projects/javascript/scripts/deploy.js - -::: - -:::: - -You can run it using `npx hardhat run`: - -::::tabsgroup{options="TypeScript,JavaScript"} - -:::tab{value="TypeScript"} - -``` -$ npx hardhat run scripts/deploy.ts -Lock with 1 ETH deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 -``` - -::: - -:::tab{value="JavaScript"} - -``` -$ npx hardhat run scripts/deploy.js -Lock with 1 ETH deployed to: 0x5FbDB2315678afecb367f032d93F642f64180aa3 -``` - -::: - -:::: - -### Connecting a wallet or Dapp to Hardhat Network - -By default, Hardhat will spin up a new in-memory instance of Hardhat Network on startup. It's also possible to run Hardhat Network in a standalone fashion so that external clients can connect to it. This could be a wallet, your Dapp front-end, or a script. - -To run Hardhat Network in this way, run `npx hardhat node`: - -``` -$ npx hardhat node -Started HTTP and WebSocket JSON-RPC server at http://127.0.0.1:8545/ -``` - -This will expose a JSON-RPC interface to Hardhat Network. To use it connect your wallet or application to `http://127.0.0.1:8545`. - -If you want to connect Hardhat to this node, for example to run a deployment script against it, you simply need to run it using `--network localhost`. - -To try this, start a node with `npx hardhat node` and re-run the deployment script using the `network` option: - -::::tabsgroup{options="TypeScript,JavaScript"} - -:::tab{value="TypeScript"} - -``` -npx hardhat run scripts/deploy.ts --network localhost -``` - -::: - -:::tab{value="JavaScript"} - -``` -npx hardhat run scripts/deploy.js --network localhost -``` - -::: - -:::: - -Congrats! You have created a project and compiled, tested and deployed a smart contract. - -Show us some love by starring [our repository on GitHub!](https://github.com/NomicFoundation/hardhat)️ diff --git a/docs/src/content/hardhat-runner/docs/guides/_dirinfo.yaml b/docs/src/content/hardhat-runner/docs/guides/_dirinfo.yaml deleted file mode 100644 index 9d3b2adfa2..0000000000 --- a/docs/src/content/hardhat-runner/docs/guides/_dirinfo.yaml +++ /dev/null @@ -1,15 +0,0 @@ -section-type: group -section-title: Guides -order: - - /project-setup - - /compile-contracts - - /test-contracts - - /deploying - - /verifying - - /tasks-and-scripts - - /hardhat-console - - /typescript - - /command-line-completion - - title: Migrating away from hardhat-waffle - href: /migrating-from-hardhat-waffle - - /getting-help diff --git a/docs/src/content/hardhat-runner/docs/guides/command-line-completion.md b/docs/src/content/hardhat-runner/docs/guides/command-line-completion.md deleted file mode 100644 index 15417e731e..0000000000 --- a/docs/src/content/hardhat-runner/docs/guides/command-line-completion.md +++ /dev/null @@ -1,50 +0,0 @@ -# Command-line completion - -Hardhat has a companion npm package that acts as a shorthand for `npx hardhat`, and at the same time, it enables command-line completions in your terminal. - -This package, `hardhat-shorthand`, installs a globally accessible binary called `hh` that runs your locally installed `hardhat`. - -## Installation - -To use the Hardhat shorthand you need to install it **globally**: - -``` -npm install --global hardhat-shorthand -``` - -After doing this running `hh` will be equivalent to running `npx hardhat`. For example, instead of running `npx hardhat compile` you can run `hh compile`. - -### Installing the command-line completions - -To enable autocomplete support you'll also need to install the shell completion script using `hardhat-completion`, which comes with `hardhat-shorthand`. Run `hardhat-completion install` and follow the instructions to install the completion script: - -``` -$ hardhat-completion install -✔ Which Shell do you use ? · zsh -✔ We will install completion to ~/.zshrc, is it ok ? (y/N) · true -=> Added tabtab source line in "~/.zshrc" file -=> Added tabtab source line in "~/.config/tabtab/zsh/__tabtab.zsh" file -=> Wrote completion script to /home/fvictorio/.config/tabtab/zsh/hh.zsh file - - => Tabtab source line added to ~/.zshrc for hh package. - - Make sure to reload your SHELL. -``` - -To try it out, open a **new** terminal, go to the directory of your Hardhat project, and try typing `hh` followed by tab: - -![](/hh.gif) - -## Context - -Out of best practice, Hardhat projects use a local installation of the npm package `hardhat` to make sure everyone working on the project is using the same version. This is why you need to use `npx` or npm scripts to run Hardhat. - -This approach has the downside of there being no way to provide autocomplete suggestions directly for the `hardhat` command, as well as making the CLI commands longer. These are the two issues that `hh` solves. - -## Troubleshooting - -### "Autocompletion is not working" - -First, make sure you installed the autocompletion script with `hardhat-completion install`, then either reload your shell or open a new terminal to try again. - -If you still have problems, make sure that your Hardhat config doesn't have any issues. You can do this by just running `hh`. If the command prints the help message, then your config is fine. If not, you'll see what the problem is. diff --git a/docs/src/content/hardhat-runner/docs/guides/compile-contracts.md b/docs/src/content/hardhat-runner/docs/guides/compile-contracts.md deleted file mode 100644 index f7cb9a426f..0000000000 --- a/docs/src/content/hardhat-runner/docs/guides/compile-contracts.md +++ /dev/null @@ -1,72 +0,0 @@ -# Compiling your contracts - -To compile your contracts in your Hardhat project, use the built-in `compile` task: - -``` -$ npx hardhat compile -Compiling... -Compiled 1 contract successfully -``` - -The compiled artifacts will be saved in the `artifacts/` directory by default, or whatever your configured artifacts path is. Look at the [paths configuration section](../config/index.md#path-configuration) to learn how to change it. This directory will be created if it doesn't exist. - -After the initial compilation, Hardhat will try to do the least amount of work possible the next time you compile. For example, if you didn't change any files since the last compilation, nothing will be compiled: - -``` -$ npx hardhat compile -Nothing to compile -``` - -If you only modified one file, only that file and others affected by it will be recompiled. - -To force a compilation you can use the `--force` argument, or run `npx hardhat clean` to clear the cache and delete the artifacts. - -## Configuring the compiler - -If you need to customize the Solidity compiler options, then you can do so through the `solidity` field in your `hardhat.config.js`. The simplest way to use this field is via the shorthand for setting the compiler version, which we recommend always doing: - -```js -module.exports = { - solidity: "0.8.9", -}; -``` - -We recommend always setting a compiler version in order to avoid unexpected behavior or compiling errors as new releases of Solidity are published. - -:::warning - -Hardhat will automatically download the versions of `solc` that you set up. If you are behind an HTTP proxy, you may need to set the `HTTP_PROXY` or `HTTPS_PROXY` environment variable to the URL of your proxy. - -::: - -The expanded usage allows for more control of the compiler: - -```js -module.exports = { - solidity: { - version: "0.8.9", - settings: { - optimizer: { - enabled: true, - runs: 1000, - }, - }, - }, -}; -``` - -`settings` has the same schema as the `settings` entry in the [Input JSON](https://solidity.readthedocs.io/en/v0.7.2/using-the-compiler.html#input-description) that can be passed to the compiler. Some commonly used settings are: - -- `optimizer`: an object with `enabled` and `runs` keys. Default value: `{ enabled: false, runs: 200 }`. - -- `evmVersion`: a string controlling the target evm version. For example: `istanbul`, `berlin` or `london`. Default value: managed by `solc`. - -If any of your contracts have a version pragma that is not satisfied by the compiler version you configured, then Hardhat will throw an error. - -:::tip - -Read [this guide](../advanced/multiple-solidity-versions.md) if you need to use multiple versions of Solidity. - -::: - -[hre]: ../advanced/hardhat-runtime-environment.md diff --git a/docs/src/content/hardhat-runner/docs/guides/deploying.md b/docs/src/content/hardhat-runner/docs/guides/deploying.md deleted file mode 100644 index c16c9ba40f..0000000000 --- a/docs/src/content/hardhat-runner/docs/guides/deploying.md +++ /dev/null @@ -1,57 +0,0 @@ -# Deploying your contracts - -When it comes to deploying, there are no official plugins that implement a deployment system for Hardhat yet. We are working on it. - -In the meantime, we recommend deploying your smart contracts using scripts, or using [the hardhat-deploy community plugin](https://github.com/wighawag/hardhat-deploy/tree/master). You can deploy the `Lock` contract from the sample project with a deployment script like this: - -::::tabsgroup{options="TypeScript,JavaScript"} - -:::tab{value="TypeScript"} - -<<< @/../packages/hardhat-core/sample-projects/typescript/scripts/deploy.ts - -::: - -:::tab{value="JavaScript"} - -<<< @/../packages/hardhat-core/sample-projects/javascript/scripts/deploy.js - -::: - -:::: - -You can deploy in the `localhost` network following these steps: - -1. Start a [local node](../getting-started/index.md#connecting-a-wallet-or-dapp-to-hardhat-network) - - ``` - npx hardhat node - ``` - -2. Open a new terminal and deploy the smart contract in the `localhost` network - - ::::tabsgroup{options="TypeScript,JavaScript"} - - :::tab{value="TypeScript"} - - ``` - npx hardhat run --network localhost scripts/deploy.ts - ``` - - ::: - - :::tab{value="JavaScript"} - - ``` - npx hardhat run --network localhost scripts/deploy.js - ``` - - ::: - - :::: - -As general rule, you can target any network from your Hardhat config using: - -``` -npx hardhat run --network scripts/deploy.js -``` diff --git a/docs/src/content/hardhat-runner/docs/guides/getting-help.md b/docs/src/content/hardhat-runner/docs/guides/getting-help.md deleted file mode 100644 index 01a63fd1f9..0000000000 --- a/docs/src/content/hardhat-runner/docs/guides/getting-help.md +++ /dev/null @@ -1,30 +0,0 @@ -# Getting help - -Hardhat has a strong community of users willing to help you in times of trouble. Please read this entire guide to learn where and how to ask for help more effectively. - -The first place to look for answers is the [GitHub Discussions section in the Hardhat repository.](https://github.com/NomicFoundation/hardhat) We recommend you search there first, as the answer may already exist. - -If you can't find what you are looking for on GitHub Discussions, you can [create a new Discussion](https://github.com/NomicFoundation/hardhat/discussions/new). - -If you didn't have any luck on GitHub, or if you prefer a real-time chat, you can join our [Discord Server](https://hardhat.org/discord). Please read its rules and ask for help in the right channel. - -## Asking an effective question - -To increase the chances of getting an answer quickly on GitHub Discussions and Discord, you need to make sure you write a good question first. To do so, you need to include: - -1. A clear description of what you are trying to do. -2. The results you are getting, and how they differ from what you expect. -3. Which version of Hardhat you are running, and which plugins and their versions you are using. -4. Very specific and concise instructions on how to reproduce your problem. Ideally, provide a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). Another good option is to provide a link to a public repository that provides an easy environment to reproduce the problem. - -## Reporting a bug - -If you think you've found a bug in Hardhat, please [report it](https://github.com/NomicFoundation/hardhat/issues). - -However, _before_ reporting a bug, please follow these steps to ensure that a new bug report is actually warranted: - -1. Make sure you are using the latest version of Hardhat and its plugins. Your problem may already be fixed. -2. Try to determine whether the issue is coming from a plugin by running your project with some of them disabled. We only accept bug reports for plugins published by us, all of which start with either `@nomiclabs/` or `@nomicfoundation/`. If you find an issue with a plugin published by someone else, you may be able to raise it with that publisher. -3. Use the search on GitHub to try to find other reports of the same problem. If you find one, please comment on the existing issue instead of creating a new one. - -Whenever reporting a bug, and ideally whenever commenting on an existing Issue, please include all the information described in [Asking an effective question](#asking-an-effective-question). By providing as much information as possible, you greatly increase the chances of your problem getting fixed quickly. diff --git a/docs/src/content/hardhat-runner/docs/guides/hardhat-console.md b/docs/src/content/hardhat-runner/docs/guides/hardhat-console.md deleted file mode 100644 index 7bf0def7a4..0000000000 --- a/docs/src/content/hardhat-runner/docs/guides/hardhat-console.md +++ /dev/null @@ -1,76 +0,0 @@ -# Using the Hardhat console - -Hardhat comes built-in with an interactive JavaScript console. You can use it by running `npx hardhat console`: - -``` -$ npx hardhat console -Welcome to Node.js v12.10.0. -Type ".help" for more information. -> -``` - -The `compile` task will be called before opening the console prompt, but you can skip this with the `--no-compile` parameter. - -The execution environment for the console is the same as for tasks, scripts and tests. This means the configuration has been processed, and the [Hardhat Runtime Environment] has been initialized and injected into the global scope. - -For example, you'll have access in the global scope to the `config` object: - -``` -> config -{ - solidity: { compilers: [ [Object] ], overrides: {} }, - defaultNetwork: 'hardhat', - ... -} -> -``` - -And if you followed the [Getting started guide](../getting-started) or installed `@nomiclabs/hardhat-ethers`, the `ethers` object: - -``` -> ethers -{ - Signer: [Function: Signer] { isSigner: [Function] }, - ... - provider: EthersProviderWrapper { - ... - }, - ... - getSigners: [Function: getSigners], - ... - getContractAt: [Function: bound getContractAt] AsyncFunction -} -> -``` - -Anything that has been injected into the [Hardhat Runtime Environment] will be magically available in the global scope. - -Alternatively, if you're the more explicit kind of developer, you can instead require the HRE explicitly: - -``` -> const hre = require("hardhat") -> hre.ethers -{ - Signer: [Function: Signer] { isSigner: [Function] }, - ... - provider: EthersProviderWrapper { - ... - }, - ... - getSigners: [Function: getSigners], - ... - getContractAt: [Function: bound getContractAt] AsyncFunction -} -``` - -### History - -You will also notice that the console has the handy history feature you expect out of most interactive terminals, including across different sessions. Try it by pressing the up arrow key. The Hardhat console is just an instance of a Node.js console, so anything you use in Node.js will also work. - -### Asynchronous operations and top-level await - -Interacting with the Ethereum network, and therefore with your smart contracts, are asynchronous operations. Therefore, most APIs and libraries use JavaScript's `Promise` for returning values. - -To make things easier, Hardhat's console supports top-level `await` statements (e.g. `console.log(await ethers.getSigners()`). - -[hardhat runtime environment]: ../advanced/hardhat-runtime-environment.md diff --git a/docs/src/content/hardhat-runner/docs/guides/migrating-from-hardhat-waffle.md b/docs/src/content/hardhat-runner/docs/guides/migrating-from-hardhat-waffle.md deleted file mode 100644 index 5d2a12c130..0000000000 --- a/docs/src/content/hardhat-runner/docs/guides/migrating-from-hardhat-waffle.md +++ /dev/null @@ -1,111 +0,0 @@ -# Migrating away from hardhat-waffle - -In the past, our recommended setup included [Waffle], by using the [`hardhat-waffle`] plugin. - -However, we now recommend using [Hardhat Toolbox], a plugin that bundles a curated set of useful packages. This set includes [Hardhat Chai Matchers] and [Hardhat Network Helpers], which work as an improved replacement for `hardhat-waffle`. - -Migrating to the Toolbox only takes a few minutes. If you do so, you'll get more functionality, like support for Solidity custom errors and native `bigint` support, and a more reliable testing experience. It will also make it easier for you to keep up to date with our recommended setup. - -## Migrating to Hardhat Toolbox - -Follow these steps to migrate your project to Hardhat Toolbox. - -1. First you'll need to remove some packages from your project. - - ::::tabsgroup{options="npm 7+,npm 6,yarn"} - - :::tab{value="npm 7+"} - - ``` - npm uninstall @nomiclabs/hardhat-waffle ethereum-waffle @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers - ``` - - ::: - - :::tab{value="npm 6"} - - ``` - npm uninstall @nomiclabs/hardhat-waffle ethereum-waffle @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers - ``` - - ::: - - :::tab{value=yarn} - - ``` - yarn remove @nomiclabs/hardhat-waffle ethereum-waffle - ``` - - ::: - - :::: - -2. Then you need to install the Toolbox. If you are using yarn or an old version of npm, you'll also have to install some other packages (the peer dependencies of the Toolbox). - - ::::tabsgroup{options="npm 7+,npm 6,yarn"} - - :::tab{value="npm 7+"} - - ``` - npm install --save-dev @nomicfoundation/hardhat-toolbox - ``` - - ::: - - :::tab{value="npm 6"} - - ``` - npm install --save-dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers - ``` - - ::: - - :::tab{value="yarn"} - - ``` - yarn add --dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers - ``` - - ::: - - :::: - -3. Finally, remove `hardhat-waffle` from your imported plugins and import the Toolbox instead: - - ::::tabsgroup{options=TypeScript,JavaScript} - - :::tab{value=TypeScript} - - ```diff - - import "@nomiclabs/hardhat-waffle"; - + import "@nomicfoundation/hardhat-toolbox"; - ``` - - ::: - - :::tab{value=JavaScript} - - ```diff - - require("@nomiclabs/hardhat-waffle"); - + require("@nomicfoundation/hardhat-toolbox"); - ``` - - ::: - - :::: - - Adding the Toolbox will make many other imports redundant, so you can remove any of these if you want: - - - `@nomiclabs/hardhat-ethers` - - `@nomiclabs/hardhat-etherscan` - - `hardhat-gas-reporter` - - `solidity-coverage` - - `@typechain/hardhat` - -Check the [Hardhat Chai Matchers] and [Hardhat Network Helpers] docs to learn more about the functionality included in the Toolbox. - -[waffle]: https://getwaffle.io -[`hardhat-waffle`]: ../../plugins/nomiclabs-hardhat-waffle -[hardhat chai matchers]: /hardhat-chai-matchers -[hardhat network helpers]: /hardhat-network-helpers -[hardhat toolbox]: /hardhat-runner/plugins/nomicfoundation-hardhat-toolbox diff --git a/docs/src/content/hardhat-runner/docs/guides/project-setup.md b/docs/src/content/hardhat-runner/docs/guides/project-setup.md deleted file mode 100644 index 0751641054..0000000000 --- a/docs/src/content/hardhat-runner/docs/guides/project-setup.md +++ /dev/null @@ -1,181 +0,0 @@ -# Setting up a project - -:::tip - -If you are using Windows, we **strongly recommend** using [WSL 2](https://docs.microsoft.com/en-us/windows/wsl/about) to follow this guide. - -::: - -Hardhat projects are Node.js projects with the `hardhat` package installed and a `hardhat.config.js` file. - -To initialize a Node.js project you can use [npm](https://docs.npmjs.com/cli/v8) or [yarn](https://classic.yarnpkg.com/). We recommend using npm 7 or later: - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm init -y -``` - -::: - -:::tab{value="npm 6"} - -``` -npm init -y -``` - -::: - -:::tab{value="yarn"} - -``` -yarn init -y -``` - -::: - -:::: - -Then you need to install Hardhat: - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm install --save-dev hardhat -``` - -::: - -:::tab{value="npm 6"} - -``` -npm install --save-dev hardhat -``` - -::: - -:::tab{value="yarn"} - -``` -yarn add --dev hardhat -``` - -::: - -:::: - -If you run `npx hardhat` now, you will be shown some options to facilitate project creation: - -``` -$ npx hardhat -888 888 888 888 888 -888 888 888 888 888 -888 888 888 888 888 -8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888 -888 888 "88b 888P" d88" 888 888 "88b "88b 888 -888 888 .d888888 888 888 888 888 888 .d888888 888 -888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. -888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 - -Welcome to Hardhat v2.10.0 - -? What do you want to do? … -▸ Create a JavaScript project - Create a TypeScript project - Create an empty hardhat.config.js - Quit -``` - -If you select _Create an empty hardhat.config.js_, Hardhat will create a `hardhat.config.js` like the following: - -```js -/** @type import('hardhat/config').HardhatUserConfig */ -module.exports = { - solidity: "0.8.9", -}; -``` - -And this is enough to run Hardhat using a default project structure. - -### Sample Hardhat project - -If you select _Create a JavaScript project_, a simple project creation wizard will ask you some questions. After that, the wizard will create some directories and files and install the necessary dependencies. The most important of these dependencies is the [Hardhat Toolbox](/hardhat-runner/plugins/nomicfoundation-hardhat-toolbox), a plugin that bundles all the things you need to start working with Hardhat. - -The initialized project has the following structure: - -``` -contracts/ -scripts/ -test/ -hardhat.config.js -``` - -These are the default paths for a Hardhat project. - -- `contracts/` is where the source files for your contracts should be. -- `test/` is where your tests should go. -- `scripts/` is where simple automation scripts go. - -If you need to change these paths, take a look at the [paths configuration section](../config/index.md#path-configuration). - -### Testing - -When it comes to testing your contracts, the sample project comes with some useful functionality: - -- The built-in [Hardhat Network](/hardhat-network/docs) as the development network to test on, along with the [Hardhat Network Helpers](/hardhat-network-helpers) library to manipulate this network. -- [Mocha](https://mochajs.org/) as the test runner, [Chai](https://chaijs.com/) as the assertion library, and the [Hardhat Chai Matchers](/hardhat-chai-matchers) to extend Chai with contracts-related functionality. -- The [`ethers.js`](https://docs.ethers.io/v5/) library to interact with the network and with contracts. - -As well as other useful plugins. You can learn more about this in the [Testing contracts guide](./test-contracts.md). - -### External networks - -If you need to use an external network, like an Ethereum testnet, mainnet or some other specific node software, you can set it up using the `networks` configuration entries in the exported object in `hardhat.config.js`, which is how Hardhat projects manage settings. - -You can make use of the `--network` CLI parameter to quickly change the network. - -Take a look at the [networks configuration section](../config/index.md#networks-configuration) to learn more about setting up different networks. - -### Plugins and dependencies - -Most of Hardhat's functionality comes from plugins, so check out the [plugins section](/hardhat-runner/plugins) for the official list and see if there are any ones of interest to you. - -To use a plugin, the first step is always to install it using npm or yarn, followed by requiring it in your config file: - -::::tabsgroup{options="TypeScript,JavaScript"} - -:::tab{value="TypeScript"} - -```ts -import "@nomicfoundation/hardhat-toolbox"; - -export default { - solidity: "0.8.9", -}; -``` - -::: - -:::tab{value="JavaScript"} - -```js -require("@nomicfoundation/hardhat-toolbox"); - -module.exports = { - solidity: "0.8.9", -}; -``` - -::: - -:::: - -Plugins are **essential** to Hardhat projects, so make sure to check out all the available ones and also build your own! - -### Setting up your editor - -[Hardhat for Visual Studio Code](/hardhat-vscode) is the official Hardhat extension that adds advanced support for Solidity to VSCode. If you use Visual Studio Code, give it a try! diff --git a/docs/src/content/hardhat-runner/docs/guides/tasks-and-scripts.md b/docs/src/content/hardhat-runner/docs/guides/tasks-and-scripts.md deleted file mode 100644 index cfe6233697..0000000000 --- a/docs/src/content/hardhat-runner/docs/guides/tasks-and-scripts.md +++ /dev/null @@ -1,85 +0,0 @@ -# Writing tasks and scripts - -At its core, Hardhat is a task runner that allows you to automate your development workflow. It comes with some built-in tasks, like `compile` and `test`, but you can add your own custom tasks as well. - -This guide will show you how to extend Hardhat's functionality using tasks and scripts. It assumes you have initialized a sample project. If you haven't done it, please read [this guide](./project-setup.md) first. - -## Writing Hardhat Tasks - -Let's write a very simple task that prints the list of available accounts, and explore how it works. - -Copy this task definition and paste it into your hardhat config file: - -```js -task("accounts", "Prints the list of accounts", async (taskArgs, hre) => { - const accounts = await hre.ethers.getSigners(); - - for (const account of accounts) { - console.log(account.address); - } -}); -``` - -Now you should be able to run it: - -``` -npx hardhat accounts -``` - -We are using the `task` function to define our new task. Its first argument is the name of the task, and it's what we use in the command line to run it. The second argument is the description of the task, which is printed when you use `npx hardhat help`. - -The third argument is an async function that gets executed when you run the task. It receives two arguments: - -1. An object with the arguments for the task. We didn't define any yet. -2. The [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) or HRE, which contains all the functionality of Hardhat and its plugins. You can also find all of its properties injected into the `global` namespace during the task execution. - -You are free to do anything you want in this function. In this case, we use `ethers.getSigners()` to obtain all the configured accounts and print each of their addresses. - -You can add parameters to your tasks, and Hardhat will handle their parsing and validation for you. - -You can also override existing tasks, which allows you to change how different parts of Hardhat work. - -To learn more about tasks, please read [this guide](../advanced/create-task). - -## Writing Hardhat scripts - -You can write scripts and run them with Hardhat. They can take advantage of the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) to access all of Hardhat's functionality, including the task runner. - -Here's a script that does the same as our `accounts` task. Create an `accounts.js` file in the `scripts` directory with this content: - -```js -async function main() { - const accounts = await ethers.getSigners(); - - for (const account of accounts) { - console.log(account.address); - } -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); -``` - -And run it using the built-in `run` task: - -``` -npx hardhat run scripts/accounts.js -``` - -Note that we are using `ethers` without importing it. This is possible because everything that is available in the Hardhat Runtime Environment is also globally available in the script. - -To learn more about scripts, including how to run them without using Hardhat's CLI, please read [this guide](../advanced/scripts). - -## Choosing between tasks and scripts - -Choosing between tasks and scripts is up to you. If you are in doubt which one you should use, you may find this useful: - -1. If you want to automate a workflow that requires no parameters, a script is probably the best choice. - -2. If the workflow you are automating requires some parameters, consider creating a Hardhat task. - -3. If you need to access the Hardhat Runtime Environment from another tool which has its own CLI, like [`jest`](https://jestjs.io/) or [`ndb`](https://www.npmjs.com/package/ndb), you should write a script. Make sure to import the Hardhat runtime environment explicitly, so it can be [run with that tool instead of Hardhat's CLI](../advanced/scripts#standalone-scripts:-using-hardhat-as-a-library). - -4. If you feel Hardhat's parameter handling is falling short of your needs, you should write a script. Just import the Hardhat runtime environment explicitly, use your own argument parsing logic (e.g. using [`yargs`](https://yargs.js.org/)), and [run it as a standalone Node.js script](../advanced/scripts#standalone-scripts:-using-hardhat-as-a-library). diff --git a/docs/src/content/hardhat-runner/docs/guides/test-contracts.md b/docs/src/content/hardhat-runner/docs/guides/test-contracts.md deleted file mode 100644 index d7e4e93552..0000000000 --- a/docs/src/content/hardhat-runner/docs/guides/test-contracts.md +++ /dev/null @@ -1,288 +0,0 @@ -# Testing contracts - -After [compiling your contracts](./compile-contracts.md), the next step is to write some tests to verify that they work as intended. - -This guide explains our recommended approach for testing contracts in Hardhat. It relies on [ethers](https://docs.ethers.io/v5/) to connect to [Hardhat Network](/hardhat-network) and on [Mocha](https://mochajs.org/) and [Chai](https://www.chaijs.com/) for the tests. It also uses our custom [Chai matchers](/hardhat-chai-matchers) and our [Hardhat Network Helpers](/hardhat-network-helpers) to make it easier to write clean test code. These packages are part of the Hardhat Toolbox plugin; if you followed the previous guides, you should already have them installed. - -While this is our recommended test setup, Hardhat is flexible: you can customize the approach or take a completely different path with other tools. - -### Initial setup - -In this guide we’ll write some tests for the sample project. If you haven’t done it yet, go and [initialize it](./project-setup.md). - -We recommend you [use TypeScript](./typescript.md) to get better autocompletion and catch possible errors earlier. This guide will assume you are using TypeScript, but you can click the tabs of the code examples to switch their language. - -The setup includes some example tests in the `test/Lock.ts` file, but ignore them for now. Instead, create a `test/my-tests.ts` file. During this guide we'll only run those, by running `npx hardhat test test/my-tests.ts`, instead of just `npx hardhat test`. - -### A simple test - -In the following sections we'll write some tests for the `Lock` contract that comes with the sample project. If you haven't read it yet, please take a look at the `contracts/Lock.sol` file. - -For our first test we’ll deploy the `Lock` contract and assert that the unlock time returned by the `unlockTime()` getter is the same one that we passed in the constructor: - -::::tabsgroup{options="TypeScript,JavaScript"} - -:::tab{value="TypeScript"} - -```tsx -import { expect } from "chai"; -import hre from "hardhat"; -import { time } from "@nomicfoundation/hardhat-network-helpers"; - -describe("Lock", function () { - it("Should set the right unlockTime", async function () { - const lockedAmount = 1_000_000_000; - const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; - const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; - - // deploy a lock contract where funds can be withdrawn - // one year in the future - const Lock = await hre.ethers.getContractFactory("Lock"); - const lock = await Lock.deploy(unlockTime, { value: lockedAmount }); - - // assert that the value is correct - expect(await lock.unlockTime()).to.equal(unlockTime); - }); -}); -``` - -::: - -:::tab{value="JavaScript"} - -```js -const { expect } = require("chai"); -const hre = require("hardhat"); -const { time } = require("@nomicfoundation/hardhat-network-helpers"); - -describe("Lock", function () { - it("Should set the right unlockTime", async function () { - const lockedAmount = 1_000_000_000; - const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; - const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; - - // deploy a lock contract where funds can be withdrawn - // one year in the future - const Lock = await hre.ethers.getContractFactory("Lock"); - const lock = await Lock.deploy(unlockTime, { value: lockedAmount }); - - // assert that the value is correct - expect(await lock.unlockTime()).to.equal(unlockTime); - }); -}); -``` - -::: - -:::: - -First we import the things we are going to use: the [`expect`](https://www.chaijs.com/api/bdd/) function from `chai` to write our assertions, the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) (`hre`), and the [network helpers](/hardhat-network-helpers) to interact with the Hardhat Network. After that we use the `describe` and `it` functions, which are global Mocha functions used to describe and group your tests. (You can read more about Mocha [here](https://mochajs.org/#getting-started).) - -The test itself is what’s inside the callback argument to the `it` function. First we set the values for the amount we want to lock (in [wei](https://ethereum.org/en/glossary/#wei)) and the unlock time. For the latter we use [`time.latest`](), a network helper that returns the timestamp of the last mined block. Then we deploy the contract itself: first we get a [`ContractFactory`](https://docs.ethers.io/v5/single-page/#/v5/api/contract/contract-factory/) for the `Lock` contract and then we deploy it, passing the unlock time as its constructor argument. We also pass an object with the transaction parameters. This is optional, but we'll use it to send some ETH by setting its `value` field. - -Finally, we check that the value returned by the `unlockTime()` [getter](https://docs.soliditylang.org/en/v0.8.13/contracts.html#getter-functions) in the contract matches the value that we used when we deployed it. Since all the functions on a contract are async, we have to use the `await` keyword to get its value; otherwise, we would be comparing a promise with a number and this would always fail. - -### Testing a function that reverts - -In the previous test we checked that a getter function returned the correct value. This was a read-only function that can be called without paying a fee and without any risk. Other functions, however, can modify the state of the contract, like the `withdraw` function in the `Lock` contract. This means that we want some pre-conditions to be met for this function to be called successfully. If you look at its first lines you’ll see a couple of `require` checks for that purpose: - -```solidity -function withdraw() public { - require(block.timestamp >= unlockTime, "You can't withdraw yet"); - require(msg.sender == owner, "You aren't the owner"); -``` - -The first statement checks that the unlock time has been reached, and the second one checks that the address calling the contract is its owner. Let’s start by writing a test for the first pre-condition: - -```tsx -it("Should revert with the right error if called too soon", async function () { - // ...deploy the contract as before... - - await expect(lock.withdraw()).to.be.revertedWith("You can't withdraw yet"); -}); -``` - -In the previous test we used `.to.equal`, which is part of Chai and is used to compare two values. Here we are using [`.to.be.revertedWith`](/hardhat-chai-matchers/docs/reference#.revertedwith), which asserts that a transaction reverts, and that the reason string of the revert is equal to the given string. The `.to.be.revertedWith` matcher is not part of Chai itself; instead, it’s added by the [Hardhat Chai Matchers](/hardhat-chai-matchers) plugin, which is included in the sample project we are using. - -Notice that in the previous test we wrote `expect(await ...)` but now we are doing `await expect(...)`. In the first case we were comparing two values in a synchronous way; the inner await is just there to wait for the value to be retrieved. In the second case, the whole assertion is async because it has to wait until the transaction is mined. This means that the `expect` call returns a promise that we have to await. - -### Manipulating the time of the network - -We are deploying our `Lock` contract with an unlock time of one year. If we want to write a test that checks what happens after the unlock time has passed, we can’t wait that amount of time. We could use a shorter unlock time, like 5 seconds, but that’s a less realistic value and it's still a long time to wait in a test. - -The solution is to simulate the passage of time. This can be done with the [`time.increaseTo`]() network helper, which mines a new block with the given timestamp: - -```tsx -it("Should transfer the funds to the owner", async function () { - // ...deploy the contract... - - await time.increaseTo(unlockTime); - - // this will throw if the transaction reverts - await lock.withdraw(); -}); -``` - -As we mentioned, calling `lock.withdraw()` returns a Promise. If the transaction fails, the promise will be rejected. Using `await` will throw in that case, so the test will fail if the transaction reverts. - -### Using a different address - -The second check done by the `withdraw` function is that the function was called by the owner of the contract. By default, deployments and function calls are done with the first [configured account](/hardhat-network/docs/reference.md#accounts). If we want to check that only the owner can call some function, we need to use a different account and verify that it fails. - -The `ethers.getSigners()` returns an array with all the configured accounts. We can use the `.connect` method of the contract to call the function with a different account and check that the transaction reverts: - -```tsx -it("Should revert with the right error if called from another account", async function () { - // ...deploy the contract... - - const [owner, otherAccount] = await ethers.getSigners(); - - // we increase the time of the chain to pass the first check - await time.increaseTo(unlockTime); - - // We use lock.connect() to send a transaction from another account - await expect(lock.connect(otherAccount).withdraw()).to.be.revertedWith( - "You aren't the owner" - ); -}); -``` - -Here again we are calling a function and asserting that it reverts with the correct reason string. The difference is that we are using `.connect(anotherAccount)` to call the method from a different address. - -### Using fixtures - -So far we've deployed the `Lock` contract in each test. This means that at the beginning of each test we have to get the contract factory and then deploy the contract. This might be fine for a single contract but, if you have a more complicated setup, each test will have several lines at the beginning just to set up the desired state, and most of the time these lines will be the same. - -In a typical Mocha test, this duplication of code is handled with a `beforeEach` hook: - -::::tabsgroup{options="TypeScript,JavaScript"} - -:::tab{value="TypeScript"} - -```tsx -import { Contract } from "ethers"; - -describe("Lock", function () { - let lock: Contract; - let unlockTime: number; - let lockedAmount = 1_000_000_000; - - beforeEach(async function () { - const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; - unlockTime = (await helpers.time.latest()) + ONE_YEAR_IN_SECS; - - const Lock = await ethers.getContractFactory("Lock"); - lock = await Lock.deploy(unlockTime, { value: lockedAmount }); - }); - - it("some test", async function () { - // use the deployed contract - }); -}); -``` - -::: - -:::tab{value="JavaScript"} - -```tsx -describe("Lock", function () { - let lock; - let unlockTime; - let lockedAmount = 1_000_000_000; - - beforeEach(async function () { - const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; - unlockTime = (await helpers.time.latest()) + ONE_YEAR_IN_SECS; - - const Lock = await ethers.getContractFactory("Lock"); - lock = await Lock.deploy(unlockTime, { value: lockedAmount }); - }); - - it("some test", async function () { - // use the deployed contract - }); -}); -``` - -::: - -:::: - -However, there are two problems with this approach: - -- If you have to deploy many contracts, your tests will be slower because each one has to send multiple transactions as part of its setup. -- Sharing the variables like this between the `beforeEach` hook and your tests is ugly and error-prone. - -The `loadFixture` helper in the Hardhat Network Helpers fixes both of these problems. This helper receives a _fixture_, a function that sets up the chain to some desired state. The first time `loadFixture` is called, the fixture is executed. But the second time, instead of executing the fixture again, `loadFixture` will reset the state of the network to the point where it was right after the fixture was executed. This is faster, and it undoes any state changes done by the previous test. - -This is how our two first tests look like when a fixture is used: - -```tsx -describe("Lock", function () { - async function deployOneYearLockFixture() { - const lockedAmount = 1_000_000_000; - const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60; - const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS; - - const Lock = await ethers.getContractFactory("Lock"); - const lock = await Lock.deploy(unlockTime, { value: lockedAmount }); - - return { lock, unlockTime, lockedAmount }; - } - - it("Should set the right unlockTime", async function () { - const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture); - - // assert that the value is correct - expect(await lock.unlockTime()).to.equal(unlockTime); - }); - - it("Should revert with the right error if called too soon", async function () { - const { lock } = await loadFixture(deployOneYearLockFixture); - - await expect(lock.withdraw()).to.be.revertedWith("You can't withdraw yet"); - }); -}); -``` - -The fixture function can return anything you want, and the `loadFixture` helper will return it. We recommend returning an object like we did here, so you can extract only the values you care about for that test. - -### Other tests - -There are several other things you can test, like [which events are emitted](/hardhat-chai-matchers/docs/reference#.emit) or [how the balances of the involved addresses change](/hardhat-chai-matchers/docs/reference#balance-change). Check the `test/Lock.js` file to see the other examples. - -### Measuring code coverage - -The Hardhat Toolbox includes the [`solidity-coverage`](https://github.com/sc-forks/solidity-coverage) plugin to measure the test coverage in your project. Just run the `coverage` task and you'll get a report: - -``` -npx hardhat coverage -``` - -### Using the gas reporter - -The Hardhat Toolbox also includes the [`hardhat-gas-reporter`](https://github.com/cgewecke/hardhat-gas-reporter) plugin to get metrics of how much gas is used, based on the execution of your tests. The gas reporter is run when the `test` task is executed and the `REPORT_GAS` environment variable is set: - -``` -REPORT_GAS=true npx hardhat test -``` - -### Running tests in parallel - -You can run your tests in parallel by using the `--parallel` flag: - -``` -npx hardhat test --parallel -``` - -Alternatively, use `parallel: true` in the `mocha` section of your Hardhat config. - -Most of the time, running your tests serially or in parallel should produce the same results, but there are some scenarios where tests run in parallel will behave differently: - -- In serial mode all the test files share the same instance of the Hardhat Runtime Environment, but in parallel mode this is not always the case. Mocha uses a pool of workers to execute the tests, and each worker starts with its own instance of the HRE. This means that if one test file deploys a contract, then that deployment will exist in some of the other test files and it won't in others. -- The `.only` modifier doesn't work in parallel mode. As an alternative, you can use `--grep` to run specific tests. -- Because parallel mode uses more system resources, the duration of individual tests might be longer, so there's a chance that some tests start timing out for that reason. If you run into this problem, you can increase the tests timeout in the Mocha section of your Hardhat config or using `this.timeout()` in your tests. -- The order in which tests are executed is non-deterministic. - -There are some other limitations related to parallel mode. You can read more about them in Mocha's docs. And if you are running into some issue when using parallel mode, you can check their Troubleshooting parallel mode section. diff --git a/docs/src/content/hardhat-runner/docs/guides/typescript.md b/docs/src/content/hardhat-runner/docs/guides/typescript.md deleted file mode 100644 index d54671b9e8..0000000000 --- a/docs/src/content/hardhat-runner/docs/guides/typescript.md +++ /dev/null @@ -1,181 +0,0 @@ -# Using TypeScript - -In this guide, we will go through the steps to get a Hardhat project working with TypeScript. This means that you can write your Hardhat config, tasks, scripts and tests in [TypeScript](https://www.typescriptlang.org/). - -For a general overview of using Hardhat refer to the [Getting started guide](../getting-started/index.md). - -## Enabling TypeScript support - -Hardhat will automatically enable its TypeScript support if your config file ends in `.ts` and is written in valid TypeScript. This requires a few changes to work properly. - -### Installing dependencies - -:::tip - -If you installed [`@nomicfoundation/hardhat-toolbox`](../../plugins/nomicfoundation-hardhat-toolbox) using npm 7 or higher, you don't need to follow these steps. - -::: - -Hardhat uses TypeScript and `ts-node` under the hood, so you need to install them. To do it, open your terminal, go to your Hardhat project, and run: - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm install --save-dev ts-node typescript -``` - -::: - -:::tab{value="npm 6"} - -``` -npm install --save-dev ts-node typescript -``` - -::: - -:::tab{value=yarn} - -``` -yarn add --dev ts-node typescript -``` - -::: - -:::: - -To be able to write your tests in TypeScript, you also need these packages: - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm install --save-dev chai @types/node @types/mocha @types/chai -``` - -::: - -:::tab{value="npm 6"} - -``` -npm install --save-dev chai @types/node @types/mocha @types/chai -``` - -::: - -:::tab{value=yarn} - -``` -yarn add --dev chai @types/node @types/mocha @types/chai -``` - -::: - -:::: - -### TypeScript configuration - -You can easily turn a JavaScript Hardhat config file into a TypeScript one. Let's see how this is done starting with a fresh Hardhat project. - -Open your terminal, go to an empty folder, run `npx hardhat`, and go through the steps to create a JavaScript project. When you're done your project directory should look something like this: - -``` -$ ls -l -total 1200 -drwxr-xr-x 3 pato wheel 96 Oct 20 12:50 contracts/ --rw-r--r-- 1 pato wheel 567 Oct 20 12:50 hardhat.config.js -drwxr-xr-x 434 pato wheel 13888 Oct 20 12:52 node_modules/ --rw-r--r-- 1 pato wheel 604835 Oct 20 12:52 package-lock.json --rw-r--r-- 1 pato wheel 460 Oct 20 12:52 package.json -drwxr-xr-x 3 pato wheel 96 Oct 20 12:50 scripts/ -drwxr-xr-x 3 pato wheel 96 Oct 20 12:50 test/ -``` - -Then, you should follow the steps mentioned in the [Installing dependencies](#installing-dependencies) section above. - -Now, we are going to rename the config file from `hardhat.config.js` to `hardhat.config.ts`, just run: - -``` -mv hardhat.config.js hardhat.config.ts -``` - -We need to make a single change to your config for it to work with TypeScript: you must use `import`/`export` instead of `require`/`module.exports`. - -By using TypeScript, you can also type your configuration, which will save you from typos and other mistakes. - -For example, the sample project's config turns from this: - -<<< @/../packages/hardhat-core/sample-projects/javascript/hardhat.config.js{1,4} - -into this: - -<<< @/../packages/hardhat-core/sample-projects/typescript/hardhat.config.ts{1,2,4,8} - -Finally, you need to create a [`tsconfig.json`](https://www.typescriptlang.org/docs/handbook/tsconfig-json.html) file. Here's our recommended one: - -<<< @/../packages/hardhat-core/sample-projects/typescript/tsconfig.json - -And that's really all it takes. Now you can write your config, tests, tasks and scripts in TypeScript. - -## Type-checking your project - -For performance reasons, Hardhat won't type-check your project when you run a task. You can explicitly enable type-checking with the `--typecheck` flag. - -For example, if you run `npx hardhat test` and one of your tests has a compilation error, the test task will be executed anyway. But if you run `npx hardhat test --typecheck`, Hardhat will detect and throw the compilation error before starting to run the tests. - -Since type-checking adds significant overhead, we recommend to do it only in your CI or in pre-commit/pre-push hooks. - -## Writing tests and scripts in TypeScript - -When using JavaScript, all the properties in the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md) are injected into the global scope. When using TypeScript nothing will be available in the global scope and you will need to import everything explicitly using, for example, `import { ethers } from "hardhat"`. - -Follow the [Getting started guide](../getting-started/index.md) and create a TypeScript project for a complete example on how to write tests and scripts using TypeScript. - -## Type-safe smart contract interactions - -:::tip - -If you installed [`@nomicfoundation/hardhat-toolbox`](../../plugins/nomicfoundation-hardhat-toolbox) you can skip this section, as it includes [`@typechain/hardhat`](https://github.com/ethereum-ts/TypeChain/tree/master/packages/hardhat). - -::: - -If you want Hardhat to generate types for your smart contract you should install and use [`@typechain/hardhat`](https://github.com/ethereum-ts/TypeChain/tree/master/packages/hardhat). It generates typing files (`*.d.ts`) based on ABI's, and it requires little to no configuration. - -## Support for path mappings - -Typescript allows defining custom [path mappings](https://www.typescriptlang.org/docs/handbook/module-resolution.html#path-mapping) via the [`paths`](https://www.typescriptlang.org/tsconfig#paths) configuration option: - -```json5 -{ - compilerOptions: { - paths: { "~/*": ["src/*"] }, - // ...Other compilerOptions - }, -} -``` - -To support this option when running Hardhat tests or scripts, you need to install the package [`tsconfig-paths`](https://www.npmjs.com/package/tsconfig-paths) and register it in your `hardhat.config.ts`: - -```typescript -import { HardhatUserConfig } from "hardhat/config"; - -// This adds support for typescript paths mappings -import "tsconfig-paths/register"; - -const config: HardhatUserConfig = { - // Your type-safe config goes here -}; - -export default config; -``` - -## Running your tests and scripts directly with `ts-node` - -When running Hardhat scripts without the CLI, you need to use `ts-node`'s [`--files` flag](https://www.npmjs.com/package/ts-node#help-my-types-are-missing). - -This can also be enabled with `TS_NODE_FILES=true`. - -[hardhat runtime environment]: ../advanced/hardhat-runtime-environment.md diff --git a/docs/src/content/hardhat-runner/docs/guides/verifying.md b/docs/src/content/hardhat-runner/docs/guides/verifying.md deleted file mode 100644 index 35e91c571e..0000000000 --- a/docs/src/content/hardhat-runner/docs/guides/verifying.md +++ /dev/null @@ -1,158 +0,0 @@ -# Verifying your contracts - -Once your contract is ready, the next step is to deploy it to a live network and verify its source code. - -Verifying a contract means making its source code public, along with the compiler settings you used, which allows anyone to compile it and compare the generated bytecode with the one that is deployed on-chain. Doing this is extremely important in an open platform like Ethereum. - -In this guide we'll explain how to do this in the [Etherscan](https://etherscan.io/) explorer, but there are other ways to verify a contract, for example with [Sourcify](https://sourcify.dev/). - -## Getting an API key from Etherscan - -The first thing you need is an API key from Etherscan. To get one, go to [their site](https://etherscan.io/login), sign in (or create an account if you don't have one) and open the "API Keys" tab. Then click the "Add" button and give a name (like "Hardhat") to the API key you are creating. After that you'll see the newly created key in the list. - -Open your Hardhat config and add the API key you just created: - -::::tabsgroup{options=TypeScript,JavaScript} - -:::tab{value=TypeScript} - -```ts -export default { - // ...rest of the config... - etherscan: { - apiKey: "ABCDE12345ABCDE12345ABCDE123456789", - }, -}; -``` - -::: - -:::tab{value=JavaScript} - -```js -module.exports = { - // ...rest of the config... - etherscan: { - apiKey: "ABCDE12345ABCDE12345ABCDE123456789", - }, -}; -``` - -::: - -:::: - -## Deploying and verifying a contract in the Sepolia testnet - -We are going to use the [Sepolia testnet](https://ethereum.org/en/developers/docs/networks/#sepolia) to deploy and verify our contract, so you need to add this network in your Hardhat config. Here we are using [Infura](https://infura.io/) to connect to the network, but you can use an alternative JSON-RPC URL like [Alchemy](https://alchemy.com/) if you want. - -::::tabsgroup{options=Infura,Alchemy} - -:::tab{value=Infura} - -```js -// Go to https://infura.io, sign up, create a new API key -// in its dashboard, and replace "KEY" with it -const INFURA_API_KEY = "KEY"; - -// Replace this private key with your Sepolia account private key -// To export your private key from Coinbase Wallet, go to -// Settings > Developer Settings > Show private key -// To export your private key from Metamask, open Metamask and -// go to Account Details > Export Private Key -// Beware: NEVER put real Ether into testing accounts -const SEPOLIA_PRIVATE_KEY = "YOUR SEPOLIA PRIVATE KEY"; - -module.exports = { - // ...rest of your config... - networks: { - sepolia: { - url: `https://sepolia.infura.io/v3/${INFURA_API_KEY}`, - accounts: [SEPOLIA_PRIVATE_KEY], - }, - }, -}; -``` - -::: - -:::tab{value=Alchemy} - -```js -// Go to https://alchemy.com, sign up, create a new App in -// its dashboard, and replace "KEY" with its key -const ALCHEMY_API_KEY = "KEY"; - -// Replace this private key with your Sepolia account private key -// To export your private key from Coinbase Wallet, go to -// Settings > Developer Settings > Show private key -// To export your private key from Metamask, open Metamask and -// go to Account Details > Export Private Key -// Beware: NEVER put real Ether into testing accounts -const SEPOLIA_PRIVATE_KEY = "YOUR SEPOLIA PRIVATE KEY"; - -module.exports = { - // ...rest of your config... - networks: { - sepolia: { - url: `https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY}`, - accounts: [SEPOLIA_PRIVATE_KEY], - }, - }, -}; -``` - -::: - -:::: - -To deploy on Sepolia you need to send some Sepolia ether to the address that's going to be making the deployment. You can get testnet ether from a faucet, a service that distributes testing-ETH for free. Here is one for Sepolia: - -- [Alchemy Sepolia Faucet](https://sepoliafaucet.com/) - -Now you are ready to deploy your contract, but first we are going to make the source code of our contract unique. The reason we need to do this is that the sample code from the previous section is already verified in Sepolia, so if you try to verify it you'll get an error. - -Open your contract and add a comment with something unique, like your GitHub's username. Keep in mind that whatever you include here will be, like the rest of the code, publicly available on Etherscan: - -```solidity -// Author: @janedoe -contract Lock { -``` - -You can now run the deploy script using the newly added Sepolia network: - -::::tabsgroup{options=TypeScript,JavaScript} - -:::tab{value=TypeScript} - -``` -npx hardhat run scripts/deploy.ts --network sepolia -``` - -::: - -:::tab{value=JavaScript} - -``` -npx hardhat run scripts/deploy.js --network sepolia -``` - -::: - -:::: - -Take note of the address and the unlock time and run the `verify` task with them: - -``` -npx hardhat verify --network sepolia
    -``` - -:::tip - -If you get an error saying that the address does not have bytecode, it probably means that Etherscan has not indexed your contract yet. In that case, wait for a minute and then try again. - -::: - -After the task is successfully executed, you'll see a link to the publicly verified code of your contract. - -To learn more about verifying, read the [hardhat-verify](/hardhat-runner/plugins/nomicfoundation-hardhat-verify) documentation. diff --git a/docs/src/content/hardhat-runner/docs/other-components/_dirinfo.yaml b/docs/src/content/hardhat-runner/docs/other-components/_dirinfo.yaml deleted file mode 100644 index 193d21e233..0000000000 --- a/docs/src/content/hardhat-runner/docs/other-components/_dirinfo.yaml +++ /dev/null @@ -1,11 +0,0 @@ -section-type: group -section-title: Other Hardhat components -order: - - href: /../../../hardhat-network/docs - title: Hardhat Network - - href: /../../../hardhat-vscode/docs - title: Hardhat VSCode - - href: /../../../hardhat-chai-matchers/docs - title: Hardhat Chai Matchers - - href: /../../../hardhat-network-helpers/docs - title: Hardhat Network Helpers diff --git a/docs/src/content/hardhat-runner/docs/other-guides/_dirinfo.yaml b/docs/src/content/hardhat-runner/docs/other-guides/_dirinfo.yaml deleted file mode 100644 index 0e880b9164..0000000000 --- a/docs/src/content/hardhat-runner/docs/other-guides/_dirinfo.yaml +++ /dev/null @@ -1,2 +0,0 @@ -section-type: hidden -section-title: Other guides diff --git a/docs/src/content/hardhat-runner/docs/other-guides/ganache-tests.md b/docs/src/content/hardhat-runner/docs/other-guides/ganache-tests.md deleted file mode 100644 index 6ff3ba1524..0000000000 --- a/docs/src/content/hardhat-runner/docs/other-guides/ganache-tests.md +++ /dev/null @@ -1,43 +0,0 @@ -# Running tests with Ganache - -:::warning - -Rather than using Ganache, we recommend using the built-in [Hardhat Network](../../../hardhat-network/docs/overview/index.md) network to test your smart contracts, as it generates [combined JavaScript and Solidity stack traces](../../../hardhat-network/docs/overview/index.md#solidity-stack-traces), making debugging easier. - -If you still want to run your tests using Ganache, you can do it in one of the following two ways. - -::: - -## Manually running Ganache - -You don't need to do anything special to use Ganache if you don't want to. - -Just start Ganache and then run Hardhat with - -``` -npx hardhat --network localhost test -``` - -## Using the `hardhat-ganache` plugin - -If you don't want to manually start and stop Ganache every time, you can use the `hardhat-ganache` plugin. - -This plugin creates a network called `ganache`, and automatically starts and stops Ganache before and after running your tests and scripts. - -To use it, you have to install it with npm - -``` -npm install --save-dev @nomiclabs/hardhat-ganache -``` - -and add this line at the beginning of your `hardhat.config.js` - -```js -require("@nomiclabs/hardhat-ganache"); -``` - -Finally, you can run your tests with - -``` -npx hardhat --network ganache test -``` diff --git a/docs/src/content/hardhat-runner/docs/other-guides/truffle-migration.md b/docs/src/content/hardhat-runner/docs/other-guides/truffle-migration.md deleted file mode 100644 index 097f60400e..0000000000 --- a/docs/src/content/hardhat-runner/docs/other-guides/truffle-migration.md +++ /dev/null @@ -1,68 +0,0 @@ -# Migrating from Truffle - -Hardhat is a task runner that facilitates building Ethereum smart contracts. It helps developers manage and automate the recurring tasks that are inherent to the process of building smart contracts, as well as easily introducing more functionality around this workflow. This means compiling and testing at the very core. - -The bulk of Hardhat's functionality comes from plugins, and as a developer you're free to choose the ones you want to use. There are plugins for Truffle 4 and 5 that make migrating to Hardhat easy. - -To migrate an existing Truffle project to Hardhat there are two main things to consider: testing and deployment. - -### Testing - -When it comes to unit tests, there are two Hardhat plugins that support the Truffle testing APIs: `hardhat-truffle4` and `hardhat-truffle5`. Using these you can run your existing tests with Hardhat. - -If you want to learn the details of writing Truffle tests to run in Hardhat, then you can read [this guide](./truffle-testing.md), but it's not necessary in order to migrate your existing test suite. - -#### Migrations and hardhat-truffle fixtures - -If your project uses [Truffle Migrations](https://www.trufflesuite.com/docs/truffle/getting-started/running-migrations) to initialize your testing environment (i.e. your tests call `Contract.deployed()`), then there's some more work to do to be able to run your tests. - -The Truffle plugins currently don't fully support Migrations. Instead, you need to adapt your Migrations to become a hardhat-truffle fixture. This file, located at `test/truffle-fixture.js`, deploys your contracts and calls the `setAsDeployed()` method on each of the contract abstractions you want to test. - -For example, this migration: - -```js -const Greeter = artifacts.require("Greeter"); - -module.exports = function (deployer) { - deployer.deploy(Greeter); -}; -``` - -should become this hardhat-truffle fixture: - -```js -const Greeter = artifacts.require("Greeter"); - -module.exports = async () => { - const greeter = await Greeter.new(); - Greeter.setAsDeployed(greeter); -}; -``` - -These fixtures will run on Mocha's `before`, which runs before each `contract()` function runs, just like Truffle migrations do. - -If you have multiple migrations, you don't need to create multiple hardhat-truffle fixture files. You can deploy all your contracts from the same one. - -Once you've written your hardhat-truffle fixtures for your migrations and completed your setup you can run your tests with `npx hardhat test`. Take a look at the [Truffle testing guide](/guides/truffle-testing.md) to learn more about using Truffle with Hardhat. - -### Deployment - -When it comes to deploying, there are no official plugins that implement a deployment system for Hardhat yet. In the meantime, we recommend [deploying your smart contracts using scripts](../guides/deploying.md), or using [the hardhat-deploy community plugin](https://github.com/wighawag/hardhat-deploy/tree/master). - -### Truffle 4 and Web3.js' synchronous calls - -Truffle 4 uses Web3.js `0.20.x`, which supports doing synchronous calls. These aren't supported by the `hardhat-web3-legacy` plugin, which is the plugin that integrates Web3.js `0.20.x`. - -Instead, you should use the promisified version of Web3.js offered by the plugin: `pweb3`. It's available as a global variable in your tests and tasks, and in the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md). It has the same API as Web3.js, but asynchronous operations return promises. - -For example, this code: - -```js -console.log(web3.eth.accounts); -``` - -should become: - -```js -console.log(await web3.eth.getAccounts()); -``` diff --git a/docs/src/content/hardhat-runner/docs/other-guides/truffle-testing.md b/docs/src/content/hardhat-runner/docs/other-guides/truffle-testing.md deleted file mode 100644 index e291fd71f6..0000000000 --- a/docs/src/content/hardhat-runner/docs/other-guides/truffle-testing.md +++ /dev/null @@ -1,179 +0,0 @@ -# Testing with Web3.js & Truffle - -:::tip - -Read [this guide](/hardhat-runner/docs/guides/test-contracts.md) to learn about our recommended approach to testing contracts. - -::: - -Hardhat allows you to use Truffle to test your smart contracts. This mainly means compatibility with the [`@truffle/contract`](https://www.npmjs.com/package/@truffle/contract) package to interact with your smart contracts. - -Truffle 4 and Truffle 5 are supported using the `@nomiclabs/hardhat-truffle4` and `@nomiclabs/hardhat-truffle5` plugins respectively. - -Let's see how to do this creating a new Hardhat project. - -Run these to start: - -``` -mkdir my-project -cd my-project -npm init --yes -npm install --save-dev hardhat -``` - -Now run `npx hardhat` inside your project folder and select `Create an empty hardhat.config.js`. - -Let's now install the `Truffle` and `Web3.js` plugins, as well as `web3.js` itself. - -``` -npm install --save-dev @nomiclabs/hardhat-truffle5 @nomiclabs/hardhat-web3 web3 -``` - -Enable the Truffle 5 plugin on your Hardhat config file by requiring it: - -```js{1} -require("@nomiclabs/hardhat-truffle5"); - -module.exports = { - solidity: "0.7.3" -}; -``` - -Create a folder named `contracts` inside your project. Add a file named `Greeter.sol`, and copy and paste this code: - -```c -pragma solidity ^0.7.0; - -contract Greeter { - - string greeting; - - constructor(string memory _greeting) { - greeting = _greeting; - } - - function greet() public view returns (string memory) { - return greeting; - } - - function setGreeting(string memory _greeting) public { - greeting = _greeting; - } - -} -``` - -## Writing a test - -Create a new directory called `test` inside your project root directory and create a new file called `Greeter.js`. - -Let's start with the code below. We'll explain it next, but for now paste this into `Greeter.js`: - -```js -const Greeter = artifacts.require("Greeter"); - -// Traditional Truffle test -contract("Greeter", (accounts) => { - it("Should return the new greeting once it's changed", async function () { - const greeter = await Greeter.new("Hello, world!"); - assert.equal(await greeter.greet(), "Hello, world!"); - - await greeter.setGreeting("Hola, mundo!"); - - assert.equal(await greeter.greet(), "Hola, mundo!"); - }); -}); - -// Vanilla Mocha test. Increased compatibility with tools that integrate Mocha. -describe("Greeter contract", function () { - let accounts; - - before(async function () { - accounts = await web3.eth.getAccounts(); - }); - - describe("Deployment", function () { - it("Should deploy with the right greeting", async function () { - const greeter = await Greeter.new("Hello, world!"); - assert.equal(await greeter.greet(), "Hello, world!"); - - const greeter2 = await Greeter.new("Hola, mundo!"); - assert.equal(await greeter2.greet(), "Hola, mundo!"); - }); - }); -}); -``` - -As you can see in the first line, the artifacts object is present in the global scope and you can use it to access the Truffle contract abstractions. - -```js -const Greeter = artifacts.require("Greeter"); -``` - -These examples show two approaches towards testing: - -- Using `contract()`, which is the traditional way to test with Truffle -- Using `describe()`, which is the traditional way to test using Mocha - -Truffle runs its tests with Mocha, but a few tools that integrate Mocha don't expect `contract()` and don't always work well. We recommend using the `describe()` approach. - -You can run these tests by running `npx hardhat test`: - -``` -$ npx hardhat test - -Contract: Greeter - ✓ Should return the new greeting once it's changed (265ms) - - Greeter contract - Deployment - ✓ Should deploy with the right greeting (114ms) - - - 2 passing (398ms) -``` - -If you want to use Truffle Migrations to initialize your tests and call `deployed()` on the contract abstractions, both `@nomiclabs/hardhat-truffle4` and `@nomiclabs/hardhat-truffle5` offer a fixtures feature to make this possible. Take a look at the [Truffle migration guide](./truffle-migration.md) to learn more. - -## Using Web3.js - -To use Web3.js in your tests, an instance of it is available in the global scope. You can see this in the `describe()` test in `Greeter.js`: - -```js{20} -const Greeter = artifacts.require("Greeter"); - -// Traditional Truffle test -contract("Greeter", accounts => { - it("Should return the new greeting once it's changed", async function() { - const greeter = await Greeter.new("Hello, world!"); - assert.equal(await greeter.greet(), "Hello, world!"); - - await greeter.setGreeting("Hola, mundo!"); - - assert.equal(await greeter.greet(), "Hola, mundo!"); - }); -}); - -// Vanilla Mocha test. Increased compatibility with tools that integrate Mocha. -describe("Greeter contract", function() { - let accounts; - - before(async function() { - accounts = await web3.eth.getAccounts(); - }); - - describe("Deployment", function() { - it("Should deploy with the right greeting", async function() { - const greeter = await Greeter.new("Hello, world!"); - assert.equal(await greeter.greet(), "Hello, world!"); - - const greeter2 = await Greeter.new("Hola, mundo!"); - assert.equal(await greeter2.greet(), "Hola, mundo!"); - }); - }); -}); -``` - -Checkout the plugin's [README file](https://github.com/NomicFoundation/hardhat/tree/main/packages/hardhat-truffle5) for more information about it. - -[hardhat runtime environment]: /documentation/#hardhat-runtime-environment-hre diff --git a/docs/src/content/hardhat-runner/docs/other-guides/waffle-testing.md b/docs/src/content/hardhat-runner/docs/other-guides/waffle-testing.md deleted file mode 100644 index 1c8521bd04..0000000000 --- a/docs/src/content/hardhat-runner/docs/other-guides/waffle-testing.md +++ /dev/null @@ -1,346 +0,0 @@ -# Testing with ethers.js & Waffle - -:::tip - -Read [this guide](/hardhat-runner/docs/guides/test-contracts.md) to learn about our recommended approach to testing contracts. - -::: - -Writing smart contract tests in Hardhat is done using JavaScript or TypeScript. - -In this guide, we'll show you how to use [Ethers.js](https://docs.ethers.io/), a JavaScript library to interact with Ethereum, and [Waffle](https://getwaffle.io/) a simple smart contract testing library built on top of it. - -Let's see how to use it starting from an empty Hardhat project. - -:::tip - -Ethers and Waffle support TypeScript. Learn how to set up Hardhat with TypeScript [here](/hardhat-runner/docs/guides/typescript.md). - -::: - -## Setting up - -[Install Hardhat](/hardhat-runner/docs/getting-started/index.md#installation) on an empty directory. When done, run `npx hardhat`: - -``` -$ npx hardhat -888 888 888 888 888 -888 888 888 888 888 -888 888 888 888 888 -8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888 -888 888 "88b 888P" d88" 888 888 "88b "88b 888 -888 888 .d888888 888 888 888 888 888 .d888888 888 -888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. -888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 - -Welcome to Hardhat v2.10.0 - -? What do you want to do? … -▸ Create a JavaScript project - Create a TypeScript project - Create an empty hardhat.config.js - Quit -``` - -Select `Create an empty hardhat.config.js`. This will create an empty Hardhat configuration file. - -Then install [`chai`](https://www.chaijs.com/), the `@nomiclabs/hardhat-waffle` plugin, and the peer dependencies of this plugin: - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm install --save-dev chai @nomiclabs/hardhat-waffle -``` - -::: - -:::tab{value="npm 6"} - -``` -npm install --save-dev chai @nomiclabs/hardhat-waffle ethereum-waffle @nomiclabs/hardhat-ethers ethers -``` - -::: - -:::tab{value="yarn"} - -``` -yarn add --dev chai @nomiclabs/hardhat-waffle ethereum-waffle @nomiclabs/hardhat-ethers ethers -``` - -::: - -:::: - -:::tip - -If you are using npm 7 or later, you only need to install chai and the plugin. npm will automatically install all the necessary peer dependencies. - -::: - -Then open the `hardhat.config.js` file and require the plugin: - -```js{1} -require("@nomiclabs/hardhat-waffle"); - -/** @type import('hardhat/config').HardhatUserConfig */ -module.exports = { - solidity: "0.8.9", -}; -``` - -:::tip - -There's no need for `require("@nomiclabs/hardhat-ethers")`, as `@nomiclabs/hardhat-waffle` already does it. - -::: - -## Testing - -Tests using Waffle are written with [Mocha](https://mochajs.org/) alongside [Chai](https://www.chaijs.com/), two popular JavaScript testing utilities. - -Before writing our test, let's add a simple contract. Create a `contracts` directory and then add a `contracts/Greeter.sol` file with this code: - -```solidity -//SPDX-License-Identifier: Unlicense -pragma solidity ^0.8.0; - -import "hardhat/console.sol"; - -contract Greeter { - string private greeting; - - constructor(string memory _greeting) { - console.log("Deploying a Greeter with greeting:", _greeting); - greeting = _greeting; - } - - function greet() public view returns (string memory) { - return greeting; - } - - function setGreeting(string memory _greeting) public { - console.log("Changing greeting from '%s' to '%s'", greeting, _greeting); - greeting = _greeting; - } -} -``` - -Then create a `test` folder and add a `test/test.js` file: - -```js -const { expect } = require("chai"); - -describe("Greeter", function () { - it("Should return the new greeting once it's changed", async function () { - const Greeter = await ethers.getContractFactory("Greeter"); - const greeter = await Greeter.deploy("Hello, world!"); - - expect(await greeter.greet()).to.equal("Hello, world!"); - - const setGreetingTx = await greeter.setGreeting("Hola, mundo!"); - - // wait until the transaction is mined - await setGreetingTx.wait(); - - expect(await greeter.greet()).to.equal("Hola, mundo!"); - }); -}); -``` - -In your terminal, run `npx hardhat test`. You should see the following output: - -``` - Greeter -Deploying a Greeter with greeting: Hello, world! -Changing greeting from 'Hello, world!' to 'Hola, mundo!' - ✔ Should return the new greeting once it's changed (847ms) - - - 1 passing (851ms) -``` - -This means the test passed. Let's now explain each line: - -```js -const { expect } = require("chai"); -``` - -We are requiring Chai, which is an assertions library. These asserting functions are called "matchers", and the ones we're using here actually come from Waffle. - -This is why we're using the `@nomiclabs/hardhat-waffle` plugin, which makes it easier to assert values from Ethereum. Check out [this section](https://ethereum-waffle.readthedocs.io/en/latest/matchers.html) in Waffle's documentation for the entire list of Ethereum-specific matchers. - -:::warning - -Some Waffle matchers return a Promise rather than executing immediately. If you're making a call or sending a transaction, make sure to check Waffle's documentation, and `await` these Promises. Otherwise your tests may pass without waiting for all checks to complete. - -::: - -```js -describe("Greeter", function () { - it("Should return the new greeting once it's changed", async function () { - // ... - }); -}); -``` - -This wrapper just follows Mocha's proposed structure for tests, but you might have noticed the use of `async` in `it`'s callback function. Interacting with the Ethereum network and smart contracts are asynchronous operations, hence most APIs and libraries use JavaScript's `Promise` for returning values. This use of `async` will allow us to `await` the calls to our contract and the Hardhat Network node. - -```js -const Greeter = await ethers.getContractFactory("Greeter"); -``` - -A `ContractFactory` in `ethers.js` is an abstraction used to deploy new smart contracts, so `Greeter` here is a factory for instances of our greeter contract. - -```js -const greeter = await Greeter.deploy("Hello, world!"); -``` - -Calling `deploy()` on a `ContractFactory` will start the deployment, and return a `Promise` that resolves to a `Contract`. This is the object that has a method for each of your smart contract functions. Here we're passing the string `Hello, world!` to the contract's constructor. - -Once the contract is deployed, we can call our contract methods on `greeter` and use them to get the state of the contract. - -```js -expect(await greeter.greet()).to.equal("Hello, world!"); -``` - -Here we're using our `Contract` instance to call a smart contract function in our Solidity code. `greet()` returns the greeter's greeting, and we're checking that it's equal to `Hello, world!`, as it should be. To do this we're using the Chai matchers `expect`, `to` and `equal`. - -```js -await greeter.setGreeting("Hola, mundo!"); -expect(await greeter.greet()).to.equal("Hola, mundo!"); -``` - -We can modify the state of a contract in the same way we read from it. Calling `setGreeting` will set a new greeting message. After the `Promise` is resolved, we perform another assertion to verify that the greeting change took effect. - -### Testing from a different account - -If you need to send a transaction from an account other than the default one, you can use the `connect()` method provided by Ethers.js. - -The first step to do so is to get the `Signers` object from `ethers`: - -```js -const [owner, addr1] = await ethers.getSigners(); -``` - -A `Signer` in Ethers.js is an object that represents an Ethereum account. It's used to send transactions to contracts and other accounts. Here we're getting a list of the accounts in the node we're connected to, which in this case is **Hardhat Network**, and only keeping the first and second ones. - -:::tip - -To learn more about `Signer`, you can look at the [Signers documentation](https://docs.ethers.io/v5/api/signer/#Wallet). - -::: - -The `ethers` variable is available in the global scope. If you like your code always being explicit, you can add this line at the top: - -```js -const { ethers } = require("hardhat"); -``` - -Finally, to execute a contract's method from another account, all you need to do is `connect` the `Contract` with the method being executed: - -```js -await greeter.connect(addr1).setGreeting("Hallo, Erde!"); -``` - -## Migrating an existing Waffle project - -If you're starting a project from scratch and looking to use Waffle, you can skip this section. If you're setting up an existing Waffle project to use Hardhat you'll need to migrate the [configuration options](https://ethereum-waffle.readthedocs.io/en/latest/configuration.html) Waffle offers. The following table maps Waffle configurations to their Hardhat equivalents: - -| Waffle | Hardhat | -| ---------------------------- | ------------------------------------ | -| `sourcesPath` | `paths.sources` | -| `targetPath` | `paths.artifacts` | -| `solcVersion` | `solc.version` (version number only) | -| `compilerOptions.evmVersion` | `solc.evmVersion` | -| `compilerOptions.optimizer` | `solc.optimizer` | - -As an example, this Waffle configuration file: - -```json -{ - "sourcesPath": "./some_custom/contracts_path", - "targetPath": "../some_custom/build", - "solcVersion": "v0.4.24+commit.e67f0147", - "compilerOptions": { - "evmVersion": "constantinople", - "optimizer": { - "enabled": true, - "runs": 200 - } - } -} -``` - -Would translate into this Hardhat config: - -```js -module.exports = { - paths: { - sources: "./some_custom/contracts_path", - artifacts: "../some_custom/build", - }, - solidity: { - version: "0.4.24", // Note that this only has the version number - settings: { - evmVersion: "constantinople", - optimizer: { - enabled: true, - runs: 200, - }, - }, - }, -}; -``` - -If you're migrating an existing Waffle project to Hardhat, then the minimum configuration you'll need is changing Hardhat's compilation output path, since Waffle uses a different one by default: - -```js -require("@nomiclabs/hardhat-waffle"); - -module.exports = { - paths: { - artifacts: "./build", - }, -}; -``` - -### Adapting the tests - -Now, when testing using a standalone Waffle setup, you should use the different parts of Waffle from Hardhat. - -For example, instead of doing: - -```js -const { deployContract } = require("ethereum-waffle"); -``` - -You should do: - -```typescript -const { waffle } = require("hardhat"); -const { deployContract } = waffle; -``` - -:::warning - -Importing Waffle's functions from `ethereum-waffle`, can lead to multiple problems. - -For example, Waffle has a [default gas limit](https://github.com/EthWorks/Waffle/blob/3.0.2/waffle-cli/src/deployContract.ts#L4-L7) of 4 million gas for contract deployment transactions, which is normally too low. - -Please, make sure you import them from the `waffle` field of the [Hardhat Runtime Environment](../advanced/hardhat-runtime-environment.md). It is a version of Waffle adapted to work well with Hardhat. - -::: - -Also, you don't need to call `chai.use`. This initialization is already handled by `@nomiclabs/hardhat-waffle`. Just be sure to include `require("@nomiclabs/hardhat-waffle");` in your Hardhat config. - -Finally, instead of initializing a `MockProvider`, just use the plugin's provider like this: - -```js -const { waffle } = require("hardhat"); -const provider = waffle.provider; -``` - -Run your tests with `npx hardhat test` and you should get stack traces when a transaction fails. diff --git a/docs/src/content/hardhat-runner/docs/reference/_dirinfo.yaml b/docs/src/content/hardhat-runner/docs/reference/_dirinfo.yaml deleted file mode 100644 index 0fddad6ee8..0000000000 --- a/docs/src/content/hardhat-runner/docs/reference/_dirinfo.yaml +++ /dev/null @@ -1,5 +0,0 @@ -section-type: group -section-title: Reference -order: - - /stability-guarantees - - /solidity-support diff --git a/docs/src/content/hardhat-runner/docs/reference/solidity-support.md b/docs/src/content/hardhat-runner/docs/reference/solidity-support.md deleted file mode 100644 index 39516b2ded..0000000000 --- a/docs/src/content/hardhat-runner/docs/reference/solidity-support.md +++ /dev/null @@ -1,51 +0,0 @@ -# Solidity support - -Hardhat Network has first-class Solidity support. It always knows which smart contracts are being run, what exactly they do, and why they fail, making smart contract development easier. - -To do these kinds of things, Hardhat integrates very deeply with Solidity, which means that new versions of it aren't automatically supported. - -This section of the docs explains which versions are supported, and what happens if you use an unsupported one. - -## Supported versions - -These are the versions of Solidity that you can expect to fully work with Hardhat: - -- Any 0.5.x version starting from 0.5.1 -- Any 0.6.x version -- Any 0.7.x version -- Any 0.8.x version up to and including 0.8.18 - -We recommend against using Hardhat with newer, unsupported versions of Solidity. But if you need to do so; please read on. - -### Using an unsupported version - -When running an unsupported version of Solidity, our integration may not work or behave incorrectly. - -This could mean that Solidity stack traces stop working, are incorrect, or incomplete. It could also mean that `console.log` stops working. - -Despite these features possibly being affected, the compilation and execution of your smart contracts won't be affected. You can still trust your test results and deploy smart contracts, but Hardhat may be less useful in the process. - -## Support for IR-based codegen - -The solc compiler has a newer, alternative way of generating bytecode through an [intermediate representation](https://docs.soliditylang.org/en/latest/ir-breaking-changes.html). This mode of compilation can be enabled with the `viaIR` setting. - -At the moment, this option only works well [when the optimizer is enabled](https://github.com/ethereum/solidity/issues/12533). Since Hardhat works much better when the optimizer is disabled, we don't completely support the `viaIR` option yet. You can still enable it to compile your contracts and run your tests, but things like stack traces might not work correctly. - -If you use the `viaIR` option, we recommend you set the [optimization step sequence](https://docs.soliditylang.org/en/v0.8.17/yul.html#optimization-step-sequence) to `"u"`, to make Hardhat work as well as possible: - -``` -solidity: { - version: "0.8.17", // any version you want - settings: { - viaIR: true, - optimizer: { - enabled: true, - details: { - yulDetails: { - optimizerSteps: "u", - }, - }, - }, - }, -} -``` diff --git a/docs/src/content/hardhat-runner/docs/reference/stability-guarantees.md b/docs/src/content/hardhat-runner/docs/reference/stability-guarantees.md deleted file mode 100644 index d925abdda2..0000000000 --- a/docs/src/content/hardhat-runner/docs/reference/stability-guarantees.md +++ /dev/null @@ -1,26 +0,0 @@ -# Stability guarantees - -Hardhat doesn't follow semver strictly, but it still aims to be a stable and easy-to-use platform, and we won't introduce breaking changes without notice. Instead, we may introduce breaking changes in some minor versions. - -Those breaking changes are part of these categories: - -- Changing the default config of Hardhat Network -- Dropping support for unmaintained Node.js versions - -## Hardhat Network default config - -Hardhat Network should closely resemble Ethereum Mainnet by default. Given that Ethereum does introduce breaking changes in the form of hardforks or network upgrades, we need to do the same with its default config. For example, we would eventually change the default `hardfork` config field in the network `hardhat`. - -We will only introduce these changes when a hardfork activates on Mainnet. This will be introduced in a minor version that changes the default `hardfork`, but will also modify other fields, like `blockGasLimit`, to match those of Mainnet. - -## Node.js versions support - -Hardhat supports every currently maintained LTS Node.js version, up to two months after its end-of-life. After that period of time, we will stop testing against it, and print a warning when trying to use it. At that point, we will release a new minor version. - -We recommend running Hardhat using the current LTS Node.js version. You can learn about it [here](https://nodejs.org/en/about/releases/). - -## How to avoid the breaking changes introduced by Hardhat - -In general, there's no need to avoid them. Using Hardhat with any actively maintained Node.js version means that you'd be running with defaults that closely resemble Ethereum Mainnet. - -If you want to play extra-safe, and make sure your project will continue running years down the road using the same Node.js version, please install Hardhat using a [tilde range](https://docs.npmjs.com/cli/v6/using-npm/semver#tilde-ranges-123-12-1). diff --git a/docs/src/content/hardhat-runner/docs/supporter-guides/_dirinfo.yaml b/docs/src/content/hardhat-runner/docs/supporter-guides/_dirinfo.yaml deleted file mode 100644 index a524a210d2..0000000000 --- a/docs/src/content/hardhat-runner/docs/supporter-guides/_dirinfo.yaml +++ /dev/null @@ -1,5 +0,0 @@ -section-type: group -section-title: Supporter guides -order: - - title: Working with oracles - href: /oracles diff --git a/docs/src/content/hardhat-runner/docs/supporter-guides/oracles.md b/docs/src/content/hardhat-runner/docs/supporter-guides/oracles.md deleted file mode 100644 index 4a1c7e90ca..0000000000 --- a/docs/src/content/hardhat-runner/docs/supporter-guides/oracles.md +++ /dev/null @@ -1,229 +0,0 @@ ---- -title: Oracles -description: Oracles help get real-world data into your Ethereum application because smart contracts can't query real-world data on their own. ---- - -# Working with blockchain oracles - -_This guide is based on the [ethereum.org oracles guide](https://ethereum.org/en/developers/docs/oracles)_ - -Oracles provide a bridge between the real-world and on-chain smart contracts by being a source of data that smart contracts can rely on, and act upon. - -Oracles play a critical role in facilitating the full potential of smart contract utility. Without a reliable connection to real-world data, smart contracts cannot effectively serve the real-world. - - - -## Why are they needed? - -With a blockchain like Ethereum, you need every node in the network to replay every transaction and end up with the same result, guaranteed. APIs introduce potentially variable data. If you were sending ETH based on an agreed $USD value using a price API, the query would return a different result from one day to the next. Not to mention, the API could be hacked or deprecated. If this happens, the nodes in the network wouldn't be able to agree on Ethereum's current state, effectively breaking [consensus](https://ethereum.org/developers/docs/consensus-mechanisms/). - -Oracles solve this problem by posting the data on the blockchain. So any node replaying the transaction will use the same immutable data that's posted for all to see. To do this, an oracle is typically made up of a smart contract and some off-chain components that can query APIs, then periodically send transactions to update the smart contract's data. - -## The oracle problem - -As we mentioned, blockchain transactions cannot access off-chain data directly. At the same time, relying on a single source of truth to provide data is insecure and invalidates the decentralization of a smart contract. This is known as the oracle problem. - -We can avoid the oracle problem by using a decentralized oracle network, which pulls data from multiple sources; if one data source is hacked or fails, the smart contract will still function as intended. - -## Security - -An oracle is only as secure as its data source(s). If a dapp uses Uniswap as an oracle for its ETH/DAI price feed, an attacker can move the price on Uniswap to manipulate the dapp's understanding of the current price. An example of how to combat this is [a feed system](https://developer.makerdao.com/feeds/) like the one used by MakerDAO, which collates price data from many external price feeds instead of just relying on a single source. - -## Architecture - -This is an example of simple Oracle architecture, however, there are more ways to trigger off-chain computation. - -1. Emit a log with your [smart contract event](https://ethereum.org/developers/docs/smart-contracts/anatomy/#events-and-logs) -2. An off-chain service has subscribed (usually using something like the JSON-RPC `eth_subscribe` command) to these specific logs. -3. The off-chain service proceeds to do some tasks as defined by the log. -4. The off-chain service responds with the data requested in a secondary transaction to the smart contract. - -This is how to get data in a 1 to 1 manner, however to improve security you may want to decentralize how you collect your off-chain data. - -## Getting Price Data - -Below is an example of how you can retrieve the latest ETH price in your smart contract using a Chainlink price feed on Goerli: - -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.7; - -import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; - -contract PriceConsumerV3 { - - AggregatorV3Interface internal priceFeed; - - /** - * Network: Goerli - * Aggregator: ETH/USD - * Address: 0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e - */ - constructor() { - priceFeed = AggregatorV3Interface(0xD4a33860578De61DBAbDc8BFdb98FD742fA7028e); - } - - /** - * Returns the latest price - */ - function getLatestPrice() public view returns (int) { - (int price) = priceFeed.latestRoundData(); - return price; - } -} - -``` - -## Randomness - -Randomness in computer systems, especially on blockchains, is challenging to achieve because general-purpose blockchains like Ethereum do not have inherent randomness. Another problem is the public nature of blockchain technology which makes finding a secure source of entropy difficult. Almost any mechanism of generating on-chain randomness using Solidity is vulnerable to [MEV attacks](https://ethereum.org/en/developers/docs/mev/). - -It is possible to generate the random value off-chain and send it on-chain, but doing so imposes high trust requirements on users. They must believe the value was truly generated via unpredictable mechanisms and wasn’t altered in transit. - -Oracles designed for off-chain computation solve this problem by securely generating random outcomes off-chain that they broadcast on-chain along with cryptographic proofs attesting to the unpredictability of the process. An example is Chainlink VRF (Verifiable Random Function), which is a provably-fair and verifiable source of randomness designed for smart contracts. Smart contract developers can use Chainlink VRF as a tamper-proof random number generation (RNG) to build smart contracts for any applications which rely on unpredictable outcomes: - -- Blockchain games and NFTs -- Random assignment of duties and resources (e.g. randomly assigning judges to cases) -- Choosing a representative sample for consensus mechanisms - -Random numbers are difficult because blockchains are deterministic. - -To start with Chainlink VRF, create a new `VRFv2Consumer.sol` smart contract, which you can get from the [Official Chainlink Documentation](https://docs.chain.link/vrf/v2/subscription/examples/get-a-random-number). - -Usually, you will create and manage your subscriptions on the [VRF Subscription Management](https://vrf.chain.link/) page, but with the [`@chainlink/hardhat-chainlink`](https://www.npmjs.com/package/@chainlink/hardhat-chainlink) plugin, you can automate that process. This plugin will help you to use the Chainlink protocol inside your tests, scripts & tasks. - -You will need to install it by typing: - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm install --save-dev @chainlink/hardhat-chainlink -``` - -::: - -:::tab{value="npm 6"} - -``` -npm install --save-dev @chainlink/hardhat-chainlink -``` - -::: - -:::tab{value="yarn"} - -``` -yarn add --dev @chainlink/hardhat-chainlink -``` - -::: - -:::: - -And import it inside the `hardhat.config` file: - -::::tabsgroup{options="TypeScript,JavaScript"} - -:::tab{value="TypeScript"} - -```ts -import "@chainlink/hardhat-chainlink"; -``` - -::: - -:::tab{value="JavaScript"} - -```js -require("@chainlink/hardhat-chainlink"); -``` - -::: - -:::: - -Then you can just expand the deployment script which will deploy the above `VRFv2Consumer` smart contract and do the VRF Managment part. - -To do so, first prepare the `hardhat.config` file for the deployment on the Goerli network: - -```ts - networks: { - goerli: { - url: GOERLI_RPC_URL, - accounts: [PRIVATE_KEY] - } - } -``` - -And after that, expand your deployment script: - -```ts -// scripts/deploy.ts -import { chainlink, ethers } from "hardhat"; - -async function main() { - // NOTE: If you already have an active VRF Subscription, proceed to step 3 - - // Step 1: Create a new VRF Subscription - const vrfCoordinatorAddress = `0x2Ca8E0C643bDe4C2E08ab1fA0da3401AdAD7734D`; - const { subscriptionId } = await chainlink.createVrfSubscription( - vrfCoordinatorAddress - ); - - // Step 2: Fund VRF Subscription - const linkTokenAddress = `0x326C977E6efc84E512bB9C30f76E30c160eD06FB`; - const amountInJuels = ethers.BigNumber.from(`1000000000000000000`); // 1 LINK - await chainlink.fundVrfSubscription( - vrfCoordinatorAddress, - linkTokenAddress, - amountInJuels, - subscriptionId - ); - - // Step 3: Deploy your smart contract - const VRFv2ConsumerFactory = await ethers.getContractFactory("VRFv2Consumer"); - const VRFv2Consumer = await VRFv2ConsumerFactory.deploy(subscriptionId); - await VRFv2Consumer.deployed(); - console.log("VRFv2Consumer deployed to:", VRFv2Consumer.address); - - // Step 4: Add VRF Consumer contract to your VRF Subscription - await chainlink.addVrfConsumer( - vrfCoordinatorAddress, - VRFv2Consumer.address, - subscriptionId - ); -} - -main().catch((error) => { - console.error(error); - process.exitCode = 1; -}); -``` - -Finnaly, run the deployment script by typing: - -```sh -npx hardhat run scripts/deploy.ts --network goerli -``` - -## Use blockchain oracles - -There are multiple oracle applications you can integrate into your dapp: - -- [Chainlink](https://chain.link/) - _Chainlink decentralized oracle networks provide tamper-proof inputs, outputs, and computations to support advanced smart contracts on any blockchain._ - -- [Witnet](https://witnet.io/) - _Witnet is a permissionless, decentralized, and censorship-resistant oracle helping smart contracts to react to real world events with strong crypto-economic guarantees._ - -- [UMA Oracle](https://umaproject.org/products/optimistic-oracle) - _UMA's optimistic oracle allows smart contracts to quickly and receive any kind of data for different applications, including insurance, financial derivatives, and prediction market._ - -- [Tellor](https://tellor.io/) - _Tellor is a transparent and permissionless oracle protocol for your smart contract to easily get any data whenever it needs it._ - -- [Band Protocol](https://bandprotocol.com/) - _Band Protocol is a cross-chain data oracle platform that aggregates and connects real-world data and APIs to smart contracts._ - -- [Provable](https://provable.xyz/) - _Provable connects blockchain dapps with any external Web API and leverages TLSNotary proofs, Trusted Execution Environments (TEEs), and secure cryptographic primitives to guarantee data authenticity._ - -- [Paralink](https://paralink.network/) - _Paralink provides an open source and decentralized oracle platform for smart contracts running on Ethereum and other popular blockchains._ - -- [Dos.Network](https://dos.network/) - _DOS Network is a decentralized oracle service network to boost blockchain usability with real-world data and computation power._ diff --git a/docs/src/content/hardhat-runner/docs/troubleshooting/_dirinfo.yaml b/docs/src/content/hardhat-runner/docs/troubleshooting/_dirinfo.yaml deleted file mode 100644 index 32f25f8493..0000000000 --- a/docs/src/content/hardhat-runner/docs/troubleshooting/_dirinfo.yaml +++ /dev/null @@ -1,7 +0,0 @@ -section-type: group -section-title: Troubleshooting -order: - - /verbose-logging - - /common-problems - - href: /../errors - title: Error codes diff --git a/docs/src/content/hardhat-runner/docs/troubleshooting/common-problems.md b/docs/src/content/hardhat-runner/docs/troubleshooting/common-problems.md deleted file mode 100644 index 56eecfe38a..0000000000 --- a/docs/src/content/hardhat-runner/docs/troubleshooting/common-problems.md +++ /dev/null @@ -1,21 +0,0 @@ -# Common problems - -This section describes common problems with working with Hardhat and how to solve them. - -## Out of memory errors when compiling large projects - -If your project has lots of smart contracts, compiling them may require more memory than what Node allows by default and crash. - -If you are experiencing this problem, you can use Hardhat's `--max-memory` argument: - -``` -npx hardhat --max-memory 4096 compile -``` - -If you find yourself using this all the time, you can set it with an environment variable in your `.bashrc` (if using bash) or `.zshrc` (if using zsh): `export HARDHAT_MAX_MEMORY=4096`. - -## Using Hardhat with a proxy server - -Hardhat supports the `http_proxy` environment variable. When this variable is set, Hardhat will send its requests through the given proxy for things like JSON-RPC requests, mainnet forking and downloading compilers. - -There's also support for the `no_proxy` variable, which accepts a comma separated list of hosts or `"*"`. Any host included in this list will not be proxied. Note that requests to `"localhost"` or `"127.0.0.1"` are never proxied. diff --git a/docs/src/content/hardhat-runner/docs/troubleshooting/verbose-logging.md b/docs/src/content/hardhat-runner/docs/troubleshooting/verbose-logging.md deleted file mode 100644 index af6da93289..0000000000 --- a/docs/src/content/hardhat-runner/docs/troubleshooting/verbose-logging.md +++ /dev/null @@ -1,50 +0,0 @@ -# Verbose logging - -You can enable Hardhat's verbose mode by running it with its `--verbose` flag, or by setting the `HARDHAT_VERBOSE` environment variable to `true`. - -This mode will print a lot of output that can be super useful for debugging. An example of a Hardhat run in verbose mode is: - -``` -$ npx hardhat test --verbose - hardhat:core:hre Creating HardhatRuntimeEnvironment +0ms - hardhat:core:hre Running task test +93ms - hardhat:core:hre Running task compile +1ms - hardhat:core:hre Running task compile:get-compilation-tasks +0ms - hardhat:core:hre Running task compile:solidity +0ms - hardhat:core:hre Running task compile:solidity:get-source-paths +0ms - hardhat:core:hre Running task compile:solidity:get-source-names +9ms - hardhat:core:hre Running task compile:solidity:get-dependency-graph +4ms - hardhat:core:hre Running task compile:solidity:get-compilation-jobs +10ms - hardhat:core:tasks:compile The dependency graph was dividied in '1' connected components +0ms - hardhat:core:hre Running task compile:solidity:get-compilation-job-for-file +1ms - hardhat:core:compilation-job File '/tmp/hardhat-project/contracts/Greeter.sol' will be compiled with version '0.7.3' +0ms - hardhat:core:compilation-job File '/tmp/hardhat-project/node_modules/hardhat/console.sol' added as dependency of '/tmp/hardhat-project/contracts/Greeter.sol' +0ms - hardhat:core:hre Running task compile:solidity:get-compilation-job-for-file +13ms - hardhat:core:compilation-job File '/tmp/hardhat-project/node_modules/hardhat/console.sol' will be compiled with version '0.7.3' +1ms - hardhat:core:hre Running task compile:solidity:handle-compilation-jobs-failures +1ms - hardhat:core:hre Running task compile:solidity:filter-compilation-jobs +0ms - hardhat:core:tasks:compile '1' jobs were filtered out +15ms - hardhat:core:hre Running task compile:solidity:merge-compilation-jobs +1ms - hardhat:core:hre Running task compile:solidity:compile-jobs +1ms - hardhat:core:tasks:compile No compilation jobs to compile +1ms - hardhat:core:hre Running task compile:solidity:log:nothing-to-compile +0ms - hardhat:core:hre Running task compile:solidity:log:compilation-result +6ms - hardhat:core:hre Running task test:get-test-files +1ms - hardhat:core:hre Running task test:setup-test-environment +0ms - hardhat:core:hre Running task test:show-fork-recommendations +0ms - hardhat:core:hre Running task test:run-mocha-tests +0ms - - - Greeter - hardhat:core:hre Creating provider for network hardhat +78ms -Deploying a Greeter with greeting: Hello, world! -Changing greeting from 'Hello, world!' to 'Hola, mundo!' - ✓ Should return the new greeting once it's changed (769ms) - - - 1 passing (771ms) - - hardhat:core:cli Killing Hardhat after successfully running task test +0ms -``` - -Hardhat uses the [debug](https://github.com/visionmedia/debug) package to manage logging. The `DEBUG` environment variable can be used to turn on the verbose logging and filter it using a simple wildcard pattern. diff --git a/docs/src/content/hardhat-runner/plugins/_dirinfo.yaml b/docs/src/content/hardhat-runner/plugins/_dirinfo.yaml deleted file mode 100644 index 1728c8daff..0000000000 --- a/docs/src/content/hardhat-runner/plugins/_dirinfo.yaml +++ /dev/null @@ -1,18 +0,0 @@ -section-type: plugins -section-title: Plugins -order: - - "@nomicfoundation/hardhat-toolbox" - - "@nomicfoundation/hardhat-chai-matchers" - - "@nomiclabs/hardhat-ethers" - - "@nomicfoundation/hardhat-verify" - - "@nomicfoundation/hardhat-foundry" - - "@nomiclabs/hardhat-vyper" - - "@nomiclabs/hardhat-solhint" - - "@nomiclabs/hardhat-solpp" - - "@nomiclabs/hardhat-waffle" - - "@nomiclabs/hardhat-web3" - - "@nomiclabs/hardhat-truffle5" - - "@nomiclabs/hardhat-web3-legacy" - - "@nomiclabs/hardhat-truffle4" - - title: Community plugins - href: /hardhat-runner/plugins/#community-plugins diff --git a/docs/src/content/hardhat-runner/plugins/index.md b/docs/src/content/hardhat-runner/plugins/index.md deleted file mode 100644 index c627933b83..0000000000 --- a/docs/src/content/hardhat-runner/plugins/index.md +++ /dev/null @@ -1,3 +0,0 @@ -Plugins are the backbone of Hardhat, and they're built using the same config API that you use in your Hardhat configuration. Read the [Building plugins](/advanced/building-plugins) guide to learn how to create your own, and [send a pull request](https://github.com/NomicFoundation/hardhat/blob/main/docs/src/content/hardhat-runner/plugins/plugins.ts#L9) to get it listed here. - -Extend Hardhat's functionality with the plugins below. diff --git a/docs/src/content/hardhat-runner/plugins/plugins.ts b/docs/src/content/hardhat-runner/plugins/plugins.ts deleted file mode 100644 index 435cf481ea..0000000000 --- a/docs/src/content/hardhat-runner/plugins/plugins.ts +++ /dev/null @@ -1,881 +0,0 @@ -// This list of plugins is automatically sorted by the numbers of downloads -// that the plugin got on npm in the last 30 days. Please add yourself to the -// bottom of the list. -// -// If your plugin's `name` is not it's package name, you can add an optional -// `npmPackage` field. -import { IPlugin } from "../../../model/types"; - -const communityPlugins: IPlugin[] = [ - { - name: "hardhat-deploy", - author: "Ronan Sandford", - authorUrl: "https://github.com/wighawag", - description: "Hardhat plugin for Deployments", - tags: ["Deployment", "Testing"], - }, - { - name: "hardhat-preprocessor", - author: "Ronan Sandford", - authorUrl: "https://github.com/wighawag", - description: - "An hardhat plugin to pre-process contract source code before compilation", - tags: ["Solidity", "Preprocessor"], - }, - { - name: "hardhat-deploy-ethers", - author: "Ronan Sandford", - authorUrl: "https://github.com/wighawag", - description: "A hardhat-deploy plugin for Ethers.js v5", - tags: ["Ethers.js", "hardhat-deploy"], - }, - { - name: "@openzeppelin/hardhat-upgrades", - author: "OpenZeppelin", - authorUrl: "https://openzeppelin.com", - description: - "Hardhat plugin for deploying and managing upgradeable contracts.", - tags: ["Security", "Upgrades", "OpenZeppelin"], - }, - { - name: "hardhat-forta", - author: "Forta", - authorUrl: "https://forta.org/", - description: - "Quickly add security and operational alerting for your project using Forta: a decentralized monitoring network for Web3 systems.", - tags: ["Security", "Monitoring", "Alerting", "Forta"], - }, - { - name: "@kriptonio/hardhat-kriptonio", - author: "Kriptonio", - authorUrl: "https://kriptonio.com/", - description: - "This plugin allows you to upload compiled hardhat smart contract artifacts to Kriptonio. On kriptonio side new smart contract will be created with attached artifacts, which you can afterward deploy and manage via kriptonio.", - tags: ["Monitoring", "Debugging", "Deployment"], - }, - { - name: "@tenderly/hardhat-tenderly", - author: "Tenderly", - authorUrl: "https://tenderly.co/", - description: - "Easily integrate your Hardhat project with Tenderly. Tenderly is an Ethereum monitoring, debugging and analytics platform.", - tags: ["Debuggin", "Monitoring", "Alerting", "Tasks", "Scripts"], - }, - { - name: "hardhat-ethernal", - author: "Ethernal", - authorUrl: "https://www.tryethernal.com", - description: - "Integrate your Hardhat project and Hardhat network with Ethernal. Ethernal is a block explorer for private chains.", - tags: ["explorer", "debugging", "development-tool"], - }, - { - name: "@typechain/hardhat", - author: "Rahul Sethuram", - authorUrl: "https://twitter.com/rhlsthrm", - description: "Zero-config TypeChain support for Hardhat.", - tags: ["Testing", "Tasks"], - }, - { - name: "hardhat-spdx-license-identifier", - author: "Nick Barry", - authorUrl: "https://github.com/ItsNickBarry", - description: - "Automatically prepend local Solidity source files with an SPDX License Identifier", - tags: ["License"], - }, - { - name: "hardhat-abi-exporter", - author: "Nick Barry", - authorUrl: "https://github.com/ItsNickBarry", - description: "Automatically export Solidity contract ABIs on compilation", - tags: ["Compiling", "ABI"], - }, - { - name: "hardhat-contract-sizer", - author: "Nick Barry", - authorUrl: "https://github.com/ItsNickBarry", - description: "Calculate compiled contract sizes", - tags: ["Compiling", "Bytecode"], - }, - { - name: "hardhat-log-remover", - author: "Nick Barry", - authorUrl: "https://github.com/ItsNickBarry", - description: - "Remove Hardhat console.log imports and calls from Solidity source files", - tags: ["Logging", "Console", "Deployment"], - }, - { - name: "hardhat-dependency-compiler", - author: "Nick Barry", - authorUrl: "https://github.com/ItsNickBarry", - description: "Compile Solidity sources directly from npm dependencies", - tags: ["Compiling", "Dependencies"], - }, - { - name: "hardhat-docgen", - author: "Nick Barry, samuveth", - authorUrl: "https://github.com/ItsNickBarry", - description: "Generate a static documentation site from NatSpec comments", - tags: ["Documentation", "NatSpec"], - }, - { - name: "@solidstate/hardhat-4byte-uploader", - author: "Nick Barry", - authorUrl: "https://github.com/ItsNickBarry", - description: - "Upload local function selectors to the Ethereum Selector Database", - tags: ["Bytecode", "ABI"], - }, - { - name: "@solidstate/hardhat-test-short-circuit", - author: "Nick Barry", - authorUrl: "https://github.com/ItsNickBarry", - description: - "Stop Hardhat test execution on demand and print output from completed tests", - tags: ["Testing", "Mocha"], - }, - { - name: "@solidstate/hardhat-txn-dot-xyz", - author: "Nick Barry", - authorUrl: "https://github.com/ItsNickBarry", - description: "Generate and execute on-chain transactions via txn.xyz", - tags: ["Signing", "Scripts"], - }, - { - name: "@solidstate/hardhat-bytecode-exporter", - author: "Nick Barry", - authorUrl: "https://github.com/ItsNickBarry", - description: "Automatically export contract bytecode on compilation", - tags: ["Bytecode", "Compiling"], - }, - { - name: "@solidstate/hardhat-accounts", - author: "Nick Barry", - authorUrl: "https://github.com/ItsNickBarry", - description: "Output list of available accounts and their balances", - tags: ["Accounts", "Balances"], - }, - { - name: "hardhat-watcher", - author: "Xander Deseyn", - authorUrl: "https://github.com/N1ghtly", - description: "Automatically run Hardhat actions on file changes.", - tags: ["Tasks", "Testing"], - }, - { - name: "solidity-coverage", - author: "Chris Gewecke", - authorUrl: "https://github.com/cgewecke", - description: "Code coverage for Solidity", - tags: ["Testing", "Coverage", "Hardhat plugin"], - }, - { - name: "hardhat-gas-trackooor", - author: "d3or", - authorUrl: "https://github.com/d3or", - description: "Simple plugin to track gas on the transaction level.", - tags: ["Testing", "Gas", "Hardhat plugin"], - }, - { - name: "hardhat-gas-reporter", - author: "Chris Gewecke", - authorUrl: "https://github.com/cgewecke", - description: - "Gas usage per unit test. Average gas usage per method. A mocha reporter.", - tags: ["Testing", "Gas", "Hardhat plugin"], - }, - { - name: "hardhat-erc1820", - author: "David Mihal", - authorUrl: "https://twitter.com/dmihal", - description: - "Automatically deploy the ERC-1820 registry contract to Hardhat EVM chains.", - tags: ["Testing"], - }, - { - name: "hardhat-local-networks-config-plugin", - author: "Facu Spagnuolo", - authorUrl: "https://twitter.com/facuspagnuolo", - description: - "Allow loading network configs for Hardhat projects in home file", - tags: ["Networks", "Config"], - }, - { - name: "@eth-optimism/plugins/hardhat/compiler", - npmPackage: "@eth-optimism/plugins", - author: "Optimism", - authorUrl: "https://github.com/ethereum-optimism", - description: - "Automatically compiles your Solidity contracts with the OVM compiler.", - tags: ["Optimism", "Solidity", "Compiler", "OVM"], - }, - { - name: "@eth-optimism/plugins/hardhat/ethers", - npmPackage: "@eth-optimism/plugins", - author: "Optimism", - authorUrl: "https://github.com/ethereum-optimism", - description: "Integrates Hardhat and ethers.js with Optimism's L2 network.", - tags: ["Optimism", "ethers.js", "OVM"], - }, - { - name: "hardhat-react", - npmPackage: "@symfoni/hardhat-react", - author: "Symfoni", - authorUrl: "https://github.com/symfoni/", - description: - "A Hardhat plugin that generates a React hook component from your smart contracts. Hot reloaded into your React app. Deployed or not deployed. And everything typed and initialized.", - tags: ["Ethers", "React", "Deploy", "Typechain", "Frontend", "Web3modal"], - }, - { - name: "hardhat-etherscan-abi", - author: "Roman Semenov", - authorUrl: "https://github.com/poma", - description: "Automatically fetch contract ABI from Etherscan", - tags: ["Etherscan", "ABI"], - }, - { - name: "hardhat-tracer", - author: "Soham Zemse", - authorUrl: "https://github.com/zemse/", - description: - "See internal transactions, events and storage operations during your hardhat tests in the console", - tags: ["EVM", "Events", "Logs", "Trace", "Console", "Testing"], - }, - { - name: "hardhat-circom", - author: "Project Sophon", - authorUrl: "https://github.com/projectsophon", - description: "Provide tasks to integrate Circom and SnarkJS", - tags: [ - "Circom", - "Snarkjs", - "Preprocessor", - "Compiling", - "Tasks", - "Scripts", - ], - }, - { - name: "hardhat-storage-layout", - author: "Aurora Labs", - authorUrl: "https://github.com/aurora-is-near", - description: "Exporting solidity contract storage layout", - tags: ["solidity", "storage-layout"], - }, - { - name: "hardhat-change-network", - author: "David Mihal", - authorUrl: "https://github.com/dmihal", - description: "Allows changing the current network in Hardhat.", - tags: ["Testing"], - }, - { - name: "hardhat-packager", - author: "Paul Razvan Berg", - authorUrl: "https://github.com/paulrberg", - description: - "Prepare the contract artifacts and the TypeChain bindings for registry deployment.", - tags: ["Deployment", "Tasks", "TypeChain"], - }, - { - name: "hardhat-time-n-mine", - npmPackage: "@atixlabs/hardhat-time-n-mine", - author: "Gonzalo Petraglia & Alan Verbner", - authorUrl: "https://github.com/atixlabs", - description: - "Helper plugin to manipulate blocks timestamp and trigger mining. It can be used from the command line and in the tests.", - tags: ["Testing"], - }, - { - name: "hardhat-proxy", - author: "Jinyang Liu", - authorUrl: "https://github.com/jinyang1994", - description: - "This plugin brings the proxy contract to Hardhat, which allows you to manage the proxy contract in a simple way.", - tags: ["Proxy Contract", "Tasks", "Scripts"], - }, - { - name: "hardhat-fund-link", - author: "Applied Blockchain", - npmPackage: "@appliedblockchain/chainlink-plugins-fund-link", - authorUrl: "https://github.com/appliedblockchain", - description: "Transfers Link token amount between accounts.", - tags: ["Chainlink", "Link"], - }, - { - name: "@defi-wonderland/smock", - author: "DeFi Wonderland and Optimism PBC", - authorUrl: "https://github.com/defi-wonderland", - description: - "The Solidity mocking library. Smock is a utility package that can generate mock Solidity contracts written entirely in JavaScript.", - tags: ["Testing", "Mocking"], - }, - { - name: "xdeployer", - author: "Pascal Marco Caversaccio", - authorUrl: "https://github.com/pcaversaccio", - description: - "Hardhat plugin to deploy your smart contracts across multiple EVM chains with the same deterministic address.", - tags: ["Deployment", "CREATE2", "Tasks"], - }, - { - name: "@tovarishfin/hardhat-yul", - author: "tovarishfin", - authorUrl: "https://codylamson.com", - description: - "An updated and working Hardhat plugin to compile the Yul and Yul+ languages into solc compatible artifacts. Works with .yul and .yulp file extensions", - tags: ["Yul", "Assembly", "Compiler", "Yul+"], - }, - { - name: "@controlcpluscontrolv/hardhat-yul", - author: "ControlCplusControlV", - authorUrl: "https://github.com/controlCplusControlV/", - description: - "Hardhat plugin to compile the Yul and Yul+ languages into solc compatible artifacts. Works with .yul and .yulp file extensions", - tags: ["Yul", "Assembly", "Compiler", "Yul+"], - }, - { - name: "@primitivefi/hardhat-dodoc", - author: "Primitive", - authorUrl: "https://github.com/primitivefinance/primitive-dodoc", - description: - "Zero-config Hardhat plugin to generate documentation for all your Solidity contracts.", - tags: ["Documentation", "Docs", "Solidity", "NatSpec"], - }, - { - name: "hardhat-output-validator", - author: "Indeavr", - authorUrl: "https://github.com/indeavr", - description: - "Zero-config Hardhat plugin to check the output of the compiler for any problems like missing NatSpec", - tags: [ - "Productivity", - "CI", - "Compiler", - "Docs", - "Solidity", - "NatSpec", - "Build", - ], - }, - { - name: "@ericxstone/hardhat-blockscout-verify", - author: "ericxstone", - authorUrl: "https://github.com/ericxstone", - description: - "Hardhat plugin for solidity contract verification on Blockscout block explorer.", - tags: ["Blockscout", "Deployment", "Solidity", "Verification"], - }, - { - name: "@muzamint/hardhat-etherspot", - author: "muzamint", - authorUrl: "https://github.com/muzamint", - description: "Hardhat TypeScript plugin for Etherspot", - tags: ["smart contract wallet"], - }, - { - name: "hardhat-multibaas-plugin", - author: "Curvegrid", - authorUrl: "https://www.curvegrid.com/", - description: "Integrate MultiBaas into Hardhat's workflow!", - tags: ["middleware", "ethereum", "OMG"], - }, - { - name: "@mangrovedao/hardhat-test-solidity", - author: "Mangrove", - authorUrl: "https://mangrove.exchange/", - description: "Hardhat plugin for writing tests in solidity", - tags: ["solidity tests"], - }, - { - name: "@reef-defi/hardhat-reef", - author: "Reef Chain", - authorUrl: "https://reef.io/", - description: - "Hardhat Reef plugin for interacting with contracts on the Reef chain", - tags: ["Reef Chain"], - }, - { - name: "hardhat-diamond-abi", - author: "Project Sophon", - authorUrl: "https://github.com/projectsophon", - description: - "Hardhat plugin to combine multiple ABIs into a Diamond ABI artifact", - tags: ["diamond standard"], - }, - { - name: "@idle-finance/hardhat-proposals-plugin", - author: "Idle Finance", - authorUrl: "https://idle.finance/", - description: "A Hardhat plugin for working with on-chain proposals", - tags: ["governance", "proposals", "simulation"], - }, - { - name: "@shardlabs/starknet-hardhat-plugin", - author: "Shard Labs", - authorUrl: "https://shardlabs.io/", - description: - "A plugin for integrating Starknet tools into Hardhat projects", - tags: ["starknet", "cairo", "layer two"], - }, - { - name: "@uniswap/hardhat-v3-deploy", - author: "Uniswap Labs", - authorUrl: "https://uniswap.org/", - description: "Hardhat plugin for Uniswap V3 deployment", - tags: ["uniswap", "testing", "deployment", "local"], - }, - { - name: "@unlock-protocol/hardhat-plugin", - author: "Unlock Inc", - authorUrl: "http://unlock-protocol.com/", - description: "Hardhat plugin for Unlock Protocol deployments.", - tags: ["unlock", "nft", "memberships", "udt", "testing", "deployment"], - }, - { - name: "hardhat-deploy-tenderly", - author: "Ronan Sandford", - authorUrl: "https://github.com/wighawag", - description: "A plugin to push contracts to tenderly", - tags: ["Deployment", "Testing", "Tenderly", "Verification"], - }, - { - name: "hardhat-laika", - author: "Laika Blockchain Lab", - authorUrl: "https://github.com/laika-lab/hardhat-laika", - description: "Hardhat plugin to sync your compiled contract with Laika", - tags: ["Tasks", "Laika"], - }, - { - name: "hardhat-network-metadata", - author: "Focal Labs Inc.", - authorUrl: "https://github.com/krruzic/hardhat-network-metadata", - description: - "Hardhat plugin to allow adding any extra data to your network configuration", - tags: ["Metadata", "Testing", "Tasks", "Config"], - }, - { - name: "hardhat-exposed", - author: "Francisco Giordano", - authorUrl: "https://github.com/frangio", - description: "Automatically expose internal Solidity functions for testing", - tags: ["Solidity", "Testing"], - }, - { - name: "hardhat-hethers", - author: "LimeChain", - authorUrl: "https://github.com/LimeChain/hardhat-hethers", - description: "Injects hethers into the Hardhat Runtime Environment", - tags: ["Hedera", "hethers"], - }, - { - name: "hardhat-sourcify", - author: "Zoey T", - authorUrl: "https://twitter.com/zzzzoey_t", - description: "A plugin for submitting code to Sourcify", - tags: ["Sourcify", "Verification"], - }, - { - name: "hardhat-awesome-cli", - author: "Marc-Aurele Besner", - authorUrl: "https://github.com/marc-aurele-besner", - description: - "Hardhat made awesome with a flexible CLI to help run tests, scripts, deploy Mock contracts and more.", - tags: ["CLI", "Testing", "Tasks", "Config"], - }, - { - name: "hardhat-test-utils", - author: "Naveen Sahu", - authorUrl: "https://twitter.com/heyNvN", - description: - "Handy set of utilities for testing contracts in Hardhat projects", - tags: ["testing", "solidity"], - }, - { - name: "hardhat-deals", - author: "use less", - authorUrl: "https://github.com/Karuzzzo", - description: "Small hardhat task for debug money transfers 🤝💰", - tags: ["Deployment", "Testing", "Security", "Debug", "helper", "Tasks"], - }, - { - name: "hardhat-contract-dumper", - author: "use less", - authorUrl: "https://github.com/Karuzzzo", - description: - "Another small hardhat task for printing contract's storage layout 📐", - tags: ["Deployment", "Testing", "Security", "Debug", "helper", "Tasks"], - }, - { - name: "@0xweb/hardhat", - author: "Alex Kit", - authorUrl: "https://github.com/tenbits", - description: - "Generate 0xWeb classes for contracts to easily communicate with the blockchain.", - tags: ["dApp-Client", "Class-Generation", "Testing"], - }, - { - name: "jest-environment-hardhat", - author: "Uniswap Labs", - authorUrl: "https://uniswap.org/", - description: "A jest environment with hardhat built in.", - tags: ["uniswap", "testing", "jest", "node"], - }, - { - name: "hardhat-ctf", - author: "Oren Yomtov", - authorUrl: "https://github.com/orenyomtov", - description: "A framework for building solidity CTF challenges.", - tags: ["ctf", "capture-the-flag", "framework", "security", "solidity"], - }, - { - name: "hardhat-contract-prompts", - author: "dbadoy", - authorUrl: "https://github.com/dbadoy", - description: "Build prompt with Solidity code.", - tags: ["solidity", "CLI"], - }, - { - name: "hardhat-address-exporter", - author: "Dennis Zoma", - authorUrl: "https://twitter.com/dennis_zoma", - description: - "Export deployed contract addresses (multichain) in typescript files.", - tags: [ - "solidity", - "vyper", - "deployment", - "typescript", - "addresses", - "monorepo", - "frontend", - ], - }, - { - name: "@graphprotocol/hardhat-graph", - author: "The Graph", - authorUrl: "https://thegraph.com", - description: - "Develop your subgraph side by side with your contracts to save gas and increase productivity.", - tags: ["graphprotocol", "subgraph", "graphql", "development", "deployment"], - }, - { - name: "hardhat-storage-layout-changes", - author: "Soham Zemse", - authorUrl: "https://github.com/zemse/", - description: "Check for storage layout changes", - tags: ["Storage Layout", "Solidity", "Upgradable Contracts"], - }, - { - name: "hardhat-live-fork", - author: "Soham Zemse", - authorUrl: "https://github.com/zemse/", - description: - "Keeps mainnet fork state updated by replaying relevant live txs", - tags: ["Mainnet fork", "live", "transaction replay"], - }, - { - name: "hardhat-ens-mock", - author: "DefiCake", - authorUrl: "https://github.com/DefiCake", - description: - "Overrides ENS ownership in hardhat network to allow orchestration superpowers", - tags: ["ENS", "Testing", "Orchestration", "Productivity"], - }, - { - name: "hardhat-cannon", - author: "Synthetix Core Contributors", - authorUrl: "https://github.com/dbeal-eth", - description: - "Define your project's deployment in a simple manifest, then deploy and share it anywhere. Inspired by Docker, Terraform, and npm. https://usecannon.com/", - tags: ["Tooling", "Deployment", "Testing"], - }, - { - name: "hardhat-etherscan-contract-cloner", - author: "Tuckson", - authorUrl: "https://github.com/TucksonDev", - description: - "Hardhat plugin for cloning verified contracts from any supported network using Etherscan's API.", - tags: ["Etherscan", "Clone", "Smart contract"], - }, - { - name: "hardhat-interact", - author: "Synthetix Core Contributors", - authorUrl: "https://github.com/dbeal-eth", - description: - "Execute commands on deployed contracts on any network using a helpful TUI.", - tags: ["Tooling", "Operations", "Testing"], - }, - { - name: "hardhat-chainlink-plugin", - author: "protofire.io", - authorUrl: "https://protofire.io/", - description: - "Hardhat TypeScript plugin to run a chainlink node and interact with it", - tags: ["ethereum", "smart-contracts", "chainlink", "hardhat-plugin"], - }, - { - name: "huff-deployer", - author: "Rodrigo Herrera", - authorUrl: "https://github.com/rodrigoherrerai", - description: - "A Hardhat Typescript plugin to test and interact with Huff contracts", - tags: ["Deployment", "Tasks", "Huff"], - }, - { - name: "hardhat-gui", - author: "yecandir", - authorUrl: "https://github.com/yecandir", - description: - "Hardhat React Plugin to interact with your deployed contracts", - tags: ["Tooling", "Testing", "ui", "plugin"], - }, - { - name: "hardhat-finder", - author: "Emre Tepe", - authorUrl: "https://emretepedev.github.io/", - description: "Hardhat plugin to get compiler outputs of contracts", - tags: ["Tooling", "Testing", "Tasks", "Scripts", "Solc", "Compiler"], - }, - { - name: "@dlsl/hardhat-migrate", - author: "Distributed Lab", - authorUrl: "https://distributedlab.com/", - description: - "Hardhat plugin to automate the deployment and verification of contracts", - tags: ["Deployment", "Verification", "Migration"], - }, - { - name: "hardhat-notifier", - author: "Mister Singh", - authorUrl: "https://www.npmjs.com/package/hardhat-notifier", - description: - "Hardhat plugin to send an OSX notification when hardhat compilcation fails/succeeds", - tags: ["Deployment", "Tooling", "Notification", "Compile"], - }, - { - name: "hardhat-jest", - author: "Arian Hosseini", - authorUrl: "https://www.npmjs.com/package/hardhat-jest", - description: "Hardhat plugin that allows you to use Jest easily", - tags: ["Deployment", "Testing", "Jest", "Smart Contracts", "Solidity"], - }, - { - name: "@dlsl/hardhat-gobind", - author: "Distributed Lab", - authorUrl: "https://distributedlab.com/", - description: - "Hardhat plugin to generate smart contract bindings for Golang", - tags: ["Bindings", "Go", "Testing"], - }, - { - name: "hardhat-storage-vault", - author: "Emre Tepe", - authorUrl: "https://emretepedev.github.io/", - description: - "Hardhat plugin to check and lock the storage layout of contracts", - tags: ["Tooling", "Testing", "Storage"], - }, - { - name: "hardhat-insight", - author: "Andres Adjimann", - authorUrl: "https://www.npmjs.com/package/hardhat-insight", - description: - "Hardhat plugin to get contract storage, gas and code size insights using the compiler ast output", - tags: ["Tooling", "Storage", "Gas", "Size", "Bytecode"], - }, - { - name: "hardhat-scilla-plugin", - author: "Saeed Dadkhah", - authorUrl: "https://www.github.com/its-saeed", - description: - "Hardhat plugin to test scilla contracts. Scilla is Zillqa's programming language to develop smart contracts.", - tags: ["Scilla", "Testing", "Zilliqa"], - }, - { - name: "hardhat-flat-exporter", - author: "Laz", - authorUrl: "https://github.com/Saszr", - description: "Export flat contract on compilation via Hardhat.", - tags: ["Flatten", "Smart contract", "Solidity", "Deployment"], - }, - { - name: "@chainlink/hardhat-chainlink", - author: "Chainlink Labs", - authorUrl: "https://github.com/smartcontractkit/hardhat-chainlink", - description: "Integrates Chainlink into Hardhat projects.", - tags: ["chainlink", "hardhat"], - }, - { - name: "@dlsl/hardhat-markup", - author: "Distributed Lab", - authorUrl: "https://distributedlab.com/", - description: - "Hardhat plugin to generate customizable smart contracts documentation", - tags: ["Documentation", "NatSpec", "Markdown"], - }, - { - name: "hardhat-contract-clarity", - author: "Marc-Aurele Besner", - authorUrl: "https://github.com/marc-aurele-besner", - description: - "This Hardhat plugin add 3 tasks to Hardhat, to summarize a smart contract in human readable format using OpenAI GPT-3, to create a readme looking at your package.json and a task to ask question to chatGPT when running into errors.", - tags: ["chatGPT", "openai", "gpt3", "ai"], - }, - { - name: "transaction-retry-tool", - author: "Marc-Aurele Besner", - authorUrl: "https://github.com/marc-aurele-besner", - description: - "This Hardhat plugin provides two tasks and two functions to help you manage and optimize your transactions on Ethereum compatible blockchain. The two tasks include the ability to retry a transaction and retrieve the current gas cost.", - tags: ["transaction", "gasPrice", "retry", "helper"], - }, - { - name: "hardhat-fireblocks", - author: "Fireblocks", - authorUrl: "https://github.com/fireblocks", - description: "Hardhat plugin for integrating with Fireblocks", - tags: ["Deployment", "Security"], - }, - { - name: "hardhat-uniswap-v2-deploy-plugin", - author: "Cyrille Derché", - authorUrl: "https://github.com/onmychain/hardhat-uniswap-v2-deploy-plugin", - description: - "Hardhat plugin for Uniswap V2 (pancakeswap protocol) testing and deployment. You can use it to test features such as pair creation, liquidity provisioning, and swaps.", - tags: ["uniswap", "pancakeswap", "testing", "deployment", "automated"], - }, - { - name: "hardhat-deal", - author: "Rubilmax", - authorUrl: "https://github.com/rubilmax/hardhat-deal", - description: - "Hardhat plugin to ease dealing ERC20 tokens in hardhat forks.", - tags: [ - "erc20", - "deal", - "foundry", - "forge", - "mock", - "balanceOf", - "fork", - "testing", - "tests", - ], - }, - { - name: "@truffle/dashboard-hardhat-plugin", - author: "Truffle", - authorUrl: "https://trufflesuite.com/", - description: - "Enable project-specific features inside Truffle Dashboard, including advanced calldata decoding and more", - tags: ["truffle-dashboard", "transaction", "signing", "decoding"], - }, -]; - -const officialPlugins: IPlugin[] = [ - { - name: "@nomicfoundation/hardhat-toolbox", - author: "Nomic Foundation", - authorUrl: "https://twitter.com/NomicFoundation", - description: "Nomic Foundation's recommended bundle of Hardhat plugins", - tags: ["Hardhat", "Setup"], - }, - { - name: "@nomicfoundation/hardhat-chai-matchers", - author: "Nomic Foundation", - authorUrl: "https://twitter.com/NomicFoundation", - description: "Adds Ethereum-related matchers to Chai", - tags: ["Chai", "Testing"], - }, - { - name: "@nomiclabs/hardhat-ethers", - author: "Nomic Foundation", - authorUrl: "https://twitter.com/NomicFoundation", - description: "Injects ethers.js into the Hardhat Runtime Environment", - tags: ["Ethers.js", "Testing", "Tasks", "Scripts"], - }, - { - name: "@nomicfoundation/hardhat-verify", - author: "Nomic Foundation", - authorUrl: "https://twitter.com/NomicFoundation", - description: "Automatically verify contracts", - tags: ["Etherscan", "Verification"], - }, - { - name: "@nomicfoundation/hardhat-foundry", - author: "Nomic Foundation", - authorUrl: "https://twitter.com/NomicFoundation", - description: - "Makes it easier to use Hardhat and Foundry in the same project", - tags: ["Foundry"], - }, - { - name: "@nomiclabs/hardhat-vyper", - author: "Nomic Foundation", - authorUrl: "https://twitter.com/NomicFoundation", - description: "Adds support to compile Vyper smart contracts", - tags: ["Vyper", "Compiler"], - }, - { - name: "@nomiclabs/hardhat-solhint", - author: "Nomic Foundation", - authorUrl: "https://twitter.com/NomicFoundation", - description: "Easily run solhint to lint your Solidity code", - tags: ["Solhint", "Linter"], - }, - { - name: "@nomiclabs/hardhat-solpp", - author: "Nomic Foundation", - authorUrl: "https://twitter.com/NomicFoundation", - description: - "Automatically run the solpp preprocessor before each compilation", - tags: ["Solpp", "Preprocessor"], - }, - { - name: "@nomiclabs/hardhat-waffle", - author: "Nomic Foundation", - authorUrl: "https://twitter.com/NomicFoundation", - description: - "Adds a Waffle-compatible provider to the Hardhat Runtime Environment and automatically initializes the Waffle Chai matchers", - tags: ["Waffle", "Testing"], - }, - { - name: "@nomiclabs/hardhat-web3", - author: "Nomic Foundation", - authorUrl: "https://twitter.com/NomicFoundation", - description: "Injects Web3 1.x into the Hardhat Runtime Environment", - tags: ["Web3.js", "Testing", "Tasks", "Scripts"], - }, - { - name: "@nomiclabs/hardhat-truffle5", - author: "Nomic Foundation", - authorUrl: "https://twitter.com/NomicFoundation", - description: "Integration with TruffleContract from Truffle 5", - tags: ["Truffle", "Testing"], - }, - { - name: "@nomiclabs/hardhat-web3-legacy", - author: "Nomic Foundation", - authorUrl: "https://twitter.com/NomicFoundation", - description: "Injects Web3 0.20.x into the Hardhat Runtime Environment", - tags: ["Web3.js", "Legacy", "Testing", "Tasks", "Scripts"], - }, - { - name: "@nomiclabs/hardhat-truffle4", - author: "Nomic Foundation", - authorUrl: "https://twitter.com/NomicFoundation", - description: "Integration with TruffleContract from Truffle 4", - tags: ["Truffle", "Testing"], - }, - // Don't add community plugins here. They should be placed in the other array. -]; - -const plugins = { - communityPlugins, - officialPlugins, -}; - -export default plugins; diff --git a/docs/src/content/hardhat-vscode/_dirinfo.yaml b/docs/src/content/hardhat-vscode/_dirinfo.yaml deleted file mode 100644 index 9ec3f9e8a0..0000000000 --- a/docs/src/content/hardhat-vscode/_dirinfo.yaml +++ /dev/null @@ -1 +0,0 @@ -section-type: hidden diff --git a/docs/src/content/hardhat-vscode/docs/_dirinfo.yaml b/docs/src/content/hardhat-vscode/docs/_dirinfo.yaml deleted file mode 100644 index 0c53d7fc7b..0000000000 --- a/docs/src/content/hardhat-vscode/docs/_dirinfo.yaml +++ /dev/null @@ -1,7 +0,0 @@ -section-type: group -section-title: Hardhat VSCode -order: - - title: Overview - href: /overview - - /hardhat-projects - - /formatting diff --git a/docs/src/content/hardhat-vscode/docs/features.md b/docs/src/content/hardhat-vscode/docs/features.md deleted file mode 100644 index ead022319c..0000000000 --- a/docs/src/content/hardhat-vscode/docs/features.md +++ /dev/null @@ -1 +0,0 @@ -# Features diff --git a/docs/src/content/hardhat-vscode/docs/formatting.md b/docs/src/content/hardhat-vscode/docs/formatting.md deleted file mode 100644 index 52b3ae8b73..0000000000 --- a/docs/src/content/hardhat-vscode/docs/formatting.md +++ /dev/null @@ -1,46 +0,0 @@ -# Formatting - -Hardhat for Visual Studio Code provides formatting support for `.sol` files, by leveraging [prettier-plugin-solidity](https://github.com/prettier-solidity/prettier-plugin-solidity). - -## Setting it up as the default Solidity formatter - -If you currently have other solidity extensions installed, or have had previously, they may be set as your default formatter for solidity files. - -To set Hardhat for Visual Studio Code as your default formatter for solidity files: - -1. Within a Solidity file run the _Format Document With_ command, either through the Command Palette, or by right clicking and selecting through the context menu: - - ![Format Document With](/hardhat-vscode-images/format_document_with.png "Format Document With") - -2. Select `Configure Default Formatter...` - - ![Format Document With](/hardhat-vscode-images/configure_default_formatter.png "Configure default formatter") - -3. Select `Hardhat + Solidity` as the default formatter for solidity files - - ![Format Document With](/hardhat-vscode-images/select_solidity_plus_hardhat.png "Confiure default formatter") - -## Formatting Configuration - -The default formatting rules that will be applied are taken from [prettier-plugin-solidity](https://github.com/prettier-solidity/prettier-plugin-solidity#configuration-file), with the exception that `explicitTypes` are preserved (rather than forced). - -To override the settings, add a `prettierrc` configuration file at the root of your project. Add a `*.sol` file override to the prettier configuration file and change from the defaults shown: - -```javascript -// .prettierrc.json -{ - "overrides": [ - { - "files": "*.sol", - "options": { - "printWidth": 80, - "tabWidth": 4, - "useTabs": false, - "singleQuote": false, - "bracketSpacing": false, - "explicitTypes": "preserve" - } - } - ] -} -``` diff --git a/docs/src/content/hardhat-vscode/docs/hardhat-projects.md b/docs/src/content/hardhat-vscode/docs/hardhat-projects.md deleted file mode 100644 index f3d91f4fc5..0000000000 --- a/docs/src/content/hardhat-vscode/docs/hardhat-projects.md +++ /dev/null @@ -1,15 +0,0 @@ -# Hardhat projects support - -Hardhat for Visual Studio Code provides enhanced functionality for Solidity files within a Hardhat project, including inline validation and quick fixes. - -To take advantage of these features, use the `File` menu to `Open Folder`, and select the folder containing the `hardhat.config.{js,ts}` file. - -Inline validation (the display of compiler errors and warnings against the code) is based on your Hardhat configuration file. The version of the `solc` solidity compiler used for validation is set within this file, see the [Hardhat documentation](https://hardhat.org/config/#solidity-configuration) for more details. - -## Monorepo Support - -Hardhat for Visual Studio Code will detect Hardhat projects (folders containing a `hardhat.config.{js,ts}` file) within a monorepo, when the root of the monorepo is opened as a workspace folder. - -The Hardhat config file that is used when validating a Solidity file is shown in the Solidity section on the _Status Bar_: - -![Open Config](/hardhat-vscode-images/open-config.gif "Open Config") diff --git a/docs/src/content/hardhat-vscode/docs/other-components/_dirinfo.yaml b/docs/src/content/hardhat-vscode/docs/other-components/_dirinfo.yaml deleted file mode 100644 index 6cc6cf92f9..0000000000 --- a/docs/src/content/hardhat-vscode/docs/other-components/_dirinfo.yaml +++ /dev/null @@ -1,11 +0,0 @@ -section-type: group -section-title: Other Hardhat components -order: - - href: /../../../hardhat-runner/docs - title: Hardhat Runner - - href: /../../../hardhat-network/docs - title: Hardhat Network - - href: /../../../hardhat-chai-matchers/docs - title: Hardhat Chai Matchers - - href: /../../../hardhat-network-helpers/docs - title: Hardhat Network Helpers diff --git a/docs/src/content/hardhat-vscode/docs/overview.md b/docs/src/content/hardhat-vscode/docs/overview.md deleted file mode 100644 index a00bcf6e03..0000000000 --- a/docs/src/content/hardhat-vscode/docs/overview.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -title: Hardhat for Visual Studio Code -description: Solidity and Hardhat support for Visual Studio Code ---- - -# Hardhat for Visual Studio Code - -[Hardhat for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=NomicFoundation.hardhat-solidity) is a VS Code extension that adds language support for [Solidity](https://soliditylang.org/) and provides editor integration for [Hardhat projects](https://hardhat.org/). Integrations for other tools are coming in the near future. - -Hardhat for Visual Studio code adds the following features: - -- [Code completion](#code-completions) -- [Go to definition, type definition and references](#navigation) -- [Symbol renames](#renames) -- [Solidity code formatting](#format-document) -- [Inline code validation from compiler errors/warnings for Hardhat projects](<#inline-code-validation-(diagnostics)>) -- [Hover help for variables, function calls, errors, events etc.](#hover) -- [Code actions (quickfixes) suggested from compiler errors/warnings for Hardhat projects](#code-actions) - -## Installation - -[Hardhat for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=NomicFoundation.hardhat-solidity) can be installed by using the Visual Studio Code Marketplace. - -Some features (e.g. inline validation, quick fixes) are still experimental and are only enabled within a [Hardhat](https://hardhat.org/) project, this is a limitation that will be lifted with future releases. - -This extension should work without any configuration. To learn more about how it works with Hardhat projects, please read [this section](./hardhat-projects.md). If formatting functionality isn't working, or you have previously configured another Solidity formatter, please see the [formatting section](./formatting.md). - -## Features - -### Code Completions - -Hardhat for Visual Studio Code autocompletes references to existing symbols (e.g. contract instances, globally available variables and built-in types like arrays) and import directives (i.e. it autocompletes the path to the imported file). - -Direct imports (those not starting with `./` or `../`) are completed based on suggestions from `./node_modules`. - -Relative imports pull their suggestions from the file system based on the current solidity file's location. - -![Import completions](/hardhat-vscode-images/import-completion.gif "Import completions") - -### Navigation - -Move through your codebase with semantic navigation commands: - -#### Go to Definition - -Navigates to the definition of an identifier. - -#### Go to Type Definition - -Navigates to the type of an identifier. - -#### Go to References - -Shows all references of the identifier under the cursor. - -![Navigation](/hardhat-vscode-images/navigation.gif "Navigation") - -### Renames - -Rename the identifier under the cursor and all of its references: - -![Rename](/hardhat-vscode-images/rename.gif "Rename") - -### Format document - -Apply solidity formatting to the current document. - -The formatting configuration can be overridden through a `.prettierrc` file, see [Formatting Configuration](./formatting.md#formatting-configuration). - -![Reformat](/hardhat-vscode-images/format.gif "Reformat") - -### Hover - -Hovering the cursor over variables, function calls, errors and events will display a popup showing type and signature information: - -![Hover](/hardhat-vscode-images/on-hover.gif "Hover") - -### Inline code validation (Diagnostics) - -As code is edited, Hardhat for Visual Studio Code runs the [solc](https://docs.soliditylang.org/en/latest/using-the-compiler.html) compiler over the changes and displays any warnings or errors it finds. - -This feature is only available in solidity files that are part of a **Hardhat** project, as **Hardhat** is used for import resolution, see [Hardhat Projects](#hardhat-projects) for details. - -![Diagnostic](/hardhat-vscode-images/diagnostic.gif "Diagnostic") - -### Code Actions - -Code actions, or quickfixes are refactorings suggested to resolve a [solc](https://docs.soliditylang.org/en/latest/using-the-compiler.html) warning or error. - -A line with a warning/error that has a _code action_, will appear with small light bulb against it; clicking the light bulb will provide the option to trigger the _code action_. - -#### Implement missing functions on interface - -A contract that implements an interface, but is missing functions specified in the interface, will get a `solidity(3656)` error. - -The matching code action _Add missing functions from interface_ will determine which functions need to be implemented to satisfy the interface and add them as stubs to the body of the contract. - -![Implement interface](/hardhat-vscode-images/implement-interface.gif "Implement interface") - -#### Constrain mutability - -A function without a mutability keyword but which does not update contract state will show a `solidity(2018)` warning, with `solc` suggesting adding either the `view` or `pure` keyword depending on whether the function reads from state. - -The matching code action _Add view/pure modifier to function declaration_ resolves the warning by adding the keyword to the function signature. - -![Constrain Mutability](/hardhat-vscode-images/constrain-mutability.gif "Constrain Mutability") - -#### Adding `virtual`/`override` on inherited function signature - -A function in an inheriting contract, that has the same name and parameters as a function in the base contract, causes `solidity(4334)` in the base contract function if it does not have the `virtual` keyword and `solidity(9456)` in the inheriting contract function if does not have the `override` keyword. - -The _Add virtual specifier to function definition_ and _Add override specifier to function definition_ code actions appear against functions with these errors. - -![Virtual and Override](/hardhat-vscode-images/virtual-override.gif "Virtual and Override") - -#### Adding `public`/`private` to function signature - -A function without an accessibility keyword will cause the `solidity(4937)` error. - -Two code actions will appear against a function with this error: _Add public visibility to declaration_ and _Add private visibility to declaration_. - -![Public Private](/hardhat-vscode-images/public-private.gif "Public Private") diff --git a/docs/src/content/home.ts b/docs/src/content/home.ts deleted file mode 100644 index 0ba2fd12e9..0000000000 --- a/docs/src/content/home.ts +++ /dev/null @@ -1,260 +0,0 @@ -import SolidityIcon from "../assets/tools/solidity"; -import RunnerIcon from "../assets/tools/runner"; -// TODO: Re-enable Ignition section -// import IgnitionIcon from "../assets/tools/ignition"; -import NetworkIcon from "../assets/tools/network"; - -import SolidityImageMobile from "../assets/feature-cards/Mobile/SolidityImage.svg"; -import SolidityImageDesktop from "../assets/feature-cards/Desktop/SolidityImage.svg"; -import FlexibilityImageMobile from "../assets/feature-cards/Mobile/FlexibilityImage.svg"; -import FlexibilityImageDesktop from "../assets/feature-cards/Desktop/FlexibilityImage.svg"; -import ExtensibleImageMobile from "../assets/feature-cards/Mobile/ExtensibleImage.svg"; -import ExtensibleImageDesktop from "../assets/feature-cards/Desktop/ExtensibleImage.svg"; -import FastIterationImageMobile from "../assets/feature-cards/Mobile/FastIterationImage.svg"; -import FastIterationImageDesktop from "../assets/feature-cards/Desktop/FastIterationImage.svg"; - -// TODO-LANDING-DARK: Replace images below with correct dark themed images. -import SolidityImageMobileDark from "../assets/feature-cards/Mobile/SolidityImageDark.svg"; -import SolidityImageDesktopDark from "../assets/feature-cards/Desktop/SolidityImageDark.svg"; -import FlexibilityImageMobileDark from "../assets/feature-cards/Mobile/FlexibilityImageDark.svg"; -import FlexibilityImageDesktopDark from "../assets/feature-cards/Desktop/FlexibilityImageDark.svg"; -import ExtensibleImageMobileDark from "../assets/feature-cards/Mobile/ExtensibleImageDark.svg"; -import ExtensibleImageDesktopDark from "../assets/feature-cards/Desktop/ExtensibleImageDark.svg"; -import FastIterationImageMobileDark from "../assets/feature-cards/Mobile/FastIterationImageDark.svg"; -import FastIterationImageDesktopDark from "../assets/feature-cards/Desktop/FastIterationImageDark.svg"; - -import vibrantCommunityImage from "../assets/vibrantCommunityImage.svg"; -import vibrantCommunityImageDark from "../assets/vibrantCommunityImageDark.svg"; - -import { Tools } from "../components/ui/types"; -import reviewsBlock from "../assets/homepage-assets/reviews-block"; -import RunnerIconDark from "../assets/tools/runner-dark"; -// import IgnitionIconDark from "../assets/tools/ignition-dark"; -import NetworkIconDark from "../assets/tools/network-dark"; -import SolidityIconDark from "../assets/tools/solidity-dark"; - -const whyHardhatContent = { - title: "Why hardhat", -}; - -const featureCardsContent = { - featureCardOne: { - mobileImgDark: SolidityImageMobileDark, - desktopImgDark: SolidityImageDesktopDark, - mobileImg: SolidityImageMobile, - desktopImg: SolidityImageDesktop, - cta: { - url: "/hardhat-network/#console.log", - title: "Get started with Solidity console.log", - }, - articleOne: { - title: "Run Solidity locally", - text: "Easily deploy your contracts, run tests and debug Solidity code without dealing with live environments. Hardhat Network is a local Ethereum network designed for development.", - }, - articleTwo: { - title: "Debugging-first ", - text: "Hardhat is the best choice for Solidity debugging. You get Solidity stack traces, console.log and explicit error messages when transactions fail.", - }, - }, - featureCardTwo: { - mobileImgDark: FlexibilityImageMobileDark, - desktopImgDark: FlexibilityImageDesktopDark, - mobileImg: FlexibilityImageMobile, - desktopImg: FlexibilityImageDesktop, - cta: { - url: "/hardhat-runner/docs/advanced/create-task.html", - title: "Learn more about extending Hardhat", - }, - articleOne: { - title: "Extreme flexibility", - text: "Change anything you like. Even entire out-of-the-box tasks, or just parts of them. Flexible and customizable design, with little constraints.", - }, - articleTwo: { - title: "Bring your own tools", - text: "Designed to make integrations easy, Hardhat allows you to keep using your existing tools while enabling deeper interoperability between them.", - }, - }, - featureCardThree: { - mobileImgDark: ExtensibleImageMobileDark, - desktopImgDark: ExtensibleImageDesktopDark, - mobileImg: ExtensibleImageMobile, - desktopImg: ExtensibleImageDesktop, - cta: { url: "/hardhat-runner/plugins", title: "Get started with plugins" }, - articleOne: { - title: "Fully extensible", - text: "A tooling platform designed to be extended, Hardhat has all the utilities you need to address your project-specific needs.", - }, - articleTwo: { - title: "Plugin ecosystem", - text: "Extend Hardhat with a composable ecosystem of plugins that add functionality and integrate your existing tools into a smooth workflow.", - }, - }, - featureCardFour: { - mobileImgDark: FastIterationImageMobileDark, - desktopImgDark: FastIterationImageDesktopDark, - mobileImg: FastIterationImageMobile, - desktopImg: FastIterationImageDesktop, - cta: { - url: "/hardhat-runner/docs/guides/typescript.html", - title: "Get started with TypeScript", - }, - articleOne: { - title: "Fast iteration", - text: "Keep your momentum going by making your development feedback loop up to 10x faster with Hardhat.", - }, - articleTwo: { - title: "TypeScript", - text: "Catch mistakes before you even run your code by switching to a typed language. Hardhat provides full native support for TypeScript.", - }, - }, -}; - -const heroBlockContent = { - title: "Ethereum development environment for professionals", - tagline: "Flexible. Extensible. Fast.", - cta: { - title: "Get started", - url: "/hardhat-runner/docs/getting-started", - }, -}; - -const getStartedBlockContent = { - title: "Hardhat is next- generation Ethereum tooling", - subtitle: "Experience the new way of building Ethereum software.", - cta: { - title: "Get started", - url: "/hardhat-runner/docs/getting-started", - }, -}; - -const vibrantCommunityBlockContent = { - title: "Vibrant community", - text: "Great tech attracts great people. Join the Hardhat community to find answers to your problems and contribute to the plugin ecosystem.", - // imageUrl: "/images/vibrant_community.png", - imageUrl: vibrantCommunityImage, - // TODO-LANDING-DARK: add missing image vibrant_community-dark.png - imageDarkUrl: vibrantCommunityImageDark, - cta: { - title: "Join the Hardhat Discord", - url: "/discord", - }, -}; - -const trustedTeamsBlockContent = { - title: "Trusted by top teams", -}; - -const builtByBlockContent = { - title: "Built by", - imageUrl: "/images/nomic-foundation-logo.svg", - imageDarkUrl: "/images/nomic-foundation-logo-dark.svg", -}; - -const reviewsBlockContent = [ - { - name: "Victor Tran", - position: "CTO at Kyber", - personImage: reviewsBlock.victor, - companyImage: "/images/reveiws-logo/kyber.svg", - alt: "Kyber logo", - comment: - '"Working with Hardhat has been a great experience. Thanks to its flexibility we were able to test across different Solidity versions without duplicating our setup. Kyber has been around for long enough to have legacy contracts deployed with different Solidity versions in our architecture, so this kind of flexibility is important for such a mature project. The collaboration between the Kyber and Hardhat teams to fix issues and implement new features has been fast and smooth, which helped our internal timelines a lot."', - }, - { - name: "Justin J. Moses", - position: "CTO at SYNTHETIX", - personImage: reviewsBlock.justin, - companyImage: "/images/reveiws-logo/synthetix.svg", - alt: "Synthetix logo", - comment: - '"Tired of battling other testing frameworks, I tried Hardhat on a whim one afternoon to see just how hard it might be to port Synthetix over to it. After fifteen minutes I had one of our specs running nearly 10x faster that what I’d become used to; from that moment I was hooked. Since then, we’ve integrated coverage, supported multiple versions of solc and even set up legacy testing through injection - all without having to wait for features to be added by the Hardhat team. It’s been built using its own extensible task system, dogfooding its own plugin architecture. Fast test turnarounds, extensible architecture and solidity stack traces - my dream of smart contract TDD has become a lot more real!"', - }, - { - name: "Brett Sun", - position: "CTO at Aragon One", - personImage: reviewsBlock.brett, - companyImage: "/images/reveiws-logo/aone.svg", - alt: "Aragon One logo", - comment: - '"Our interest in Hardhat was driven by our own experience of building and maintaining developer tooling for the Aragon ecosystem. Not only were these efforts time consuming, difficult, and error-prone, we also found ourselves constantly re-inventing the wheel in areas we did not want to care about or force opinions on (e.g. Ganache connections, Truffle providers, test strategy). Hardhat, with its plugin ecosystem, has effectively eliminated many of these problems for us. We feel confident piggybacking on the best for the underlying layers so that we can focus our attention on exposing the power of the Aragon ecosystem to our community."', - }, - { - name: "Rahul Sethuram", - position: "CTO at Connext Network", - personImage: reviewsBlock.rahul, - companyImage: "/images/reveiws-logo/connext.svg", - alt: "Connext logo", - comment: - "\"Builder has become an essential part of our development and Continuous Integration stack. At Connext, we develop and test complicated smart contract systems for our state channel implementations, making proper Solidity tooling a key to our productivity and success. Hardhat's state-of-the-art Solidity stack trace and console.log features saved us considerable development time. As a user, it's clear that Hardhat prioritizes a great developer experience, which aligns fully with Connext's values. We enjoy interacting with the team and we have even made contributions to the project.\"", - }, - { - name: "Esteban Ordano", - position: "CTO at Decentraland", - personImage: reviewsBlock.esteban, - companyImage: "/images/reveiws-logo/decentraland.svg", - alt: "Decentraland logo", - comment: - '"Hardhat\'s extensibility, clean interface and excellent design is the most significant advancement in the professionalization of tools for Ethereum of the past year. Our development experience improved significantly, and the quality of the development process is reflected in the fact that our team went from fearing updating packages to the latest version to watching out for the next release."', - }, -]; - -const toolsBlockContent = { - title: "Tools", - companyName: "Hardhat", - infoItems: [ - { - icon: RunnerIcon, - iconDark: RunnerIconDark, - title: "Runner", - value: Tools.RUNNER, - mottos: ["compile", "test", "extend"], - description: - "Hardhat Runner is the main component you interact with when using Hardhat. It's a flexible and extensible task runner that helps you manage and automate the recurring tasks inherent to developing smart contracts and dApps.", - link: "/hardhat-runner", - }, - // TODO: Re-enable Ignition section - // { - // icon: IgnitionIcon, - // title: "Ignition", - // value: Tools.IGNITION, - // mottos: ["deploy", "distribute"], - // description: - // "Deployment system for structuring, automating and distributing smart contract deployment setups.", - // link: "/hardhat-ignition", - // }, - { - icon: NetworkIcon, - iconDark: NetworkIconDark, - title: "Network", - value: Tools.NETWORK, - mottos: ["debug", "deploy", "simulate"], - description: - "Hardhat comes built-in with Hardhat Network, a local Ethereum network node designed for development. It allows you to deploy your contracts, run your tests and debug your code, all within the confines of your local machine.", - link: "/hardhat-network", - }, - { - icon: SolidityIcon, - iconDark: SolidityIconDark, - title: "VSCode", - value: Tools.SOLIDITY, - mottos: ["code", "navigation", "refactor"], - description: - "Hardhat for Visual Studio Code is a VS Code extension that adds language support for Solidity and provides editor integration for Hardhat projects.", - link: "/hardhat-vscode", - }, - ], -}; - -const homepageContent = { - whyHardhatContent, - featureCardsContent, - heroBlockContent, - getStartedBlockContent, - vibrantCommunityBlockContent, - trustedTeamsBlockContent, - builtByBlockContent, - reviewsBlockContent, - toolsBlockContent, -}; - -export default homepageContent; diff --git a/docs/src/content/layouts.yaml b/docs/src/content/layouts.yaml deleted file mode 100644 index c984269661..0000000000 --- a/docs/src/content/layouts.yaml +++ /dev/null @@ -1,57 +0,0 @@ -hardhat-runner: - title: Hardhat Runner - folders: - - hardhat-runner - - hardhat-runner/docs - - hardhat-runner/docs/getting-started - - hardhat-runner/docs/config - - hardhat-runner/docs/guides - - hardhat-runner/docs/advanced - - hardhat-runner/docs/supporter-guides - - hardhat-runner/docs/troubleshooting - - hardhat-runner/docs/reference - - hardhat-runner/plugins - - hardhat-runner/docs/other-components - # hidden - - hardhat-runner/docs/errors - - hardhat-runner/docs/other-guides - -hardhat-network: - title: Hardhat Network - folders: - - hardhat-network - - hardhat-network/docs - - hardhat-network/docs/other-components - # hidden - - hardhat-network/docs/metamask-issue - -hardhat-vscode: - title: Hardhat VSCode - folders: - - hardhat-vscode - - hardhat-vscode/docs - - hardhat-vscode/docs/other-components - -hardhat-chai-matchers: - title: Hardhat Chai Matchers - folders: - - hardhat-chai-matchers - - hardhat-chai-matchers/docs - - hardhat-chai-matchers/docs/other-components - -hardhat-network-helpers: - title: Hardhat Network Helpers - folders: - - hardhat-network-helpers - - hardhat-network-helpers/docs - - hardhat-network-helpers/docs/other-components - -hidden: - title: hidden - folders: - - docs-landing - -tutorial: - title: tutorial - folders: - - tutorial diff --git a/docs/src/content/tutorial/_dirinfo.yaml b/docs/src/content/tutorial/_dirinfo.yaml deleted file mode 100644 index 2eec3ed15d..0000000000 --- a/docs/src/content/tutorial/_dirinfo.yaml +++ /dev/null @@ -1,21 +0,0 @@ -section-type: group -section-title: Tutorial -order: - - title: 1. Overview - href: / - - title: 2. Setting up the environment - href: /setting-up-the-environment - - title: 3. Creating a new Hardhat project - href: /creating-a-new-hardhat-project - - title: 4. Writing and compiling contracts - href: /writing-and-compiling-contracts - - title: 5. Testing contracts - href: /testing-contracts - - title: 6. Debugging with Hardhat Network - href: /debugging-with-hardhat-network - - title: 7. Deploying to a live network - href: /deploying-to-a-live-network - - title: 8. Boilerplate Project - href: /boilerplate-project - - title: 9. Final thoughts - href: /final-thoughts diff --git a/docs/src/content/tutorial/boilerplate-project.md b/docs/src/content/tutorial/boilerplate-project.md deleted file mode 100644 index 8137fb3168..0000000000 --- a/docs/src/content/tutorial/boilerplate-project.md +++ /dev/null @@ -1,103 +0,0 @@ -# Hardhat Boilerplate Project - -If you want to get started with your dApp quickly or see what this whole project looks like with a frontend, you can use [our boilerplate repo](https://github.com/NomicFoundation/hardhat-boilerplate). - -## What's included - -- The Solidity contract we used in this tutorial -- Tests for the entire functionality of the contract -- A minimal React front-end to interact with the contract using ethers.js - -### Solidity contract & tests - -In the root of the repo you'll find the Hardhat project we put together through this tutorial with the `Token` contract. To refresh your memory on what it implements: - -- There is a fixed total supply of tokens that can't be changed. -- The entire supply is assigned to the address that deploys the contract. -- Anyone can receive tokens. -- Anyone with at least one token can transfer tokens. -- The token is non-divisible. You can transfer 1, 2, 3 or 37 tokens but not 2.5. - -### Frontend app - -In `frontend` you'll find a simple app that allows the user to do two things: - -- Check the connected wallet's balance -- Send tokens to an address - -It's a separate npm project and it was created using `create-react-app`, so this means that it uses webpack and babel. - -### Frontend file architecture - -- `src/` contains all the code - - `src/components` contains the react components - - `Dapp.js` is the only file with business logic. This is where you'd replace the code with your own if you were to use this as boilerplate - - Every other component just renders HTML, no logic. - - `src/contracts` has the ABI and address of the contract and these are automatically generated by the deployment script - -## How to use it - -First clone the repository, and then prepare for the contract deployment: - -``` -cd hardhat-boilerplate -npm install -npx hardhat node -``` - -Here we just install the npm project's dependencies, and by running `npx hardhat node` we spin up an instance of Hardhat Network that you can connect to using your wallet. In a different terminal in the same directory, run: - -``` -npx hardhat --network localhost run scripts/deploy.js -``` - -This will deploy the contract to Hardhat Network. After this completes, start the react web app: - -``` -cd frontend -npm install -npm run start -``` - -Then open [http://127.0.0.1:3000/](http://127.0.0.1:3000/) in your browser and you should see this: ![](/front-5.png) - -Click the button to connect your wallet. If you are using MetaMask, make sure you have selected the `Localhost 8545` network. - -After connecting your wallet, you should see this: - -![](/front-2.png) - -What's happening here is that the frontend code to show the current wallet's balance is detecting that the balance is `0`, so you wouldn't be able to try the transfer functionality. By running: - -``` -npx hardhat --network localhost faucet -``` - -You'll run a custom Hardhat task we included that uses the balance of the deploying account to send 100 MHT and 1 ETH to your address. This will allow you to send tokens to another address. - -You can check out the code for the task in [`/tasks/faucet.js`](https://github.com/NomicFoundation/hardhat-boilerplate/blob/master/tasks/faucet.js), which is required from `hardhat.config.js`. - -``` -$ npx hardhat --network localhost faucet 0x0987a41e73e69f60c5071ce3c8f7e730f9a60f90 -Transferred 1 ETH and 100 tokens to 0x0987a41e73e69f60c5071ce3c8f7e730f9a60f90 -``` - -In the terminal where you ran `npx hardhat node` you should also see: - -```markup{10-11} -eth_sendTransaction - Contract call: Token#transfer - Transaction: 0x460526d98b86f7886cd0f218d6618c96d27de7c745462ff8141973253e89b7d4 - From: 0xc783df8a850f42e7f7e57013759c285caa701eb6 - To: 0x7c2c195cd6d34b8f845992d380aadb2730bb9c6f - Value: 0 ETH - Gas used: 37098 of 185490 - Block #8: 0x6b6cd29029b31f30158bfbd12faf2c4ac4263068fd12b6130f5655e70d1bc257 - - console.log: - Transferring from 0xc783df8a850f42e7f7e57013759c285caa701eb6 to 0x0987a41e73e69f60c5071ce3c8f7e730f9a60f90 100 tokens -``` - -Showing the `console.log` output from the `transfer()` function in our contract, and this is what the web app will look like after you run the faucet task: ![](/front-6.png) - -Try playing around with it and reading the code. It's full of comments explaining what's going on and clearly indicating what code is Ethereum boilerplate and what's actually dApp logic. This should make the repository easy to reuse for your project. diff --git a/docs/src/content/tutorial/creating-a-new-hardhat-project.md b/docs/src/content/tutorial/creating-a-new-hardhat-project.md deleted file mode 100644 index 8f6d0d39a5..0000000000 --- a/docs/src/content/tutorial/creating-a-new-hardhat-project.md +++ /dev/null @@ -1,169 +0,0 @@ -# 3. Creating a new Hardhat project - -We'll install Hardhat using the Node.js package manager (`npm`), which is both a package manager and an online repository for JavaScript code. - -You can use other package managers with Node.js, but we suggest you use npm 7 or higher to follow this guide. You should already have it if you followed the previous section's steps. - -Open a new terminal and run these commands to create a new folder: - -``` -mkdir hardhat-tutorial -cd hardhat-tutorial -``` - -Then initialize an npm project as shown below. You'll be prompted to answer some questions. - -::::tip - -Use the tabs in the snippets to select your preferred package manager. We recommend using npm 7 or later, since it makes installing Hardhat's dependencies much easier. - -:::: - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm init -``` - -::: - -:::tab{value="npm 6"} - -``` -npm init -``` - -::: - -:::tab{value=yarn} - -``` -yarn init -``` - -::: - -:::: - -Now we can install Hardhat: - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm install --save-dev hardhat -``` - -::: - -:::tab{value="npm 6"} - -``` -npm install --save-dev hardhat -``` - -::: - -:::tab{value=yarn} - -``` -yarn add --dev hardhat -``` - -::: - -:::: - -In the same directory where you installed Hardhat run: - -``` -npx hardhat -``` - -Select `Create an empty hardhat.config.js` with your keyboard and hit enter. - -```markup{16} -$ npx hardhat -888 888 888 888 888 -888 888 888 888 888 -888 888 888 888 888 -8888888888 8888b. 888d888 .d88888 88888b. 8888b. 888888 -888 888 "88b 888P" d88" 888 888 "88b "88b 888 -888 888 .d888888 888 888 888 888 888 .d888888 888 -888 888 888 888 888 Y88b 888 888 888 888 888 Y88b. -888 888 "Y888888 888 "Y88888 888 888 "Y888888 "Y888 - -👷 Welcome to Hardhat v2.9.9 👷‍ - -? What do you want to do? … - Create a JavaScript project - Create a TypeScript project -❯ Create an empty hardhat.config.js - Quit -``` - -When Hardhat is run, it searches for the closest `hardhat.config.js` file starting from the current working directory. This file normally lives in the root of your project and an empty `hardhat.config.js` is enough for Hardhat to work. The entirety of your setup is contained in this file. - -## Hardhat's architecture - -Hardhat is designed around the concepts of tasks and plugins. The bulk of Hardhat's functionality comes from plugins, and [you're free to choose](/hardhat-runner/plugins/) the ones you want to use. - -### Tasks - -Every time you're running Hardhat from the command-line, you're running a task. For example, `npx hardhat compile` is running the `compile` task. To see the currently available tasks in your project, run `npx hardhat`. Feel free to explore any task by running `npx hardhat help [task]`. - -:::tip - -You can create your own tasks. Check out the [Creating a task](/guides/create-task.md) guide. - -::: - -### Plugins - -Hardhat is unopinionated in terms of what tools you end up using, but it does come with some built-in defaults. All of which can be overridden. Most of the time the way to use a given tool is by consuming a plugin that integrates it into Hardhat. - -In this tutorial we are going to use our recommended plugin, [`@nomicfoundation/hardhat-toolbox`](../hardhat-runner/plugins/nomicfoundation-hardhat-toolbox), which has everything you need for developing smart contracts. - -To install it, run this in your project directory: - -::::tabsgroup{options="npm 7+,npm 6,yarn"} - -:::tab{value="npm 7+"} - -``` -npm install --save-dev @nomicfoundation/hardhat-toolbox -``` - -::: - -:::tab{value="npm 6"} - -``` -npm install --save-dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers -``` - -::: - -:::tab{value=yarn} - -``` -yarn add --dev @nomicfoundation/hardhat-toolbox @nomicfoundation/hardhat-network-helpers @nomicfoundation/hardhat-chai-matchers @nomiclabs/hardhat-ethers @nomiclabs/hardhat-etherscan chai ethers hardhat-gas-reporter solidity-coverage @typechain/hardhat typechain @typechain/ethers-v5 @ethersproject/abi @ethersproject/providers -``` - -::: - -:::: - -Add the highlighted line to your `hardhat.config.js` so that it looks like this: - -```js{1} -require("@nomicfoundation/hardhat-toolbox"); - -/** @type import('hardhat/config').HardhatUserConfig */ -module.exports = { - solidity: "0.8.18", -}; -``` diff --git a/docs/src/content/tutorial/debugging-with-hardhat-network.md b/docs/src/content/tutorial/debugging-with-hardhat-network.md deleted file mode 100644 index 3e2f3c13e2..0000000000 --- a/docs/src/content/tutorial/debugging-with-hardhat-network.md +++ /dev/null @@ -1,63 +0,0 @@ -# 6. Debugging with Hardhat Network - -Hardhat comes built-in with Hardhat Network, a local Ethereum network designed for development. It allows you to deploy your contracts, run your tests and debug your code, all within the confines of your local machine. It's the default network that Hardhat connects to, so you don't need to set up anything for it to work. Just run your tests. - -## Solidity `console.log` - -When running your contracts and tests on Hardhat Network you can print logging messages and contract variables calling `console.log()` from your Solidity code. To use it you have to import `hardhat/console.sol` in your contract code. - -This is what it looks like: - -```solidity{3} -pragma solidity ^0.8.9; - -import "hardhat/console.sol"; - -contract Token { - //... -} -``` - -Then you can just add some `console.log` calls to the `transfer()` function as if you were using it in JavaScript: - -```solidity{4-9} -function transfer(address to, uint256 amount) external { - require(balances[msg.sender] >= amount, "Not enough tokens"); - - console.log( - "Transferring from %s to %s %s tokens", - msg.sender, - to, - amount - ); - - balances[msg.sender] -= amount; - balances[to] += amount; - - emit Transfer(msg.sender, to, amount); -} -``` - -The logging output will show when you run your tests: - -```markup{8-11,14-17} -$ npx hardhat test - - Token contract - Deployment - ✓ Should set the right owner - ✓ Should assign the total supply of tokens to the owner - Transactions -Transferring from 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 to 0x70997970c51812dc3a010c7d01b50e0d17dc79c8 50 tokens -Transferring from 0x70997970c51812dc3a010c7d01b50e0d17dc79c8 to 0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc 50 tokens - ✓ Should transfer tokens between accounts (373ms) - ✓ Should fail if sender doesn’t have enough tokens -Transferring from 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 to 0x70997970c51812dc3a010c7d01b50e0d17dc79c8 50 tokens -Transferring from 0x70997970c51812dc3a010c7d01b50e0d17dc79c8 to 0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc 50 tokens - ✓ Should update balances after transfers (187ms) - - - 5 passing (2s) -``` - -Check out the [documentation](/hardhat-network/index.md#console.log) to learn more about this feature. diff --git a/docs/src/content/tutorial/deploying-to-a-live-network.md b/docs/src/content/tutorial/deploying-to-a-live-network.md deleted file mode 100644 index 088f044b51..0000000000 --- a/docs/src/content/tutorial/deploying-to-a-live-network.md +++ /dev/null @@ -1,139 +0,0 @@ -# 7. Deploying to a live network - -Once you're ready to share your dApp with other people, you may want to deploy it to a live network. This way others can access an instance that's not running locally on your system. - -The "mainnet" Ethereum network deals with real money, but there are separate "testnet" networks that do not. These testnets provide shared staging environments that do a good job of mimicking the real world scenario without putting real money at stake, and [Ethereum has several](https://ethereum.org/en/developers/docs/networks/#ethereum-testnets), like _Sepolia_ and _Goerli_. We recommend you deploy your contracts to the _Sepolia_ testnet. - -At the software level, deploying to a testnet is the same as deploying to mainnet. The only difference is which network you connect to. Let's look into what the code to deploy your contracts using ethers.js would look like. - -The main concepts used are `Signer`, `ContractFactory` and `Contract` which we explained back in the [testing](testing-contracts.md) section. There's nothing new that needs to be done when compared to testing, given that when you're testing your contracts you're _actually_ making a deployment to your development network. This makes the code very similar, or even the same. - -Let's create a new directory `scripts` inside the project root's directory, and paste the following into a `deploy.js` file in that directory: - -```js -async function main() { - const [deployer] = await ethers.getSigners(); - - console.log("Deploying contracts with the account:", deployer.address); - - console.log("Account balance:", (await deployer.getBalance()).toString()); - - const Token = await ethers.getContractFactory("Token"); - const token = await Token.deploy(); - - console.log("Token address:", token.address); -} - -main() - .then(() => process.exit(0)) - .catch((error) => { - console.error(error); - process.exit(1); - }); -``` - -To tell Hardhat to connect to a specific Ethereum network, you can use the `--network` parameter when running any task, like this: - -``` -npx hardhat run scripts/deploy.js --network -``` - -With our current configuration, running it without the `--network` parameter would cause the code to run against an embedded instance of Hardhat Network. In this scenario, the deployment actually gets lost when Hardhat finishes running, but it's still useful to test that our deployment code works: - -``` -$ npx hardhat run scripts/deploy.js -Deploying contracts with the account: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266 -Account balance: 10000000000000000000000 -Token address: 0x5FbDB2315678afecb367f032d93F642f64180aa3 -``` - -## Deploying to remote networks - -To deploy to a remote network such as mainnet or any testnet, you need to add a `network` entry to your `hardhat.config.js` file. We’ll use Sepolia for this example, but you can add any network similarly: - -::::tabsgroup{options=Infura,Alchemy} - -:::tab{value=Infura} - -```js{5,11,15-20} -require("@nomicfoundation/hardhat-toolbox"); - -// Go to https://infura.io, sign up, create a new API key -// in its dashboard, and replace "KEY" with it -const INFURA_API_KEY = "KEY"; - -// Replace this private key with your Sepolia account private key -// To export your private key from Coinbase Wallet, go to -// Settings > Developer Settings > Show private key -// To export your private key from Metamask, open Metamask and -// go to Account Details > Export Private Key -// Beware: NEVER put real Ether into testing accounts -const SEPOLIA_PRIVATE_KEY = "YOUR SEPOLIA PRIVATE KEY"; - -module.exports = { - solidity: "0.8.9", - networks: { - sepolia: { - url: `https://sepolia.infura.io/v3/${INFURA_API_KEY}`, - accounts: [SEPOLIA_PRIVATE_KEY] - } - } -}; -``` - -::: - -:::tab{value=Alchemy} - -```js{5,11,15-20} -require("@nomicfoundation/hardhat-toolbox"); - -// Go to https://alchemy.com, sign up, create a new App in -// its dashboard, and replace "KEY" with its key -const ALCHEMY_API_KEY = "KEY"; - -// Replace this private key with your Sepolia account private key -// To export your private key from Coinbase Wallet, go to -// Settings > Developer Settings > Show private key -// To export your private key from Metamask, open Metamask and -// go to Account Details > Export Private Key -// Beware: NEVER put real Ether into testing accounts -const SEPOLIA_PRIVATE_KEY = "YOUR SEPOLIA PRIVATE KEY"; - -module.exports = { - solidity: "0.8.9", - networks: { - sepolia: { - url: `https://eth-sepolia.g.alchemy.com/v2/${ALCHEMY_API_KEY}`, - accounts: [SEPOLIA_PRIVATE_KEY] - } - } -}; -``` - -::: - -:::: - -We're using [Infura](https://infura.io) or [Alchemy](https://alchemy.com/), but pointing `url` to any Ethereum node or gateway. Go grab your API key and come back. - -To deploy on Sepolia you need to send some Sepolia ether to the address that's going to be making the deployment. You can get testnet ether from a faucet, a service that distributes testing-ETH for free. Here is one for Sepolia: - -- [Alchemy Sepolia Faucet](https://sepoliafaucet.com/) -- [Coinbase Sepolia Faucet](https://coinbase.com/faucets/ethereum-sepolia-faucet) (only works if you are using the Coinbase Wallet) - -You'll have to change your wallet's network to Sepolia before transacting. - -:::tip - -You can learn more about other testnets and find links to their faucets on the [ethereum.org site](https://ethereum.org/en/developers/docs/networks/#ethereum-testnets). - -::: - -Finally, run: - -``` -npx hardhat run scripts/deploy.js --network sepolia -``` - -If everything went well, you should see the deployed contract address. diff --git a/docs/src/content/tutorial/final-thoughts.md b/docs/src/content/tutorial/final-thoughts.md deleted file mode 100644 index 419b85a365..0000000000 --- a/docs/src/content/tutorial/final-thoughts.md +++ /dev/null @@ -1,25 +0,0 @@ -# 9. Final thoughts - -Congratulations on finishing the tutorial! - -Here are some links you might find useful throughout your journey: - -- [Hardhat's Boilerplate](https://github.com/NomicFoundation/hardhat-boilerplate) -- [Hardhat's documentation site](/docs/) -- [Hardhat Toolbox's documentation](/hardhat-runner/plugins/nomicfoundation-hardhat-toolbox) -- [Hardhat Support Discord server](/discord) -- [Ethers.js Documentation](https://docs.ethers.io/) -- [Mocha Documentation](https://mochajs.org/) -- [Chai Documentation](https://www.chaijs.com/) -- [Alchemy's smart contract tutorial](https://docs.alchemy.com/docs/hello-world-smart-contract) to also learn how to use Metamask and Solidity as well as an RPC endpoint like the one that Alchemy provides. - -Further things to do with your smart contract using Hardhat: - -- [Interact with a smart contract](https://docs.alchemy.com/docs/interacting-with-a-smart-contract) -- [Submit your smart contract to Etherscan](https://docs.alchemy.com/docs/submitting-your-smart-contract-to-etherscan) - -Finally, show us some love by starring [our repository on GitHub!](https://github.com/NomicFoundation/hardhat)️ - -Happy hacking! - -![](/cool-hardhat.svg) diff --git a/docs/src/content/tutorial/index.md b/docs/src/content/tutorial/index.md deleted file mode 100644 index 9c73ff2dfd..0000000000 --- a/docs/src/content/tutorial/index.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -prev: false ---- - -![Teacher Hardhat](/hardhat-tutorial.svg) - -# Hardhat's tutorial for beginners - -Welcome to our beginners guide to Ethereum contracts and dApp development. This tutorial aims to quickly get you set up to build something from scratch. - -To orchestrate this process we're going to use Hardhat, a development environment that facilitates building on Ethereum. It helps developers manage and automate the recurring tasks that are inherent to the process of building smart contracts and dApps, and it allows you to easily introduce more functionality around this workflow. This means compiling and testing at the very core. - -Hardhat also comes built-in with Hardhat Network, a local Ethereum network designed for development. It allows you to deploy your contracts, run your tests and debug your code. - -In this tutorial we'll guide you through: - -- Setting up your Node.js environment for Ethereum development -- Creating and configuring a Hardhat project -- The basics of a Solidity smart contract that implements a token -- Writing automated tests for your contract using Hardhat -- Debugging Solidity with `console.log()` using Hardhat Network -- Deploying your contract to Hardhat Network and Ethereum testnets - -To follow this tutorial you should be able to: - -- Write code in [JavaScript](https://developer.mozilla.org/en-US/docs/Learn/Getting_started_with_the_web/JavaScript_basics) -- Operate a [terminal](https://en.wikipedia.org/wiki/Terminal_emulator) -- Use [git](https://git-scm.com/doc) -- Understand the basics of how [smart contracts](https://ethereum.org/learn/#smart-contracts) work -- Set up a [Coinbase](https://www.coinbase.com/wallet) or [Metamask](https://metamask.io/) wallet - -If you can't do any of the above, follow the links and take some time to learn the basics. diff --git a/docs/src/content/tutorial/setting-up-the-environment.md b/docs/src/content/tutorial/setting-up-the-environment.md deleted file mode 100644 index 50854bb22a..0000000000 --- a/docs/src/content/tutorial/setting-up-the-environment.md +++ /dev/null @@ -1,75 +0,0 @@ -# 2. Setting up the environment - -Most Ethereum libraries and tools are written in JavaScript, and so is Hardhat. If you're not familiar with Node.js, it's a JavaScript runtime built on Chrome's V8 JavaScript engine. It's the most popular solution to run JavaScript outside of a web browser and Hardhat is built on top of it. - -:::tip - -[Hardhat for Visual Studio Code](/hardhat-vscode) is the official Hardhat extension that adds advanced support for Solidity to VSCode. If you use Visual Studio Code, give it a try! - -::: - -## Installing Node.js - -You can [skip](./creating-a-new-hardhat-project.md) this section if you already have a working Node.js `>=16.0` installation. If not, here's how to install it on Ubuntu, MacOS and Windows. - -### Linux - -#### Ubuntu - -Copy and paste these commands in a terminal: - -``` -sudo apt update -sudo apt install curl git -curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash - -sudo apt-get install -y nodejs -``` - -### MacOS - -Make sure you have `git` installed. Otherwise, follow [these instructions](https://www.atlassian.com/git/tutorials/install-git). - -There are multiple ways of installing Node.js on MacOS. We will be using [Node Version Manager (nvm)](http://github.com/creationix/nvm). Copy and paste these commands in a terminal: - -``` -curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash -nvm install 18 -nvm use 18 -nvm alias default 18 -npm install npm --global # Upgrade npm to the latest version -``` - -### Windows - -If you are using Windows, we **strongly recommend** you use Windows Subsystem for Linux (also known as WSL 2). You can use Hardhat without it, but it will work better if you use it. - -To install Node.js using WSL 2, please read [this guide](https://docs.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-wsl). - -Make sure you also [have `git` installed on WSL](https://docs.microsoft.com/en-us/windows/wsl/tutorials/wsl-git). - -## Upgrading your Node.js installation - -If your version of Node.js is older and [not supported by Hardhat](../hardhat-runner/docs/reference/stability-guarantees.md#node.js-versions-support) follow the instructions below to upgrade. - -### Linux - -#### Ubuntu - -1. Run `sudo apt remove nodejs` in a terminal to remove Node.js. -2. Find the version of Node.js that you want to install [here](https://github.com/nodesource/distributions#debinstall) and follow the instructions. -3. Run `sudo apt update && sudo apt install nodejs` in a terminal to install Node.js again. - -### MacOS - -You can change your Node.js version using [nvm](http://github.com/creationix/nvm). To upgrade to Node.js `18.x` run these in a terminal: - -``` -nvm install 18 -nvm use 18 -nvm alias default 18 -npm install npm --global # Upgrade npm to the latest version -``` - -### Windows - -You need to follow the [same installation instructions](#windows) as before but choose a different version. You can check the list of all available versions [here](https://nodejs.org/en/download/releases/). diff --git a/docs/src/content/tutorial/testing-contracts.md b/docs/src/content/tutorial/testing-contracts.md deleted file mode 100644 index 4d87502e75..0000000000 --- a/docs/src/content/tutorial/testing-contracts.md +++ /dev/null @@ -1,315 +0,0 @@ -# 5. Testing contracts - -Writing automated tests when building smart contracts is of crucial importance, as your user's money is what's at stake. - -To test our contract, we are going to use Hardhat Network, a local Ethereum network designed for development. It comes built-in with Hardhat, and it's used as the default network. You don't need to setup anything to use it. - -In our tests we're going to use [ethers.js](https://docs.ethers.io/v5/) to interact with the Ethereum contract we built in the previous section, and we'll use [Mocha](https://mochajs.org/) as our test runner. - -## Writing tests - -Create a new directory called `test` inside our project root directory and create a new file in there called `Token.js`. - -Let's start with the code below. We'll explain it next, but for now paste this into `Token.js`: - -```js -const { expect } = require("chai"); - -describe("Token contract", function () { - it("Deployment should assign the total supply of tokens to the owner", async function () { - const [owner] = await ethers.getSigners(); - - const Token = await ethers.getContractFactory("Token"); - - const hardhatToken = await Token.deploy(); - - const ownerBalance = await hardhatToken.balanceOf(owner.address); - expect(await hardhatToken.totalSupply()).to.equal(ownerBalance); - }); -}); -``` - -In your terminal run `npx hardhat test`. You should see the following output: - -``` -$ npx hardhat test - - Token contract - ✓ Deployment should assign the total supply of tokens to the owner (654ms) - - - 1 passing (663ms) -``` - -This means the test passed. Let's now explain each line: - -```js -const [owner] = await ethers.getSigners(); -``` - -A `Signer` in ethers.js is an object that represents an Ethereum account. It's used to send transactions to contracts and other accounts. Here we're getting a list of the accounts in the node we're connected to, which in this case is Hardhat Network, and we're only keeping the first one. - -The `ethers` variable is available in the global scope. If you like your code always being explicit, you can add this line at the top: - -```js -const { ethers } = require("hardhat"); -``` - -:::tip - -To learn more about `Signer`, you can look at the [Signers documentation](https://docs.ethers.io/v5/api/signer/). - -::: - -```js -const Token = await ethers.getContractFactory("Token"); -``` - -A `ContractFactory` in ethers.js is an abstraction used to deploy new smart contracts, so `Token` here is a factory for instances of our token contract. - -```js -const hardhatToken = await Token.deploy(); -``` - -Calling `deploy()` on a `ContractFactory` will start the deployment, and return a `Promise` that resolves to a `Contract`. This is the object that has a method for each of your smart contract functions. - -```js -const ownerBalance = await hardhatToken.balanceOf(owner.address); -``` - -Once the contract is deployed, we can call our contract methods on `hardhatToken`. Here we get the balance of the owner account by calling the contract's `balanceOf()` method. - -Recall that the account that deploys the token gets its entire supply. By default, `ContractFactory` and `Contract` instances are connected to the first signer. This means that the account in the `owner` variable executed the deployment, and `balanceOf()` should return the entire supply amount. - -```js -expect(await hardhatToken.totalSupply()).to.equal(ownerBalance); -``` - -Here we're again using our `Contract` instance to call a smart contract function in our Solidity code. `totalSupply()` returns the token's supply amount and we're checking that it's equal to `ownerBalance`, as it should be. - -To do this we're using [Chai](https://www.chaijs.com/) which is a popular JavaScript assertion library. These asserting functions are called "matchers", and the ones we're using here come from the [`@nomicfoundation/hardhat-chai-matchers`](../hardhat-runner/plugins/nomicfoundation-hardhat-chai-matchers) plugin, which extends Chai with many matchers useful to test smart contracts. - -### Using a different account - -If you need to test your code by sending a transaction from an account (or `Signer` in ethers.js terminology) other than the default one, you can use the `connect()` method on your ethers.js `Contract` object to connect it to a different account, like this: - -```js{18} -const { expect } = require("chai"); - -describe("Token contract", function () { - // ...previous test... - - it("Should transfer tokens between accounts", async function() { - const [owner, addr1, addr2] = await ethers.getSigners(); - - const Token = await ethers.getContractFactory("Token"); - - const hardhatToken = await Token.deploy(); - - // Transfer 50 tokens from owner to addr1 - await hardhatToken.transfer(addr1.address, 50); - expect(await hardhatToken.balanceOf(addr1.address)).to.equal(50); - - // Transfer 50 tokens from addr1 to addr2 - await hardhatToken.connect(addr1).transfer(addr2.address, 50); - expect(await hardhatToken.balanceOf(addr2.address)).to.equal(50); - }); -}); -``` - -### Reusing common test setups with fixtures - -The two tests that we wrote begin with their setup, which in this case means deploying the token contract. In more complex projects, this setup could involve multiple deployments and other transactions. Doing that in every test means a lot of code duplication. Plus, executing many transactions at the beginning of each test can make the test suite much slower. - -You can avoid code duplication and improve the performance of your test suite by using **fixtures**. A fixture is a setup function that is run only the first time it's invoked. On subsequent invocations, instead of re-running it, Hardhat will reset the state of the network to what it was at the point after the fixture was initially executed. - -```js -const { loadFixture } = require("@nomicfoundation/hardhat-network-helpers"); -const { expect } = require("chai"); - -describe("Token contract", function () { - async function deployTokenFixture() { - const Token = await ethers.getContractFactory("Token"); - const [owner, addr1, addr2] = await ethers.getSigners(); - - const hardhatToken = await Token.deploy(); - - await hardhatToken.deployed(); - - // Fixtures can return anything you consider useful for your tests - return { Token, hardhatToken, owner, addr1, addr2 }; - } - - it("Should assign the total supply of tokens to the owner", async function () { - const { hardhatToken, owner } = await loadFixture(deployTokenFixture); - - const ownerBalance = await hardhatToken.balanceOf(owner.address); - expect(await hardhatToken.totalSupply()).to.equal(ownerBalance); - }); - - it("Should transfer tokens between accounts", async function () { - const { hardhatToken, owner, addr1, addr2 } = await loadFixture( - deployTokenFixture - ); - - // Transfer 50 tokens from owner to addr1 - await expect( - hardhatToken.transfer(addr1.address, 50) - ).to.changeTokenBalances(hardhatToken, [owner, addr1], [-50, 50]); - - // Transfer 50 tokens from addr1 to addr2 - // We use .connect(signer) to send a transaction from another account - await expect( - hardhatToken.connect(addr1).transfer(addr2.address, 50) - ).to.changeTokenBalances(hardhatToken, [addr1, addr2], [-50, 50]); - }); -}); -``` - -Here we wrote a `deployTokenFixture` function that does the necessary setup and returns every value we use later in the tests. Then in each test, we use `loadFixture` to run the fixture and get those values. `loadFixture` will run the setup the first time, and quickly return to that state in the other tests. - -### Full coverage - -Now that we've covered the basics that you'll need for testing your contracts, here's a full test suite for the token with a lot of additional information about Mocha and how to structure your tests. We recommend reading it thoroughly. - -```js -// This is an example test file. Hardhat will run every *.js file in `test/`, -// so feel free to add new ones. - -// Hardhat tests are normally written with Mocha and Chai. - -// We import Chai to use its asserting functions here. -const { expect } = require("chai"); - -// We use `loadFixture` to share common setups (or fixtures) between tests. -// Using this simplifies your tests and makes them run faster, by taking -// advantage of Hardhat Network's snapshot functionality. -const { loadFixture } = require("@nomicfoundation/hardhat-network-helpers"); - -// `describe` is a Mocha function that allows you to organize your tests. -// Having your tests organized makes debugging them easier. All Mocha -// functions are available in the global scope. -// -// `describe` receives the name of a section of your test suite, and a -// callback. The callback must define the tests of that section. This callback -// can't be an async function. -describe("Token contract", function () { - // We define a fixture to reuse the same setup in every test. We use - // loadFixture to run this setup once, snapshot that state, and reset Hardhat - // Network to that snapshot in every test. - async function deployTokenFixture() { - // Get the ContractFactory and Signers here. - const Token = await ethers.getContractFactory("Token"); - const [owner, addr1, addr2] = await ethers.getSigners(); - - // To deploy our contract, we just have to call Token.deploy() and await - // its deployed() method, which happens once its transaction has been - // mined. - const hardhatToken = await Token.deploy(); - - await hardhatToken.deployed(); - - // Fixtures can return anything you consider useful for your tests - return { Token, hardhatToken, owner, addr1, addr2 }; - } - - // You can nest describe calls to create subsections. - describe("Deployment", function () { - // `it` is another Mocha function. This is the one you use to define each - // of your tests. It receives the test name, and a callback function. - // - // If the callback function is async, Mocha will `await` it. - it("Should set the right owner", async function () { - // We use loadFixture to setup our environment, and then assert that - // things went well - const { hardhatToken, owner } = await loadFixture(deployTokenFixture); - - // `expect` receives a value and wraps it in an assertion object. These - // objects have a lot of utility methods to assert values. - - // This test expects the owner variable stored in the contract to be - // equal to our Signer's owner. - expect(await hardhatToken.owner()).to.equal(owner.address); - }); - - it("Should assign the total supply of tokens to the owner", async function () { - const { hardhatToken, owner } = await loadFixture(deployTokenFixture); - const ownerBalance = await hardhatToken.balanceOf(owner.address); - expect(await hardhatToken.totalSupply()).to.equal(ownerBalance); - }); - }); - - describe("Transactions", function () { - it("Should transfer tokens between accounts", async function () { - const { hardhatToken, owner, addr1, addr2 } = await loadFixture( - deployTokenFixture - ); - // Transfer 50 tokens from owner to addr1 - await expect( - hardhatToken.transfer(addr1.address, 50) - ).to.changeTokenBalances(hardhatToken, [owner, addr1], [-50, 50]); - - // Transfer 50 tokens from addr1 to addr2 - // We use .connect(signer) to send a transaction from another account - await expect( - hardhatToken.connect(addr1).transfer(addr2.address, 50) - ).to.changeTokenBalances(hardhatToken, [addr1, addr2], [-50, 50]); - }); - - it("Should emit Transfer events", async function () { - const { hardhatToken, owner, addr1, addr2 } = await loadFixture( - deployTokenFixture - ); - - // Transfer 50 tokens from owner to addr1 - await expect(hardhatToken.transfer(addr1.address, 50)) - .to.emit(hardhatToken, "Transfer") - .withArgs(owner.address, addr1.address, 50); - - // Transfer 50 tokens from addr1 to addr2 - // We use .connect(signer) to send a transaction from another account - await expect(hardhatToken.connect(addr1).transfer(addr2.address, 50)) - .to.emit(hardhatToken, "Transfer") - .withArgs(addr1.address, addr2.address, 50); - }); - - it("Should fail if sender doesn't have enough tokens", async function () { - const { hardhatToken, owner, addr1 } = await loadFixture( - deployTokenFixture - ); - const initialOwnerBalance = await hardhatToken.balanceOf(owner.address); - - // Try to send 1 token from addr1 (0 tokens) to owner. - // `require` will evaluate false and revert the transaction. - await expect( - hardhatToken.connect(addr1).transfer(owner.address, 1) - ).to.be.revertedWith("Not enough tokens"); - - // Owner balance shouldn't have changed. - expect(await hardhatToken.balanceOf(owner.address)).to.equal( - initialOwnerBalance - ); - }); - }); -}); -``` - -This is what the output of `npx hardhat test` should look like against the full test suite: - -``` -$ npx hardhat test - - Token contract - Deployment - ✓ Should set the right owner - ✓ Should assign the total supply of tokens to the owner - Transactions - ✓ Should transfer tokens between accounts (199ms) - ✓ Should fail if sender doesn’t have enough tokens - ✓ Should update balances after transfers (111ms) - - - 5 passing (1s) -``` - -Keep in mind that when you run `npx hardhat test`, your contracts will be automatically compiled if they've changed since the last time you ran your tests. diff --git a/docs/src/content/tutorial/writing-and-compiling-contracts.md b/docs/src/content/tutorial/writing-and-compiling-contracts.md deleted file mode 100644 index 4c8c2da679..0000000000 --- a/docs/src/content/tutorial/writing-and-compiling-contracts.md +++ /dev/null @@ -1,114 +0,0 @@ -# 4. Writing and compiling smart contracts - -We're going to create a simple smart contract that implements a token that can be transferred. Token contracts are most frequently used to exchange or store value. We won't go in depth into the Solidity code of the contract on this tutorial, but there's some logic we implemented that you should know: - -- There is a fixed total supply of tokens that can't be changed. -- The entire supply is assigned to the address that deploys the contract. -- Anyone can receive tokens. -- Anyone with at least one token can transfer tokens. -- The token is non-divisible. You can transfer 1, 2, 3 or 37 tokens but not 2.5. - -:::tip - -You might have heard about ERC-20, which is a token standard in Ethereum. Tokens such as DAI and USDC implement the ERC-20 standard which allows them all to be compatible with any software that can deal with ERC-20 tokens. For the sake of simplicity, the token we're going to build does _not_ implement the ERC-20 standard. - -::: - -## Writing smart contracts - -Start by creating a new directory called `contracts` and create a file inside the directory called `Token.sol`. - -Paste the code below into the file and take a minute to read the code. It's simple and it's full of comments explaining the basics of Solidity. - -:::tip - -To get syntax highlighting and editing assistance for Solidity in Visual Studio Code, try [Hardhat for Visual Studio Code](/hardhat-vscode). - -::: - -```solidity -//SPDX-License-Identifier: UNLICENSED - -// Solidity files have to start with this pragma. -// It will be used by the Solidity compiler to validate its version. -pragma solidity ^0.8.9; - - -// This is the main building block for smart contracts. -contract Token { - // Some string type variables to identify the token. - string public name = "My Hardhat Token"; - string public symbol = "MHT"; - - // The fixed amount of tokens, stored in an unsigned integer type variable. - uint256 public totalSupply = 1000000; - - // An address type variable is used to store ethereum accounts. - address public owner; - - // A mapping is a key/value map. Here we store each account's balance. - mapping(address => uint256) balances; - - // The Transfer event helps off-chain applications understand - // what happens within your contract. - event Transfer(address indexed _from, address indexed _to, uint256 _value); - - /** - * Contract initialization. - */ - constructor() { - // The totalSupply is assigned to the transaction sender, which is the - // account that is deploying the contract. - balances[msg.sender] = totalSupply; - owner = msg.sender; - } - - /** - * A function to transfer tokens. - * - * The `external` modifier makes a function *only* callable from *outside* - * the contract. - */ - function transfer(address to, uint256 amount) external { - // Check if the transaction sender has enough tokens. - // If `require`'s first argument evaluates to `false` then the - // transaction will revert. - require(balances[msg.sender] >= amount, "Not enough tokens"); - - // Transfer the amount. - balances[msg.sender] -= amount; - balances[to] += amount; - - // Notify off-chain applications of the transfer. - emit Transfer(msg.sender, to, amount); - } - - /** - * Read only function to retrieve the token balance of a given account. - * - * The `view` modifier indicates that it doesn't modify the contract's - * state, which allows us to call it without executing a transaction. - */ - function balanceOf(address account) external view returns (uint256) { - return balances[account]; - } -} -``` - -:::tip - -`*.sol` is used for Solidity files. We recommend matching the file name to the contract it contains, which is a common practice. - -::: - -## Compiling contracts - -To compile the contract run `npx hardhat compile` in your terminal. The `compile` task is one of the built-in tasks. - -``` -$ npx hardhat compile -Compiling 1 file with 0.8.9 -Compilation finished successfully -``` - -The contract has been successfully compiled and it's ready to be used. diff --git a/docs/src/global-tabs.tsx b/docs/src/global-tabs.tsx deleted file mode 100644 index a5bf83e662..0000000000 --- a/docs/src/global-tabs.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import React, { useCallback, useEffect, useMemo, useState } from "react"; -import tabsConfig from "../temp/tabsConfig.json"; - -type TabType = string; - -export interface ITabsState { - [key: TabType]: string; -} - -interface ITabsContext { - tabsState: ITabsState; - changeTab: (type: string, value: string) => void; - setTabsState: React.Dispatch>; -} - -export const GlobalTabsContext = React.createContext({ - tabsState: {}, - changeTab: () => {}, - setTabsState: () => {}, -}); - -export const generateTabsGroupType = (options: string): string => { - return options - .split(",") - .map((option) => option.trim()) - .join("/"); -}; - -export const TabsProvider = ({ - children, -}: React.PropsWithChildren<{}>): JSX.Element => { - const [tabsState, setTabsState] = useState(tabsConfig); - - const changeTab = useCallback( - (type, value) => { - const newTabsState = { - ...tabsState, - [type]: value, - }; - setTabsState(newTabsState); - }, - [tabsState, setTabsState] - ); - - useEffect(() => { - const savedTabsState = localStorage.getItem("tabs"); - if (savedTabsState === null) return; - - setTabsState({ - ...tabsConfig, - ...JSON.parse(savedTabsState), - }); - }, []); - - useEffect(() => { - localStorage.setItem("tabs", JSON.stringify(tabsState)); - }, [tabsState]); - - const initialContext = useMemo( - () => ({ tabsState, changeTab, setTabsState }), - [tabsState, changeTab, setTabsState] - ); - - return ( - - {children} - - ); -}; diff --git a/docs/src/hooks/useWindowSize.ts b/docs/src/hooks/useWindowSize.ts deleted file mode 100644 index 85bda13e62..0000000000 --- a/docs/src/hooks/useWindowSize.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { useEffect, useState } from "react"; - -export interface WindowSizeState { - width: number; - height: number; -} - -function handleResize({ - setWindowSize, - windowObject, -}: { - setWindowSize: (state: WindowSizeState) => void; - windowObject: Window; -}) { - setWindowSize({ - width: windowObject.innerWidth, - height: windowObject.innerHeight, - }); -} - -export default function useWindowSize(): WindowSizeState { - const [windowSize, setWindowSize] = useState({ - width: 0, - height: 0, - }); - - useEffect(() => { - if (typeof window !== "undefined") { - const listener = () => - handleResize({ setWindowSize, windowObject: window }); - - window.addEventListener("resize", listener); - - handleResize({ setWindowSize, windowObject: window }); - - return () => { - window.removeEventListener("resize", listener); - }; - } - return () => {}; - }, []); - - return windowSize; -} diff --git a/docs/src/model/layout.tsx b/docs/src/model/layout.tsx deleted file mode 100644 index 1fe6abfcf1..0000000000 --- a/docs/src/model/layout.tsx +++ /dev/null @@ -1,420 +0,0 @@ -import glob from "glob"; -import fs from "fs"; -import yaml from "js-yaml"; - -import { - getHrefByFile, - getMDFiles, - parseMdFile, - readMDFileFromPathOrIndex, -} from "./markdown"; -import { DirInfoConfigKeys, DOCS_PATH, TEMP_PATH } from "../config"; -import { getPluginsSubitems } from "./plugins"; - -import { - SectionType, - OrderType, - DirInfo, - Layout, - LayoutsInfo, - FolderWithFiles, - FolderInfo, - FolderType, - FoldersConfig, - TocSubitem, - TocItem, - FlatTocItem, - InfoFiles, -} from "./types"; - -const toCapitalCase = (str: string): string => { - // @ts-ignore - const [c, ...rest] = str; - return `${c.toUpperCase()}${rest.join("")}`; -}; - -const getDefaultConfig = (folder: FolderInfo): DirInfo => { - const config = { - [DirInfoConfigKeys.SECTION_TYPE]: SectionType.GROUP, - [DirInfoConfigKeys.SECTION_TITLE]: toCapitalCase(folder.path), - order: folder.files.map(({ file }) => - file.replace(/\.mdx?$/, "").replace(new RegExp(`^${folder.path}`), "") - ), - }; - - return config; -}; - -const getLayoutsInfo = (): LayoutsInfo => { - const fullPath = `${DOCS_PATH}/layouts.yaml`; - const yamlText = fs.readFileSync(fullPath).toString(); - const yamlData = yaml.load(yamlText) as LayoutsInfo; - return yamlData; -}; - -export const getDirInfoFiles = (): InfoFiles => - glob - .sync(`${DOCS_PATH}**/_dirinfo.yaml`) - .filter((pathname) => /\.yaml$/.test(pathname)) - .map((pathname) => pathname.replace(DOCS_PATH, "")) - .map((pathname) => ({ - path: pathname, - })); - -export const getYamlData = (relativePath: string): DirInfo => { - const fullPath = `${DOCS_PATH}/${relativePath}`; - const yamlText = fs.readFileSync(fullPath).toString(); - const yamlData = yaml.load(yamlText) as DirInfo; - return yamlData; -}; - -export const getFoldersInfo = (infoFiles: InfoFiles): FoldersConfig => - infoFiles.map(({ path }) => ({ - path, - folder: path.replace("/_dirinfo.yaml", ""), - config: getYamlData(path), - })); - -export const getAllFolders = (mdFiles: string[]): FolderWithFiles[] => { - const filesWithPaths = mdFiles.map((fileName) => ({ - fileName, - path: fileName.replace(/\/.*\.mdx?$/, ""), - })); - // @ts-ignore - const allPaths = [...new Set(filesWithPaths.map(({ path }) => path))]; - const folders = allPaths.map((path) => ({ - path, - files: filesWithPaths - .filter((fl) => fl.path === path) - .map(({ fileName }) => fileName), - })); - - return folders; -}; - -const matchFoldersToLayouts = ( - folders: FolderWithFiles[], - layouts: LayoutsInfo, - foldersInfo: FoldersConfig -): Array => { - const layoutsList = Object.entries(layouts).map(([layoutKey, lt]) => ({ - layoutKey, - ...lt, - })); - - const allFolderPaths = new Set([ - ...folders.map(({ path }) => path), - ...foldersInfo.map(({ folder }) => folder), - ]); - - // @ts-ignore - return [...allFolderPaths].map((path) => { - const lt = layoutsList.find(({ folders: ff }) => ff.includes(path)); - if (!lt) { - throw new Error( - `Folder ${path} isn't included to any layout. Please specify it in ${DOCS_PATH}/layouts.yaml file. If you don't want to list it in the sidebar, use "section-type: hidden" in _dirinfo.yaml` - ); - } - const fld = folders.find((f) => f.path === path); - const fldInfo = foldersInfo.find((f) => f.folder === path); - if ( - fldInfo && - fldInfo.config[DirInfoConfigKeys.SECTION_TYPE] === SectionType.PLUGINS - ) { - const virtualFiles = fldInfo?.config?.order?.map((file: string | {}) => { - if (typeof file === "object") { - return file; - } - return { - file, - href: file, - }; - }); - - return { - path, - files: virtualFiles, - layout: lt, - [DirInfoConfigKeys.SECTION_TYPE]: SectionType.PLUGINS, - }; - } - const files = - fld?.files?.map((file) => ({ file, href: getHrefByFile(file) })) || null; - return { - path, - files, - layout: lt, - [DirInfoConfigKeys.SECTION_TYPE]: fldInfo?.config - ? fldInfo?.config[DirInfoConfigKeys.SECTION_TYPE] - : undefined, - }; - }); -}; - -const getSubitems = (path: string, order: OrderType[]): TocSubitem[] => { - const items = order.map((item) => { - if (typeof item === "object") { - return { - label: item.title, - href: `/${path}${item.href}`, - }; - } - - const fullName = `${path}${item}.md`; - const { source } = readMDFileFromPathOrIndex(`${DOCS_PATH}${fullName}`); - - const { tocTitle } = parseMdFile(source); - - return { - href: `/${path}${item}`, - label: tocTitle || item, - }; - }); - return items; -}; - -const generateGroupSection = (folder: FolderType) => { - const tocItem = { - label: folder[DirInfoConfigKeys.SECTION_TITLE], - type: folder[DirInfoConfigKeys.SECTION_TYPE], - children: folder.order?.length - ? getSubitems(folder.path, folder.order) - : undefined, - }; - - return tocItem; -}; - -const generateSingleSection = (folder: FolderType) => { - const tocItem = { - label: folder[DirInfoConfigKeys.SECTION_TITLE], - href: folder[DirInfoConfigKeys.SECTION_URL] ?? `/${folder.path}`, - type: folder[DirInfoConfigKeys.SECTION_TYPE], - children: folder.order?.length - ? getSubitems(folder.path, folder.order) - : undefined, - }; - - return tocItem; -}; - -const generateHiddenSection = () => null; - -const generatePluginsSection = (folder: FolderType) => { - const tocItem = { - label: - folder[DirInfoConfigKeys.SECTION_TITLE] || toCapitalCase(folder.path), - type: folder[DirInfoConfigKeys.SECTION_TYPE], - children: getPluginsSubitems(folder.path, folder.order), - }; - - return tocItem; -}; - -const sectionTypeGeneratorsMap = { - [SectionType.GROUP]: generateGroupSection, - [SectionType.SINGLE]: generateSingleSection, - [SectionType.HIDDEN]: generateHiddenSection, - [SectionType.PLUGINS]: generatePluginsSection, -}; - -const generateTocItem = (fld: null | FolderType): TocItem | null => { - if (!fld) { - return null; - } - const sectionType = fld[DirInfoConfigKeys.SECTION_TYPE] as - | SectionType - | string; - // @ts-ignore - const sectionGenerator = sectionTypeGeneratorsMap[sectionType]; - - if (!sectionGenerator) { - throw new Error(`wrong section-type - ${sectionType} (see ${fld.path})`); - } - - return sectionGenerator(fld); -}; - -const getItemByHref = - (flatTocList: FlatTocItem[]) => - ( - href: string, - needSkipSearch: boolean - ): - | { - prev: TocSubitem; - next: TocSubitem; - } - | {} => { - if (needSkipSearch) { - return {}; - } - const items = flatTocList.filter((item) => { - if (!item?.href) { - return false; - } - const itemHref = item.href.replace(/#.*$/, "").replace(/\/$/, ""); - return itemHref === href; - }); - if (!items.length) { - // throw new Error(`Can't find menu entry for ${href} URL`); - return {}; - } - const first = items[0] as FlatTocItem; - const last = items[items.length - 1] as FlatTocItem; - return { - prev: first.prev, - next: last.next, - }; - }; - -const getPluginsItems = ( - layoutNavigations: FlatTocItem[], - folder: FolderInfo & { - layout: Layout; - } -): Array => { - const pluginItems = layoutNavigations.filter(({ href }) => - /\/plugins/.test(href) - ); - - return pluginItems.map((item) => ({ - ...item, - file: item.label, - folder: folder.path, - layout: folder.layout.layoutKey, - })); -}; - -const getLayoutToc = ( - layout: Layout, - foldersStructure: Array<{ - path: string; - files: Array<{ - file: string; - href: string; - }>; - layout: Layout; - }> -): { tocItems: TocItem[]; flatTocList: FlatTocItem[] } => { - const tocItems = layout.folders - .map((fldName: string) => { - const fld = foldersStructure.find( - ({ path }: { path: string }) => path === fldName - ); - return fld; - }) - // @ts-ignore - .map(generateTocItem) - .filter(Boolean) as TocItem[]; - - const flatTocList = tocItems - .flatMap((item: TocItem | TocSubitem) => { - if ((item as TocItem).children) { - return (item as TocItem).children; - } - return [item]; - }) - .map((item, index, list) => { - const prev = index > 0 ? list[index - 1] : null; - const next = index < list.length - 1 ? list[index + 1] : null; - return { - ...item, - prev, - next, - }; - }) as FlatTocItem[]; - - return { tocItems, flatTocList }; -}; - -export const createLayouts = () => { - const infoFiles = getDirInfoFiles(); - const foldersInfo = getFoldersInfo(infoFiles); - const mdFiles = getMDFiles(); - const folders = getAllFolders(mdFiles); - - const layouts = getLayoutsInfo(); - - const foldersWithLayouts = matchFoldersToLayouts( - folders, - layouts, - foldersInfo - ); - const foldersStructure = foldersWithLayouts.map((fld) => ({ - ...fld, - ...(foldersInfo.find(({ folder }) => folder === fld.path)?.config || - getDefaultConfig(fld)), - })); - - const layoutConfigAndNavigation = Object.entries(layouts).map(([key, l]) => { - const layoutToc = getLayoutToc(l, foldersStructure); - return { - config: { - [key]: layoutToc.tocItems, - }, - navigation: layoutToc.flatTocList, - }; - }); - - const layoutConfigs = layoutConfigAndNavigation.reduce( - (acc, obj) => ({ - ...acc, - ...obj.config, - }), - {} - ); - - const layoutNavigations = layoutConfigAndNavigation.flatMap( - (l) => l.navigation - ); - - const getNavigation = getItemByHref(layoutNavigations); - - const layoutsMap = foldersWithLayouts - .map((folder) => - folder.files - ?.map((fileEntry) => { - if (folder[DirInfoConfigKeys.SECTION_TYPE] === SectionType.PLUGINS) { - const pluginItems = getPluginsItems(layoutNavigations, folder); - return pluginItems; - } - // @ts-ignore - const { prev, next } = getNavigation( - `/${fileEntry.href}`, - folder[DirInfoConfigKeys.SECTION_TYPE] === SectionType.HIDDEN - ); - return [ - { - file: fileEntry.file, - href: fileEntry.href, - folder: folder.path, - layout: folder.layout.layoutKey, - prev, - next, - }, - ]; - }) - .flat() - ) - .filter(Boolean) - .flat() - .reduce( - (acc, obj) => ({ - ...acc, - [obj.file]: obj, - }), - {} - ); - - /** - * We generating this config once per build from `getStaticPaths`. - * After that we writing the config to a temporary file for reusing this data from `getStaticProps` on page generations. - * So each single page don't need to execute this function again - */ - const sidebarConfigPath = `${TEMP_PATH}sidebarConfig.json`; - fs.writeFileSync( - sidebarConfigPath, - JSON.stringify({ layoutConfigs, layoutsMap }) - ); -}; diff --git a/docs/src/model/markdown.tsx b/docs/src/model/markdown.tsx deleted file mode 100644 index 935ff15812..0000000000 --- a/docs/src/model/markdown.tsx +++ /dev/null @@ -1,341 +0,0 @@ -import React from "react"; -import path from "path"; -import glob from "glob"; -import fs from "fs"; -import { execSync } from "child_process"; -import { MDXRemoteSerializeResult } from "next-mdx-remote"; -import matter from "gray-matter"; -import remarkDirective from "remark-directive"; -import { serialize } from "next-mdx-remote/serialize"; -import { visit } from "unist-util-visit"; -import { h } from "hastscript"; -import remarkGfm from "remark-gfm"; -import remarkUnwrapImages from "remark-unwrap-images"; -import rehypePrism from "rehype-prism"; -import remarkPrism from "remark-prism"; - -import { DOCS_PATH, REPO_URL, TEMP_PATH } from "../config"; -import { ITabsState } from "../global-tabs"; - -export const newLineDividerRegEx = /\r\n|\n/; - -export const withIndexURL = (pathname: string): string[] => { - const docPath = pathname.split("/"); - if (docPath[docPath.length - 1] === "index") { - return [...docPath.slice(0, docPath.length - 1)]; - } - return docPath; -}; - -export const withIndexFile = (docPath: string[]): string => { - const mdFilePath = path.join(DOCS_PATH, `${docPath.join("/")}.md`); - return mdFilePath; -}; - -export const withCodeElementWrapper = ( - content: string, - extension: string = "", - highlightedLinesNumbers: string = "" -) => { - const stringNumbersEntity = - highlightedLinesNumbers.length > 0 ? `{${highlightedLinesNumbers}}` : ""; - - return `\`\`\`${extension ?? "markup"}${stringNumbersEntity} -${content} - \`\`\``; -}; - -export const getEntriesInfo = ( - line: string -): { - pathname: string; - highlightedLinesNumbers: string; -} => { - const highlightedLinesNumbers: string | null = line.includes("{") - ? line.substring(line.indexOf("{")).replace(/[{}]/g, "").trim() - : ""; - - const pathname = ( - highlightedLinesNumbers ? line.substring(0, line.indexOf("{")) : line - ) - .replace("<<< @/", "") - .trim(); - - return { - pathname, - highlightedLinesNumbers, - }; -}; - -export const readFileContent = (pathname: string) => { - try { - return fs.readFileSync(pathname).toString(); - } catch (err) { - throw new Error(`Cannot read file from: ${pathname}`); - } -}; - -export const getFileExtensionFromPathname = (pathname: string) => { - return pathname.substring(pathname.lastIndexOf(".") + 1); -}; - -export const withInsertedCodeFromLinks = (content: string) => { - return content - .split(newLineDividerRegEx) - .map((line: string) => { - if (!line.startsWith("<<<")) return line; - - const { pathname, highlightedLinesNumbers } = getEntriesInfo(line); - - const fileContent = readFileContent(pathname); - const fileExtension = getFileExtensionFromPathname(pathname); - - return withCodeElementWrapper( - fileContent, - fileExtension, - highlightedLinesNumbers - ); - }) - .join("\n"); -}; - -export const withoutComments = (content: string) => { - return content.replace(//gm, ""); -}; - -export const readMDFileFromPathOrIndex = ( - fileName: string -): { source: string; fileName: string } => { - try { - const source = fs.readFileSync(fileName).toString(); - return { - source, - fileName, - }; - } catch (err) { - const file = fileName.replace(".md", "/index.md"); - const source = fs.readFileSync(file).toString(); - return { - source, - fileName: file, - }; - } -}; - -/** @type {import("unified").Plugin<[], import("mdast").Root>} */ -function createCustomNodes() { - // @ts-ignore - return (tree) => { - visit(tree, (node) => { - if ( - node.type === "textDirective" || - node.type === "leafDirective" || - node.type === "containerDirective" - ) { - // eslint-disable-next-line - const data = node.data || (node.data = {}); - const hast = h(node.name, node.attributes); - // Create custom nodes from extended MD syntax. E.g. "tip"/"warning" - // @ts-ignore - data.hName = hast.tagName; - // @ts-ignore - data.hProperties = hast.properties; - } - }); - }; -} - -/** @type {import("unified").Plugin<[], import("mdast").Root>} */ -function setDefaultLang() { - // @ts-ignore - return (tree) => { - visit(tree, (node) => { - if (node.type === "code" && !node.lang) { - // eslint-disable-next-line - node.lang = "markup"; - } - }); - }; -} - -function validateTabs() { - // @ts-ignore - return (tree) => { - const initialTabsState: ITabsState = {}; - visit(tree, (node) => { - if (node.type === "containerDirective" && node.name === "tabsgroup") { - node.children?.forEach( - ( - child: React.ReactElement & { - data: { - hName: string; - hProperties: { value: string }; - }; - } - ) => { - const { options } = node.attributes; - if (!options.split(",").includes(child.data.hProperties.value)) { - throw new Error( - `Value "${child.data.hProperties.value}" is not provided in TabsGroups options.` - ); - } - initialTabsState[options.split(",").join("/")] = options - .split(",")[0] - .trim(); - } - ); - } - }); - const tabsConfigPath = `${TEMP_PATH}tabsConfig.json`; - fs.writeFileSync(tabsConfigPath, JSON.stringify(initialTabsState)); - }; -} - -export const generateTitleFromContent = (content: string) => { - return content - .split(newLineDividerRegEx) - .filter((line) => line.startsWith("#"))[0] - ?.replace(/[#]*/g, "") - .trim(); -}; - -export const parseMdFile = (source: string) => { - const { content, data } = matter(source); - const formattedContent = withoutComments(withInsertedCodeFromLinks(content)); - - const tocTitle = data.title ?? generateTitleFromContent(formattedContent); - const seoTitle = tocTitle || "Hardhat"; - const seoDescription = - data.title || - "Ethereum development environment for professionals by Nomic Foundation"; - - return { - rawContent: content, - formattedContent, - data, - tocTitle, - seoTitle, - seoDescription, - }; -}; - -export const prepareMdContent = async ( - source: string -): Promise<{ - mdxSource: MDXRemoteSerializeResult; - data: { - [key: string]: any; - }; - seoTitle: string; - seoDescription: string; -}> => { - const { formattedContent, ...props } = parseMdFile(source); - let mdxSource: MDXRemoteSerializeResult>; - try { - mdxSource = await serialize(formattedContent, { - mdxOptions: { - remarkPlugins: [ - remarkGfm, - remarkDirective, - createCustomNodes, - remarkUnwrapImages, - setDefaultLang, - remarkPrism, - validateTabs, - ], - - rehypePlugins: [ - [ - rehypePrism, - { - plugins: ["line-highlight"], - }, - ], - ], - }, - }); - } catch (error: unknown) { - throw new Error(error as string); - } - - return { - mdxSource, - ...props, - }; -}; - -export const getMDFiles = (): string[] => - glob - .sync(`${DOCS_PATH}**/*.md`) - .filter( - (pathname) => - /\.mdx?$/.test(pathname) && !pathname.includes("plugins/index.md") - ) - .map((pathname) => pathname.replace(DOCS_PATH, "")); - -export const getPathParamsByFile = (pathname: string): string[] => { - const fileBase = pathname.replace(/\.mdx?$/, ""); - return withIndexURL(fileBase); -}; - -export const getHrefByFile = (pathname: string): string => { - const params = getPathParamsByFile(pathname); - return path.join(...params); -}; - -export const getMDPaths = (): Array<{ params: { docPath: string[] } }> => - getMDFiles().map((pathname) => ({ - params: { - docPath: getPathParamsByFile(pathname), - }, - })); - -export const getSidebarConfig = () => { - try { - const sidebarConfigPath = `${TEMP_PATH}sidebarConfig.json`; - const configText = fs.readFileSync(sidebarConfigPath).toString(); - const config = JSON.parse(configText); - const { layoutConfigs, layoutsMap } = config; - return { layoutConfigs, layoutsMap }; - } catch (err) { - console.error(err); - throw new Error(`Can't read sidebar configs. See the error above`); - } -}; - -export const getLayout = (fileName: string) => { - /** - * Layout configs is generated from content folder based on .yaml and .md files. - * The config contains information for all pages at once - * This happens by executing `createLayouts` function from `getStaticPaths`. - * In order to optimize build time we store that config in a temporary file - * (as getStaticPaths and getStaticProps executed in isolated environments, so it's the only way to pass information) - */ - const { layoutConfigs, layoutsMap } = getSidebarConfig(); - const fileNameKey = fileName.replace(DOCS_PATH, ""); - const { layout, prev = null, next = null } = layoutsMap[fileNameKey]; - return { layout: layoutConfigs[layout], prev, next }; -}; - -export const getCommitDate = (fileName: string): string => { - const output = execSync( - `git log -1 --pretty="format:%cI" ${fileName}` - ).toString(); - return output; -}; - -export const getEditLink = (fileName: string): string => { - // the errors page is a special case because it's auto-generated - const errorsFile = path.join( - "content", - "hardhat-runner", - "docs", - "errors", - "index.md" - ); - if (fileName.endsWith(errorsFile)) { - return "https://github.com/NomicFoundation/hardhat/edit/main/packages/hardhat-core/src/internal/core/errors-list.ts"; - } - - return fileName.replace(DOCS_PATH, REPO_URL); -}; diff --git a/docs/src/model/plugins.tsx b/docs/src/model/plugins.tsx deleted file mode 100644 index 066177a008..0000000000 --- a/docs/src/model/plugins.tsx +++ /dev/null @@ -1,145 +0,0 @@ -import path from "path"; -import { request } from "undici"; -import { getSidebarConfig, readFileContent } from "./markdown"; -import { IPlugin, OrderType, SectionType, TocItem, TocSubitem } from "./types"; -import plugins from "../content/hardhat-runner/plugins/plugins"; - -/** - * NOTE: here we assumes that "Plugins" menu items only belongs to ${PLUGINS_LAYOUT} layout. - * This means the information for generating static pages will be found in this layout from a section - * with section-type == plugin (section is a folder in content) - * We also assume that only one section with plugins exists - * Additionally we hardcode plugins pages path to `/pages/plugins/...` - * - * If you ever need to extend this behavior see `getPluginsPaths` function. - * e.g. for adding a plugin section to another layout start reading `content/layouts.yaml` - * as a source of actual layouts configuration - */ -const PLUGINS_LAYOUT = "hardhat-runner"; - -export const generateSlug = (pluginName: string): string => - pluginName.replace(/^@/, "").replace(/\//g, "-"); - -export const getPluginsSubitems = ( - folderPath: string, - order: OrderType[] -): TocSubitem[] => { - return order.map((item: OrderType) => { - if (typeof item === "object") { - return { - label: item.title, - href: item.href, - }; - } - return { - label: item, - href: `/${folderPath}/${generateSlug(item)}`, - }; - }); -}; - -export const getPluginsPaths = (): Array<{ params: { plugin: string } }> => { - try { - const { layoutConfigs } = getSidebarConfig(); - const config = layoutConfigs[PLUGINS_LAYOUT] as TocItem[]; - const pluginsSection = config.find( - ({ type }) => type === SectionType.PLUGINS - ); - if (!pluginsSection?.children) { - throw new Error( - `Section with type=plugins is missed or empty. Check content/hardhat-runner/plugins/_dirinfo.yaml` - ); - } - return pluginsSection.children - .map(({ href }) => href.replace(/^\/hardhat-runner\/plugins\//, "")) - .filter((slug) => slug[0] !== "#") - .map((slug) => ({ - params: { - plugin: slug, - }, - })); - } catch (err) { - console.error(err); - throw new Error( - `Error while generation plugin page paths. See details above` - ); - } -}; - -const getPluginReadmeFilename = (pluginSlug: string): string => { - const folderName = pluginSlug - .replace("hardhat-runner/plugins/", "") - .replace(/nomiclabs-/, "") - .replace(/nomicfoundation-/, ""); - const rootPath = process.cwd().toString(); - const filename = path.join(rootPath, "../packages/", folderName, "README.md"); - return filename; -}; - -export const getPluginMDSource = (pluginSlug: string) => { - const readmeFilename = getPluginReadmeFilename(pluginSlug); - const source = readFileContent(readmeFilename).toString(); - return source; -}; - -export const sortPluginsByDownloads = (downloadsD: { - [key: string]: number; -}) => { - try { - plugins.communityPlugins.sort( - (p1: IPlugin, p2: IPlugin) => downloadsD[p2.name] - downloadsD[p1.name] - ); - } catch { - // we just don't sort here - } -}; - -const getLastMonthDownloads = async (npmPackage: string): Promise => { - const res = await request( - `https://api.npmjs.org/downloads/point/last-month/${npmPackage}`, - { - method: "GET", - headers: { - "Content-Type": "application/json", - Accept: "application/json", - }, - } - ); - - if (res.statusCode === 404) { - return 0; - } - - const json = (await res.body.json()) as { downloads: number }; - - return json.downloads; -}; - -export const generatePluginsDownloads = async (pluginsD: typeof plugins) => { - const downloads: Array<{ [plugin: string]: number }> = await Promise.all( - pluginsD.communityPlugins.map(async (p: any) => ({ - [p.name]: await getLastMonthDownloads(p.npmPackage ?? p.name), - })) - ); - - downloads.sort((p1, p2) => Object.values(p2)[0] - Object.values(p1)[0]); - - const result = Object.assign({}, ...downloads); - return result; -}; - -export const addNormalizedName = (pluginsList: IPlugin[]) => { - return pluginsList.map((p) => ({ - ...p, - normalizedName: p.name.split("/").join("-").replace(/^@/, ""), - })); -}; - -export const getPlugins = async () => { - const generatedPluginsDownloads = await generatePluginsDownloads(plugins); - sortPluginsByDownloads(generatedPluginsDownloads); - plugins.officialPlugins = addNormalizedName(plugins.officialPlugins); - return plugins; -}; - -export type PluginsList = typeof plugins; diff --git a/docs/src/model/types.ts b/docs/src/model/types.ts deleted file mode 100644 index df8ba55408..0000000000 --- a/docs/src/model/types.ts +++ /dev/null @@ -1,99 +0,0 @@ -import { DirInfoConfigKeys, LayoutsConfigKeys } from "../config"; - -export enum SectionType { - SINGLE = "single", - GROUP = "group", - HIDDEN = "hidden", - PLUGINS = "plugins", -} - -export type OrderType = - | string - | { - href: string; - title: string; - }; - -export interface DirInfo { - [DirInfoConfigKeys.SECTION_TYPE]: SectionType; - [DirInfoConfigKeys.SECTION_TITLE]: string; - [DirInfoConfigKeys.ORDER]: OrderType[]; -} - -export interface Layout { - [LayoutsConfigKeys.TITLE]: string; - [LayoutsConfigKeys.FOLDERS]: string[]; - layoutKey?: string; -} - -export interface LayoutsInfo { - [layoutKey: string]: Layout; -} - -export interface FolderWithFiles { - path: string; - files: string[]; -} - -export interface FolderInfo { - path: string; - files: Array<{ file: string; href: string }>; - [DirInfoConfigKeys.SECTION_TYPE]: SectionType; -} - -export interface FolderType { - [DirInfoConfigKeys.SECTION_TYPE]: SectionType; - [DirInfoConfigKeys.SECTION_TITLE]: string; - [DirInfoConfigKeys.SECTION_URL]: string | undefined; - [DirInfoConfigKeys.ORDER]: OrderType[]; - path: string; -} - -export type FoldersConfig = Array<{ - path: string; - folder: string; - config: { - [key: string]: any; - }; -}>; - -export interface TocSubitem { - label: string; - href: string; - type?: SectionType; - next?: TocSubitem; - prev?: TocSubitem; -} - -export interface TocItem { - label: string; - type: SectionType; - href?: string; - children?: TocSubitem[]; - // next?: TocSubitem; - // prev?: TocSubitem; -} - -export interface FlatTocItem { - label: string; - href: string; - next?: TocSubitem; - prev?: TocSubitem; -} - -export type InfoFiles = Array<{ path: string }>; - -export interface IFrontMatter { - seoTitle: string; - seoDescription: string; -} - -export interface IPlugin { - name: string; - npmPackage?: string; - author: string; - authorUrl: string; - description: string; - tags: string[]; - normalizedName?: string; -} diff --git a/docs/src/pages/[...docPath].tsx b/docs/src/pages/[...docPath].tsx deleted file mode 100644 index d027e89100..0000000000 --- a/docs/src/pages/[...docPath].tsx +++ /dev/null @@ -1,93 +0,0 @@ -import type { NextPage, GetStaticProps, GetStaticPaths } from "next"; -import { MDXRemoteSerializeResult } from "next-mdx-remote"; - -import { - getCommitDate, - getEditLink, - getLayout, - getMDPaths, - prepareMdContent, - readMDFileFromPathOrIndex, - withIndexFile, -} from "../model/markdown"; -import DocumentationLayout from "../components/DocumentationLayout"; -import { createLayouts } from "../model/layout"; -import { - IDocumentationSidebarStructure, - IFooterNavigation, -} from "../components/types"; -import { IFrontMatter } from "../model/types"; - -interface IDocPage { - mdxSource: MDXRemoteSerializeResult; - frontMatter: IFrontMatter; - layout: IDocumentationSidebarStructure; - prev: IFooterNavigation; - next: IFooterNavigation; - lastEditDate: string; - editLink: string; -} - -const DocPage: NextPage = ({ - mdxSource, - frontMatter, - layout, - prev, - next, - lastEditDate, - editLink, -}): JSX.Element => { - return ( - - ); -}; - -export default DocPage; - -export const getStaticProps: GetStaticProps = async (props) => { - const { params } = props; - // @ts-ignore - const fullName = withIndexFile(params.docPath); - const { source, fileName } = readMDFileFromPathOrIndex(fullName); - const lastEditDate = getCommitDate(fileName); - const editLink = getEditLink(fileName); - - const { mdxSource, data, seoTitle, seoDescription } = await prepareMdContent( - source - ); - const { layout, next, prev } = getLayout(fileName); - - return { - props: { - mdxSource, - frontMatter: { - ...data, - seoTitle, - seoDescription, - }, - layout, - next: data.next ? next : false, - prev: data.prev ? prev : false, - lastEditDate, - editLink, - }, - }; -}; - -export const getStaticPaths: GetStaticPaths = async () => { - const paths = getMDPaths(); - createLayouts(); - - return { - paths, - fallback: false, - }; -}; diff --git a/docs/src/pages/_app.tsx b/docs/src/pages/_app.tsx deleted file mode 100644 index ad4c59574c..0000000000 --- a/docs/src/pages/_app.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import React from "react"; -import type { AppProps } from "next/app"; -import "../styles/globals.css"; -import "../styles/prism.css"; -import { TabsProvider } from "../global-tabs"; - -function MyApp({ Component, pageProps }: AppProps) { - return ( - - {/* @ts-ignore */} - - - ); -} - -export default MyApp; diff --git a/docs/src/pages/_document.tsx b/docs/src/pages/_document.tsx deleted file mode 100644 index 799a7b3c4e..0000000000 --- a/docs/src/pages/_document.tsx +++ /dev/null @@ -1,56 +0,0 @@ -/* eslint-disable react/no-danger */ -import { Html, Head, Main, NextScript } from "next/document"; - -const MeasurementID = process.env.NEXT_PUBLIC_MEASUREMENT_ID as string; - -export default function Document() { - return ( - - - - - - + + + diff --git a/packages/hardhat-ignition-ui/package.json b/packages/hardhat-ignition-ui/package.json new file mode 100644 index 0000000000..02104bb5fe --- /dev/null +++ b/packages/hardhat-ignition-ui/package.json @@ -0,0 +1,46 @@ +{ + "name": "@nomicfoundation/ignition-ui", + "version": "0.15.11", + "type": "module", + "scripts": { + "predev": "pnpm regenerate-deployment-example", + "dev": "vite --force", + "build": "tsc --build . && vite build", + "test": "mocha --loader=ts-node/esm --recursive \"test/**/*.ts\"", + "test:coverage": "nyc mocha --loader=ts-node/esm --recursive \"test/**/*.ts\"", + "regenerate-deployment-example": "node ./scripts/generate-example-deployment-json.js", + "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview", + "clean": "rimraf dist tsconfig.tsbuildinfo", + "prepack": "pnpm build" + }, + "devDependencies": { + "@fontsource/roboto": "^5.0.8", + "@nomicfoundation/ignition-core": "workspace:^", + "@types/chai": "^4.2.22", + "@types/chai-as-promised": "^7.1.5", + "@types/mocha": "9.1.1", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", + "@types/styled-components": "5.1.26", + "@typescript-eslint/parser": "^5.57.1", + "@vitejs/plugin-react": "^4.0.0", + "chai": "^4.3.4", + "chai-as-promised": "7.1.1", + "eslint": "^8.38.0", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.3.4", + "mermaid": "10.9.3", + "mocha": "^9.1.3", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "6.11.0", + "react-tooltip": "^5.21.4", + "styled-components": "5.3.10", + "svg-pan-zoom": "^3.6.1", + "ts-node": "10.9.1", + "typescript": "^5.0.2", + "vite": "^5.4.17", + "vite-plugin-singlefile": "^2.0.1" + } +} diff --git a/packages/hardhat-ignition-ui/public/.gitkeep b/packages/hardhat-ignition-ui/public/.gitkeep new file mode 100644 index 0000000000..ad88fa0b0f --- /dev/null +++ b/packages/hardhat-ignition-ui/public/.gitkeep @@ -0,0 +1,2 @@ +# To keep the public folder that is used in vite +# Our development server dumps a `deployment.json` here. diff --git a/packages/hardhat-ignition-ui/scripts/generate-example-deployment-json.js b/packages/hardhat-ignition-ui/scripts/generate-example-deployment-json.js new file mode 100644 index 0000000000..caef452f79 --- /dev/null +++ b/packages/hardhat-ignition-ui/scripts/generate-example-deployment-json.js @@ -0,0 +1,31 @@ +import { + IgnitionModuleSerializer, + batches, +} from "@nomicfoundation/ignition-core"; +import { writeFile } from "node:fs/promises"; + +import complexModule from "../examples/ComplexModule.js"; + +const main = async () => { + await writeDeploymentJsonFor(complexModule); +}; + +async function writeDeploymentJsonFor(ignitionModule) { + const serializedIgnitionModule = + IgnitionModuleSerializer.serialize(ignitionModule); + + const moduleBatches = batches(ignitionModule); + + console.log("Deployment written to ./public/deployment.json"); + + await writeFile( + "./public/deployment.json", + JSON.stringify( + { module: serializedIgnitionModule, batches: moduleBatches }, + undefined, + 2 + ) + ); +} + +main(); diff --git a/packages/hardhat-ignition-ui/src/assets/ExternalLinkIcon.tsx b/packages/hardhat-ignition-ui/src/assets/ExternalLinkIcon.tsx new file mode 100644 index 0000000000..58c310609c --- /dev/null +++ b/packages/hardhat-ignition-ui/src/assets/ExternalLinkIcon.tsx @@ -0,0 +1,15 @@ +import React from "react"; + +export const ExternalLinkIcon: React.FC = () => ( + + + + + +); diff --git a/packages/hardhat-ignition-ui/src/assets/TooltipIcon.tsx b/packages/hardhat-ignition-ui/src/assets/TooltipIcon.tsx new file mode 100644 index 0000000000..be04a3273f --- /dev/null +++ b/packages/hardhat-ignition-ui/src/assets/TooltipIcon.tsx @@ -0,0 +1,16 @@ +import React from "react"; + +export const TooltipIcon: React.FC = () => ( + + + +); diff --git a/packages/hardhat-ignition-ui/src/assets/purple-rocket.png b/packages/hardhat-ignition-ui/src/assets/purple-rocket.png new file mode 100644 index 0000000000..374f639397 Binary files /dev/null and b/packages/hardhat-ignition-ui/src/assets/purple-rocket.png differ diff --git a/packages/hardhat-ignition-ui/src/components/mermaid.tsx b/packages/hardhat-ignition-ui/src/components/mermaid.tsx new file mode 100644 index 0000000000..44341da19c --- /dev/null +++ b/packages/hardhat-ignition-ui/src/components/mermaid.tsx @@ -0,0 +1,58 @@ +import React, { useEffect, useMemo } from "react"; +import styled from "styled-components"; +import svgPanZoom from "svg-pan-zoom"; + +import { + IgnitionModule, + IgnitionModuleResult, +} from "@nomicfoundation/ignition-core/ui-helpers"; +import mermaid from "mermaid"; + +import { toMermaid } from "../utils/to-mermaid"; + +export const Mermaid: React.FC<{ + ignitionModule: IgnitionModule>; +}> = ({ ignitionModule }) => { + const diagram = useMemo(() => { + const d = toMermaid(ignitionModule); + + // NOTE: this is explicitly added to aid troubleshooting + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (window as any).diagram = d; + + return d; + }, [ignitionModule]); + + useEffect(() => { + mermaid.initialize({ + maxTextSize: 5000000, + flowchart: { + padding: 50, + }, + }); + + mermaid.contentLoaded(); + }); + + // requestAnimationFrame is used to ensure that the svgPanZoom is called after the svg is rendered + useEffect(() => { + requestAnimationFrame(() => { + setTimeout(() => { + svgPanZoom(".mermaid > svg", { + zoomEnabled: true, + controlIconsEnabled: true, + fit: true, + center: true, + }); + }, 0); + }); + }); + + return ( + +
    {diagram}
    +
    + ); +}; + +const Wrap = styled.div``; diff --git a/docs/src/assets/socials/dc-logo.tsx b/packages/hardhat-ignition-ui/src/components/socials/dc-logo.tsx similarity index 93% rename from docs/src/assets/socials/dc-logo.tsx rename to packages/hardhat-ignition-ui/src/components/socials/dc-logo.tsx index bfef1ccb37..993fe038ca 100644 --- a/docs/src/assets/socials/dc-logo.tsx +++ b/packages/hardhat-ignition-ui/src/components/socials/dc-logo.tsx @@ -1,7 +1,6 @@ -import * as React from "react"; -import { SVGProps, memo } from "react"; +import { SVGProps } from "react"; -const DiscordLogo = (props: SVGProps) => ( +export const DiscordLogo = (props: SVGProps) => ( ) => ( ); - -export default memo(DiscordLogo); diff --git a/docs/src/assets/socials/gh-logo.tsx b/packages/hardhat-ignition-ui/src/components/socials/gh-logo.tsx similarity index 91% rename from docs/src/assets/socials/gh-logo.tsx rename to packages/hardhat-ignition-ui/src/components/socials/gh-logo.tsx index fef3ebd193..4788a54230 100644 --- a/docs/src/assets/socials/gh-logo.tsx +++ b/packages/hardhat-ignition-ui/src/components/socials/gh-logo.tsx @@ -1,7 +1,6 @@ -import * as React from "react"; -import { SVGProps, memo } from "react"; +import { SVGProps } from "react"; -const GitHubLogo = (props: SVGProps) => ( +export const GitHubLogo = (props: SVGProps) => ( ) => ( /> ); - -export default memo(GitHubLogo); diff --git a/packages/hardhat-ignition-ui/src/components/socials/index.tsx b/packages/hardhat-ignition-ui/src/components/socials/index.tsx new file mode 100644 index 0000000000..07454b5e82 --- /dev/null +++ b/packages/hardhat-ignition-ui/src/components/socials/index.tsx @@ -0,0 +1,33 @@ +import { DiscordLogo } from "./dc-logo"; +import { GitHubLogo } from "./gh-logo"; +import { TwitterLogo } from "./tw-logo"; + +export enum SocialsEnum { + GITHUB = "GITHUB", + TWITTER = "TWITTER", + DISCORD = "DISCORD", +} + +const SOCIALS_LINKS = { + [SocialsEnum.GITHUB]: "https://hardhat.org/ignition", + [SocialsEnum.TWITTER]: "https://twitter.com/HardhatHQ", + [SocialsEnum.DISCORD]: "https://hardhat.org/ignition-discord", +}; + +export const socialsItems = [ + { + name: SocialsEnum.GITHUB, + href: SOCIALS_LINKS[SocialsEnum.GITHUB], + Icon: GitHubLogo, + }, + { + name: SocialsEnum.TWITTER, + href: SOCIALS_LINKS[SocialsEnum.TWITTER], + Icon: TwitterLogo, + }, + { + name: SocialsEnum.DISCORD, + href: SOCIALS_LINKS[SocialsEnum.DISCORD], + Icon: DiscordLogo, + }, +]; diff --git a/docs/src/assets/socials/tw-logo.tsx b/packages/hardhat-ignition-ui/src/components/socials/tw-logo.tsx similarity index 88% rename from docs/src/assets/socials/tw-logo.tsx rename to packages/hardhat-ignition-ui/src/components/socials/tw-logo.tsx index e528996b10..a558a2a692 100644 --- a/docs/src/assets/socials/tw-logo.tsx +++ b/packages/hardhat-ignition-ui/src/components/socials/tw-logo.tsx @@ -1,7 +1,6 @@ -import * as React from "react"; -import { SVGProps, memo } from "react"; +import { SVGProps } from "react"; -const TwitterLogo = (props: SVGProps) => ( +export const TwitterLogo = (props: SVGProps) => ( ) => ( ); - -export default memo(TwitterLogo); diff --git a/packages/hardhat-ignition-ui/src/main.css b/packages/hardhat-ignition-ui/src/main.css new file mode 100644 index 0000000000..629528edf6 --- /dev/null +++ b/packages/hardhat-ignition-ui/src/main.css @@ -0,0 +1,86 @@ +body { + font-family: "Roboto", sans-serif; + font-weight: 400; + font-size: 15px; + margin: 0; +} + +.deploy-background { + background: #fffde7; +} + +.call-background { + background: #f8f2ff; +} + +.styled-tooltip { + background-color: #ffffff !important; + color: #9b9fa8 !important; + padding: 1.5rem !important; + opacity: 1 !important; + -webkit-box-shadow: 0px 6px 50px 0px rgba(10, 10, 10, 0.4) !important; + -moz-box-shadow: 0px 6px 50px 0px rgba(10, 10, 10, 0.4) !important; + box-shadow: 0px 6px 50px 0px rgba(10, 10, 10, 0.4) !important; +} + +.styled-tooltip span { + font-weight: 400 !important; +} + +.styled-tooltip * { + font-size: 0.8rem !important; +} + +.batches-tooltip { + max-width: 231px !important; +} + +.batches-tooltip div { + font-weight: 400 !important; +} + +.flow-tooltip { + max-width: 391px !important; +} + +span.future-to-module-arrow { + font-weight: 900 !important; + font-size: medium !important; + letter-spacing: -2px; +} + +/* mermaid styles */ + +.mermaid { + background: #fbfbfb; + height: 500px; +} + +.mermaid * { + font-family: "Roboto", sans-serif; + font-size: 30px; +} + +.mermaid svg { + height: 100%; + vertical-align: middle; + max-width: unset !important; +} + +.mermaid span { + cursor: default; +} + +.mermaid rect { + rx: 5; + ry: 5; +} + +/* selects moduleIds only */ +.clusters .nodeLabel { + font-weight: 700; +} + +.futureNode rect { + stroke: none !important; +} diff --git a/packages/hardhat-ignition-ui/src/main.tsx b/packages/hardhat-ignition-ui/src/main.tsx new file mode 100644 index 0000000000..29478e42a0 --- /dev/null +++ b/packages/hardhat-ignition-ui/src/main.tsx @@ -0,0 +1,93 @@ +import "@fontsource/roboto"; +import "@fontsource/roboto/400.css"; +import "@fontsource/roboto/700.css"; +import React from "react"; + +import { + IgnitionModule, + IgnitionModuleDeserializer, + IgnitionModuleResult, +} from "@nomicfoundation/ignition-core/ui-helpers"; +import ReactDOM from "react-dom/client"; +import { RouterProvider, createHashRouter } from "react-router-dom"; +import { VisualizationOverview } from "./pages/visualization-overview/visualization-overview"; + +import "./main.css"; + +const loadDeploymentFromEmbeddedDiv = (): { + ignitionModule: IgnitionModule>; + batches: string[][]; +} | null => { + const scriptTag = document.getElementById("deployment"); + + if (scriptTag === null || scriptTag.textContent === null) { + return null; + } + + const data = JSON.parse(scriptTag.textContent); + + if (data.unloaded) { + return null; + } + + return { + ignitionModule: IgnitionModuleDeserializer.deserialize(data.module), + batches: data.batches, + }; +}; + +const loadDeploymentFromDevFile = async (): Promise<{ + ignitionModule: IgnitionModule>; + batches: string[][]; +}> => { + const response = await fetch("./deployment.json"); + const data = await response.json(); + + return { + ignitionModule: IgnitionModuleDeserializer.deserialize(data.module), + batches: data.batches, + }; +}; + +const loadDeploymentData = () => { + return loadDeploymentFromEmbeddedDiv() ?? loadDeploymentFromDevFile(); +}; + +const main = async () => { + try { + const { ignitionModule, batches } = await loadDeploymentData(); + + document.title = `${ignitionModule.id} Deployment Visualization - Hardhat Ignition`; + + const router = createHashRouter([ + { + path: "/", + element: ( + + ), + }, + ]); + + ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( + + + + ); + } catch (error) { + console.error(error); + const message = error instanceof Error ? error.message : "unknown error"; + + ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( +
    +

    + Error during deployment loading: {message} +

    +
    + ); + } +}; + +main(); diff --git a/packages/hardhat-ignition-ui/src/pages/visualization-overview/components/deployment-flow.tsx b/packages/hardhat-ignition-ui/src/pages/visualization-overview/components/deployment-flow.tsx new file mode 100644 index 0000000000..99f6f5871f --- /dev/null +++ b/packages/hardhat-ignition-ui/src/pages/visualization-overview/components/deployment-flow.tsx @@ -0,0 +1,209 @@ +import { + IgnitionModule, + IgnitionModuleResult, + isDeploymentFuture, +} from "@nomicfoundation/ignition-core/ui-helpers"; +import React, { useState } from "react"; +import { Tooltip } from "react-tooltip"; +import styled, { css } from "styled-components"; +import { TooltipIcon } from "../../../assets/TooltipIcon"; +import { Mermaid } from "../../../components/mermaid"; +import { getAllFuturesForModule } from "../../../queries/futures"; +import { toEscapedId } from "../../../utils/to-escaped-id"; + +export const DeploymentFlow: React.FC<{ + ignitionModule: IgnitionModule>; + batches: string[][]; +}> = ({ ignitionModule, batches }) => { + /* batch highlighting logic */ + const escapedIdMap = batches.reduce((acc, batch, i) => { + const batchId = `batch-${i}`; + + const escapedFutureIds = batch.map(toEscapedId); + + return { + ...acc, + [batchId]: escapedFutureIds, + }; + }, {} as Record); + + const [currentlyHovered, setCurrentlyHovered] = useState(""); + + const futuresToHighlight = escapedIdMap[currentlyHovered] || []; + + /* basic future node styling */ + + const futures = getAllFuturesForModule(ignitionModule); + const deploys: string[] = []; + const others: string[] = []; + futures.forEach((future) => { + if (isDeploymentFuture(future)) { + deploys.push(toEscapedId(future.id)); + } else { + others.push(toEscapedId(future.id)); + } + }); + + return ( +
    + + Deployment flow + + + {futures.length <= 1 ? ( + + A module diagram will show once you have more than 1 future. + + ) : ( +
    + + Visualize batches + {batches.map((_, i) => ( + setCurrentlyHovered(`batch-${i}`)} + onMouseLeave={() => setCurrentlyHovered("")} + isCurrentlyHovered={currentlyHovered === `batch-${i}`} + > + Batch #{i + 1} + + ))} + + + + + +
    + )} +
    + ); +}; + +const SingleFutureNotice = styled.div` + padding-top: 1rem; +`; + +const VisualizeDiv = styled.div` + font-weight: 700; + padding: 1.5rem; + width: 100%; +`; + +// TODO: when we added the future-to-module dependency, we created a non-ideal situation where +// a module-to-module dependency arrow still gets added to the mermaid graph, even if the dependant module +// is only used as a future-to-module dependency. This is because the dependant module has to get added to the +// parent module as a submodule, and we currently don't have a way of distinguishing at this point in the code between +// a submodule that is exclusively used as a future-to-module dependency (i.e. in { after: [...] }) +// and a submodule that is used as a module-to-module dependency (i.e. in m.useModule(...)). +// This is a known issue that we have decided to revisit at a later point in time because the solution is not trivial. +const FlowTooltip: React.FC = () => ( + + + + + +
    Diagram reference
    + Future to future dependency +         + + -----------> + +
    + Future to module dependency      + + ----> + +
    + Module to module dependency     + - - -> +
    +
    +); + +const HighlightedFutures = styled.div<{ + futures: string[]; + deploys: string[]; + others: string[]; +}>` + ${({ deploys }) => + deploys.map( + (id) => + css` + g[id^="flowchart-${id}-"] rect { + fill: #fbf8d8 !important; + } + ` + )} + + ${({ others }) => + others.map( + (id) => + css` + g[id^="flowchart-${id}-"] rect { + fill: #f8f2ff !important; + } + ` + )} + + ${({ futures }) => + futures.map( + (id) => + css` + g[id^="flowchart-${id}-"] rect { + fill: #16181d !important; + } + + g[id^="flowchart-${id}-"] span { + color: #fbf8d8 !important; + } + ` + )} +`; + +const SectionHeader = styled.div` + font-size: 28px; + font-weight: 700; + line-height: 30px; + letter-spacing: 0em; + text-align: left; + display: inline-flex; + align-items: center; + + margin-bottom: 1rem; + margin-top: 1rem; +`; + +const BatchBtnSection = styled.div` + margin-bottom: 40px; + text-align: center; + display: inline-flex; + flex-wrap: wrap; + justify-content: center; + row-gap: 1rem; + width: 100%; +`; + +const BatchBtn = styled.span<{ isCurrentlyHovered: boolean }>` + font-size: 0.8rem; + width: 86px; + text-align: center; + padding: 0.5rem 1rem; + margin: auto 0.5rem; + border-radius: 10px; + background: #ffffff; + border: 1px solid #edcf00; + cursor: pointer; + white-space: nowrap; + + ${(props) => + props.isCurrentlyHovered && + ` + background: #16181D; + color: #FBF8D8; + border: 1px solid #16181D; + `} +`; diff --git a/packages/hardhat-ignition-ui/src/pages/visualization-overview/components/execution-batches.tsx b/packages/hardhat-ignition-ui/src/pages/visualization-overview/components/execution-batches.tsx new file mode 100644 index 0000000000..cb6b83a776 --- /dev/null +++ b/packages/hardhat-ignition-ui/src/pages/visualization-overview/components/execution-batches.tsx @@ -0,0 +1,186 @@ +import { + Future, + FutureType, + IgnitionModule, + IgnitionModuleResult, +} from "@nomicfoundation/ignition-core/ui-helpers"; +import { useMemo, useRef, useState, createRef } from "react"; +import { Tooltip } from "react-tooltip"; +import styled from "styled-components"; + +import { getAllFuturesForModule } from "../../../queries/futures"; +import { FutureBatch } from "./future-batch"; +import { TooltipIcon } from "../../../assets/TooltipIcon"; + +export const ExecutionBatches: React.FC<{ + ignitionModule: IgnitionModule>; + batches: string[][]; +}> = ({ ignitionModule, batches }) => { + const futures = useMemo( + () => getAllFuturesForModule(ignitionModule), + [ignitionModule] + ); + + const nonLibraryFutureIds = futures + .filter( + ({ type }) => + type !== FutureType.LIBRARY_DEPLOYMENT && + type !== FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT + ) + .map(({ id }) => id); + + const scrollRefMap = useRef( + nonLibraryFutureIds.reduce((acc, id) => { + return { ...acc, [id]: createRef() }; + }, {} as Record>) + ); + + const toggleMap = Object.fromEntries( + nonLibraryFutureIds.map((id) => [id, false]) + ); + + const [toggleState, setToggledInternal] = useState(toggleMap); + + const setToggled = (id: string, newToggleState: boolean) => { + if (newToggleState) { + scrollRefMap.current[id].current?.scrollIntoView({ + behavior: "smooth", + block: "center", + }); + } + + const newState = { ...toggleState, [id]: newToggleState }; + setToggledInternal(newState); + }; + + const [currentlyHovered, setCurrentlyHovered] = useState(""); + + const futureBatches = batches.reduce((acc, batch) => { + const fullBatch = batch.map((id) => futures.find((f) => f.id === id)); + + return [...acc, fullBatch as Future[]]; + }, [] as Future[][]); + + /* logic for highlighting a future based on future details hover */ + const futureHoverMap = Object.fromEntries( + batches.flatMap((batch, i) => { + const batchId = `batch-${i + 1}`; + + return batch.map((id, j) => [id, `${batchId}-future-${j}`]); + }) + ); + const [hoveredFuture, setHoveredFutureInternal] = useState(""); + + const setHoveredFuture = (id: string) => { + const futureId = futureHoverMap[id]; + setHoveredFutureInternal(futureId); + }; + + return ( +
    + + Execution batches + + + + {futures.length} futures will be executed across{" "} + {batches.length} batches + + + + [ {ignitionModule.id} ] + + {futureBatches.map((batch, i) => ( + + ))} + + +
    + ); +}; + +const BatchesTooltip: React.FC = () => ( + + + + + +
    + Futures that can be run simultaneously are executed at the same time in + batches. +
    +
    +
    + The sequence order shown for each batch doesn't reflect the final + execution order. The exact order is determined once they're run. + However, this specific order isn't relevant to the process, + allowing for simultaneous execution. +
    +
    +
    +); + +const RootModuleName = styled.div` + font-weight: 700; + padding-bottom: 1.5rem; + padding-left: 1.5rem; +`; + +const RootModuleBackground = styled.div` + border: 1px solid #e5e6e7; + border-radius: 10px; + padding: 1.5rem; +`; + +const SectionHeader = styled.div` + font-size: 28px; + font-weight: 700; + line-height: 30px; + letter-spacing: 0em; + display: inline-flex; + align-items: center; + + margin-bottom: 1rem; + margin-top: 1rem; +`; + +const SectionSubHeader = styled.div` + margin-bottom: 2rem; + margin-top: 2rem; +`; + +const Actions = styled.div<{ currentlyHovered: string; hoveredFuture: string }>` + display: grid; + row-gap: 1.5rem; + + ${({ currentlyHovered }) => + currentlyHovered && + ` + .${currentlyHovered} { + background: #16181D; + color: #FBF8D8; + } + `} + + ${({ hoveredFuture }) => + hoveredFuture && + ` + .${hoveredFuture} { + background: #16181D; + color: #FBF8D8; + box-shadow: -2px 2px 4px 0px #6C6F7433; + } + `} +`; diff --git a/packages/hardhat-ignition-ui/src/pages/visualization-overview/components/future-batch.tsx b/packages/hardhat-ignition-ui/src/pages/visualization-overview/components/future-batch.tsx new file mode 100644 index 0000000000..81567fab5e --- /dev/null +++ b/packages/hardhat-ignition-ui/src/pages/visualization-overview/components/future-batch.tsx @@ -0,0 +1,398 @@ +import { + ArgumentType, + Future, + FutureType, + isDeploymentType, + isFuture, +} from "@nomicfoundation/ignition-core/ui-helpers"; +import React from "react"; +import styled from "styled-components"; +import { argumentTypeToString } from "../../../utils/argumentTypeToString"; +import { FutureHeader } from "./future-header"; + +export const FutureBatch: React.FC<{ + batch: Future[]; + index: number; + toggleState: Record; + setToggled: (id: string, newToggleState: boolean) => void; + setCurrentlyHovered: (id: string) => void; + setHoveredFuture: (id: string) => void; + scrollRefMap: Record>; +}> = ({ + batch, + index, + toggleState, + setToggled, + setCurrentlyHovered, + setHoveredFuture, + scrollRefMap, +}) => { + return ( + + + Batch #{index} + + {batch.map((future, i) => ( + + ))} + + ); +}; + +const Batch = styled.div` + padding: 1rem; + border: 1px solid #edcf00; + border-radius: 7px; +`; + +const BatchHeader = styled.div` + padding: 1rem; +`; + +const FutureBtn = styled.div<{ isLibrary: boolean; toggled: boolean }>` + padding: 1rem; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + margin: 1rem; + + border-top-left-radius: 5px; + border-top-right-radius: 5px; + + ${(props) => + props.toggled && + ` + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + `} + + ${(props) => + !props.toggled && + ` + border-bottom-left-radius: 5px; + border-bottom-right-radius: 5px; + `} + + ${(props) => + !props.isLibrary && + ` + cursor: pointer; + `} +`; + +const FutureBlock: React.FC<{ + future: Future; + toggleState: Record; + setToggled: (id: string, newToggleState: boolean) => void; + setCurrentlyHovered: (id: string) => void; + setHoveredFuture: (id: string) => void; + classKey: string; + scrollRef: React.RefObject; +}> = ({ + future, + toggleState, + setToggled, + setCurrentlyHovered, + setHoveredFuture, + classKey, + scrollRef, +}) => { + const futureId = future.id; + const toggled = toggleState[futureId]; + + const displayText = toDisplayText(future); + + const isLibrary = + future.type === FutureType.LIBRARY_DEPLOYMENT || + future.type === FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT; + + const className = isDeploymentType(future.type) + ? "deploy-background" + : "call-background"; + + return ( +
    + setToggled(futureId, !toggled)} + > + + + {toggled && ( + + )} +
    + ); +}; + +function toDisplayText(future: Future): string { + switch (future.type) { + case FutureType.NAMED_ARTIFACT_CONTRACT_DEPLOYMENT: + case FutureType.CONTRACT_DEPLOYMENT: + return `Deploy ${future.contractName}`; + case FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT: + return `Library deploy ${future.id}`; + case FutureType.LIBRARY_DEPLOYMENT: + return `Library deploy ${future.id} from artifact`; + case FutureType.CONTRACT_CALL: + return `Call ${future.contract.contractName}.${future.functionName}`; + case FutureType.STATIC_CALL: + return `Static call ${future.id}`; + case FutureType.ENCODE_FUNCTION_CALL: + return `Encode function call ${future.id}`; + case FutureType.NAMED_ARTIFACT_CONTRACT_AT: + return `Existing contract ${future.id} (${ + typeof future.address === "string" + ? future.address + : isFuture(future.address) + ? future.address.id + : argumentTypeToString(future.address) + })`; + case FutureType.CONTRACT_AT: + return `Existing contract ${future.id} from artifact (${ + typeof future.address === "string" + ? future.address + : isFuture(future.address) + ? future.address.id + : argumentTypeToString(future.address) + })`; + case FutureType.READ_EVENT_ARGUMENT: + return `Read event from future ${future.futureToReadFrom.id} (event ${future.eventName} argument ${future.nameOrIndex})`; + case FutureType.SEND_DATA: + return `Send data ${future.id} to ${ + typeof future.to === "string" + ? future.to + : isFuture(future.to) + ? future.to.id + : argumentTypeToString(future.to) + }`; + } +} + +const FutureDetailsStyle = styled.div` + cursor: auto; + padding: 1rem 2rem; + margin: -1rem 1rem 1rem 1rem; + + border-top-left-radius: 0; + border-top-right-radius: 0; + border-bottom-right-radius: 5px; + border-bottom-left-radius: 5px; + + -webkit-box-shadow: inset 0px 6px 8px -8px rgba(0, 0, 0, 0.3); + -moz-box-shadow: inset 0px 6px 8px -8px rgba(0, 0, 0, 0.3); + box-shadow: inset 0px 6px 8px -8px rgba(0, 0, 0, 0.3); +`; + +const FutureDetailsSection: React.FC<{ + className: string; + future: Future; + setToggled: (id: string, newToggleState: boolean) => void; + setHoveredFuture: (id: string) => void; +}> = ({ className, future, setToggled, setHoveredFuture }) => { + switch (future.type) { + case FutureType.NAMED_ARTIFACT_CONTRACT_DEPLOYMENT: + case FutureType.CONTRACT_DEPLOYMENT: { + const args = Object.entries(future.constructorArgs); + return ( + +

    {args.length === 0 ? "No " : null}Constructor Arguments

    +
      + {args.map(([, arg], i) => ( +
    • + +
    • + ))} +
    +
    + ); + } + case FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT: + case FutureType.LIBRARY_DEPLOYMENT: + return null; + case FutureType.CONTRACT_CALL: { + const args = Object.entries(future.args); + return ( + +

    {args.length === 0 ? "No " : null}Arguments

    +
      + {args.map(([, arg], i) => ( +
    • + +
    • + ))} +
    +
    + ); + } + case FutureType.STATIC_CALL: { + const args = Object.entries(future.args); + return ( + +

    {args.length === 0 ? "No " : null}Arguments

    +
      + {args.map(([, arg], i) => ( +
    • + +
    • + ))} +
    +
    + ); + } + case FutureType.ENCODE_FUNCTION_CALL: { + const args = Object.entries(future.args); + return ( + +

    {args.length === 0 ? "No " : null}Arguments

    +
      + {args.map(([, arg], i) => ( +
    • + +
    • + ))} +
    +
    + ); + } + case FutureType.NAMED_ARTIFACT_CONTRACT_AT: + case FutureType.CONTRACT_AT: { + return ( + +

    Contract - {future.contractName}

    +

    + Address -{" "} + {typeof future.address === "string" ? ( + future.address + ) : ( + + )} +

    +
    + ); + } + case FutureType.READ_EVENT_ARGUMENT: { + return ( + +

    Emitter - {future.emitter.id}

    +

    Event - {future.eventName}

    +

    Event index - {future.eventIndex}

    +

    Argument - {future.nameOrIndex}

    +
    + ); + } + case FutureType.SEND_DATA: { + return ( + +

    + To -{" "} + {typeof future.to === "string" ? ( + future.to + ) : ( + + )} +

    +

    + Data -{" "} + {typeof future.data === "string" ? ( + future.data + ) : future.data === undefined ? ( + "0x" + ) : ( + + )} +

    +
    + ); + } + } +}; + +const Argument: React.FC<{ + setToggled: (id: string, newToggleState: boolean) => void; + setHoveredFuture: (id: string) => void; + arg: ArgumentType; +}> = ({ setToggled, arg, setHoveredFuture }) => { + if (isFuture(arg)) { + return ( + setToggled(arg.id, true)} + onMouseEnter={() => setHoveredFuture(arg.id)} + onMouseLeave={() => setHoveredFuture("")} + > + {argumentTypeToString(arg)} + + ); + } + + return {argumentTypeToString(arg)}; +}; + +const ArgumentText = styled.p` + margin: 0; +`; + +const ArgumentLink = styled.a` + textdecoration: underline; + color: #16181d; + cursor: pointer; + + &:hover { + font-weight: 700; + } +`; diff --git a/packages/hardhat-ignition-ui/src/pages/visualization-overview/components/future-header.tsx b/packages/hardhat-ignition-ui/src/pages/visualization-overview/components/future-header.tsx new file mode 100644 index 0000000000..ccbe4753a4 --- /dev/null +++ b/packages/hardhat-ignition-ui/src/pages/visualization-overview/components/future-header.tsx @@ -0,0 +1,53 @@ +import { Future } from "@nomicfoundation/ignition-core/ui-helpers"; +import styled from "styled-components"; + +export const FutureHeader: React.FC<{ + isLibrary: boolean; + toggled: boolean; + displayText: string; + setCurrentlyHovered: (id: string) => void; + future: Future; +}> = ({ isLibrary, toggled, displayText, setCurrentlyHovered, future }) => { + return ( + + {isLibrary ?
    : } + {displayText} +
    + setCurrentlyHovered(future.module.id)} + onMouseLeave={() => setCurrentlyHovered("")} + > + [ {future.module.id} ] + + + ); +}; + +const ToggleNameWrap = styled.div` + display: grid; + grid-template-columns: 1rem auto 1fr auto; +`; + +const ToggleBtn: React.FC<{ + toggled: boolean; +}> = ({ toggled }) => { + return {toggled ? "- " : "+ "}; +}; + +const ModuleName = styled.div` + font-weight: 700; + padding: 0.5rem; +`; + +const Text = styled.p` + margin: 0; + display: inline; + padding-top: 0.5rem; + padding-bottom: 0.5rem; + text-align: left; +`; + +const ToggleBtnText = styled(Text)` + text-align: center; +`; diff --git a/packages/hardhat-ignition-ui/src/pages/visualization-overview/components/summary.tsx b/packages/hardhat-ignition-ui/src/pages/visualization-overview/components/summary.tsx new file mode 100644 index 0000000000..26d39387da --- /dev/null +++ b/packages/hardhat-ignition-ui/src/pages/visualization-overview/components/summary.tsx @@ -0,0 +1,64 @@ +import { + IgnitionModule, + IgnitionModuleResult, +} from "@nomicfoundation/ignition-core/ui-helpers"; +import React, { useMemo } from "react"; +import styled from "styled-components"; +import { getAllDeployFuturesFor } from "../../../queries/futures"; + +export const Summary: React.FC<{ + ignitionModule: IgnitionModule>; +}> = ({ ignitionModule }) => { + const deployFutures = useMemo( + () => getAllDeployFuturesFor(ignitionModule), + [ignitionModule] + ); + + const deployCountPerContract = deployFutures.reduce((acc, future) => { + const count = acc[future.contractName] ?? 0; + return { ...acc, [future.contractName]: count + 1 }; + }, {} as Record); + + return ( + + Contracts to be deployed + +
    + {deployFutures.length === 0 ? null : ( + + {Object.entries(deployCountPerContract).map( + ([contractName, count]) => ( + + {contractName} + {count > 1 ? ` x${count}` : null} + + ) + )} + + )} +
    +
    + ); +}; + +const SummaryStyle = styled.div``; + +const Title = styled.div` + font-size: 24px; + font-weight: 700; + line-height: 30px; + letter-spacing: 0em; + + color: #16181d; +`; + +const StyledList = styled.ul` + padding-inline-start: 1rem; +`; + +const ListItem = styled.li` + font-size: 17px; + line-height: 1.6rem; + text-align: left; + color: #040405; +`; diff --git a/packages/hardhat-ignition-ui/src/pages/visualization-overview/visualization-overview.tsx b/packages/hardhat-ignition-ui/src/pages/visualization-overview/visualization-overview.tsx new file mode 100644 index 0000000000..9d4db679f7 --- /dev/null +++ b/packages/hardhat-ignition-ui/src/pages/visualization-overview/visualization-overview.tsx @@ -0,0 +1,249 @@ +import { + IgnitionModule, + IgnitionModuleResult, +} from "@nomicfoundation/ignition-core/ui-helpers"; +import React from "react"; +import styled from "styled-components"; + +import { DeploymentFlow } from "./components/deployment-flow"; +import { ExecutionBatches } from "./components/execution-batches"; +import { Summary } from "./components/summary"; + +import { socialsItems } from "../../components/socials"; +import rocketPNG from "../../assets/purple-rocket.png"; +import { ExternalLinkIcon } from "../../assets/ExternalLinkIcon"; + +export const VisualizationOverview: React.FC<{ + ignitionModule: IgnitionModule>; + batches: string[][]; +}> = ({ ignitionModule, batches }) => { + return ( +
    + + + + + + + DOCUMENTATION + + + + + {socialsItems.map((social) => { + const { Icon } = social; + return ( + + + + + + ); + })} + + + + + +
    + + HARDHAT IGNITION + +
    + {ignitionModule.id} deployment visualization +
    + + + + + + + + + + + + + +
    + ); +}; + +const RocketIcon: React.FC = () => ( + rocket +); + +const DocLink = styled.span` + font-size: 14px; + font-weight: 400; + line-height: 14px; + letter-spacing: 0.07em; + text-align: left; + margin-top: -5px; + + padding-right: 2rem; + + & a { + text-decoration: none; + color: #040405; + } +`; + +const SocialsList = styled.ul` + min-width: 80px; + width: 80px; + display: flex; + height: 32px; + align-items: center; + list-style-type: none; + justify-content: space-between; +`; + +const SocialLink = styled.a` + display: flex; + align-items: center; + & svg { + fill: #0a0a0a; + } + &:hover svg { + cursor: pointer; + opacity: 0.8; + } + &:focus svg { + cursor: pointer; + opacity: 0.5; + } +`; + +const SocialListItem = styled.li` + display: flex; + align-items: center; + justify-content: center; + & svg { + width: 22px; + height: 22px; + } +`; + +const NavBar = styled.div` + height: 72px; + padding: 2px 64px; + border-bottom: 1px solid #b0b2b5; + display: flex; + justify-content: space-between; + align-items: center; +`; + +const Contents = styled.div` + padding: 5rem 180px; + display: grid; + row-gap: 1rem; + min-width: 920px; +`; + +const Panel = styled.div` + padding: 20px 0 40px 0; + :not(:last-child) { + border-bottom: 1px solid #b0b2b5; + } +`; + +const PageTitle = styled.div` + font-size: 20px; + font-weight: 400; + line-height: 12px; + letter-spacing: 0.2em; + color: #040405; + display: flex; + align-items: center; + margin-bottom: 1rem; +`; + +const SubTitle = styled.div` + font-size: 42px; + font-weight: 700; + line-height: 45px; + letter-spacing: 0.5px; +`; + +const HardhatLogo: React.FC = () => ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +); diff --git a/packages/hardhat-ignition-ui/src/queries/futures.ts b/packages/hardhat-ignition-ui/src/queries/futures.ts new file mode 100644 index 0000000000..c1b8316624 --- /dev/null +++ b/packages/hardhat-ignition-ui/src/queries/futures.ts @@ -0,0 +1,64 @@ +import { + DeploymentFuture, + FunctionCallFuture, + Future, + IgnitionModule, + IgnitionModuleResult, + isDeploymentFuture, + isFunctionCallFuture, +} from "@nomicfoundation/ignition-core/ui-helpers"; + +export function getFutureById( + ignitionModule: IgnitionModule>, + futureId: string | undefined +): Future | undefined { + if (futureId === undefined) { + return undefined; + } + + const f = getAllFuturesForModule(ignitionModule).find( + (f) => f.id === futureId + ); + + if (f === undefined) { + return undefined; + } + + return f; +} + +/* Get all futures in a module and its submodules */ +export function getAllFuturesForModule({ + futures, + submodules, +}: IgnitionModule>): Future[] { + return Array.from(futures) + .concat( + Array.from(submodules.values()).flatMap((submodule) => + getAllFuturesForModule(submodule) + ) + ) + .filter((v, i, a) => a.indexOf(v) === i); // remove duplicates +} + +/** + * Get all deploy futures in a module and its submodules, including: + * - hardhat contract deploys + * - artifact contract deploys + * - library deploys + * - artifact library deploys + */ +export function getAllDeployFuturesFor( + ignitionModule: IgnitionModule> +): DeploymentFuture[] { + return getAllFuturesForModule(ignitionModule).filter(isDeploymentFuture); +} + +/** + * Get all calls in a module and its submodules + */ +export function getAllCallFuturesFor( + ignitionModule: IgnitionModule> +): FunctionCallFuture[] { + return getAllFuturesForModule(ignitionModule).filter(isFunctionCallFuture); +} diff --git a/packages/hardhat-ignition-ui/src/utils/argumentTypeToString.tsx b/packages/hardhat-ignition-ui/src/utils/argumentTypeToString.tsx new file mode 100644 index 0000000000..215afdda27 --- /dev/null +++ b/packages/hardhat-ignition-ui/src/utils/argumentTypeToString.tsx @@ -0,0 +1,30 @@ +import { + ArgumentType, + RuntimeValueType, + isFuture, + isRuntimeValue, +} from "@nomicfoundation/ignition-core/ui-helpers"; + +export function argumentTypeToString(argument: ArgumentType): string { + if (typeof argument === "bigint") { + return ``; + } + + if (isFuture(argument)) { + return ``; + } + + if (isRuntimeValue(argument)) { + if (argument.type === RuntimeValueType.ACCOUNT) { + return ``; + } + + return ``; + } + + return JSON.stringify(argument, null, 2); +} diff --git a/packages/hardhat-ignition-ui/src/utils/to-escaped-id.ts b/packages/hardhat-ignition-ui/src/utils/to-escaped-id.ts new file mode 100644 index 0000000000..94271b0d37 --- /dev/null +++ b/packages/hardhat-ignition-ui/src/utils/to-escaped-id.ts @@ -0,0 +1,12 @@ +/** + * Convert Ignition id to an escaped version for safe use in Mermaid diagrams. + */ +export function toEscapedId(id: string): string { + return id + .replaceAll("(", "__") + .replaceAll(")", "___") + .replaceAll(",", "____") + .replaceAll("~", "_____") + .replaceAll("#", "______") + .replaceAll(" ", "_______"); +} diff --git a/packages/hardhat-ignition-ui/src/utils/to-mermaid.ts b/packages/hardhat-ignition-ui/src/utils/to-mermaid.ts new file mode 100644 index 0000000000..f37dcfd87d --- /dev/null +++ b/packages/hardhat-ignition-ui/src/utils/to-mermaid.ts @@ -0,0 +1,158 @@ +import { + Future, + FutureType, + IgnitionModule, + IgnitionModuleResult, + isFuture, +} from "@nomicfoundation/ignition-core/ui-helpers"; +import { getAllFuturesForModule } from "../queries/futures.js"; +import { argumentTypeToString } from "./argumentTypeToString.js"; +import { toEscapedId } from "./to-escaped-id.js"; + +export function toMermaid( + ignitionModule: IgnitionModule> +) { + const modules = recursivelyListModulesAndSubmodulesFor(ignitionModule); + + const subgraphSections = modules + .map((m) => prettyPrintModule(m, " ")) + .join("\n"); + + const futureDependencies = [ + ...new Set( + getAllFuturesForModule(ignitionModule) + .flatMap((f) => + Array.from(f.dependencies).map<[string, string, boolean]>((d) => [ + toEscapedId(f.id), + toEscapedId(d.id), + /#/.test(d.id), + ]) + ) + .map( + ([from, to, isFuture]) => `${from} ${isFuture ? "-->" : "==>"} ${to}` + ) + ), + ].join("\n"); + + const moduleDependencies = [ + ...new Set( + modules + .flatMap((f) => + Array.from(f.submodules).map((d) => [ + toEscapedId(f.id), + toEscapedId(d.id), + ]) + ) + .map(([from, to]) => `${from} -.-> ${to}`) + ), + ].join("\n"); + + return `flowchart BT\n\n${toEscapedId( + ignitionModule.id + )}\n\n${subgraphSections}${ + futureDependencies === "" ? "" : "\n\n" + futureDependencies + }${moduleDependencies === "" ? "" : "\n\n" + moduleDependencies}`; +} + +function recursivelyListModulesAndSubmodulesFor( + module: IgnitionModule> +): Array>> { + return [module].concat( + Array.from(module.submodules).flatMap( + recursivelyListModulesAndSubmodulesFor + ) + ); +} + +function prettyPrintModule( + module: IgnitionModule>, + lineIndent = "" +): string { + const futures = Array.from(module.futures); + const futureList = futures + .map( + (f) => `${lineIndent}${toEscapedId(f.id)}["${toLabel(f)}"]:::futureNode` + ) + .join(`\n${lineIndent}`); + + if (futures.length > 0) { + const inner = `${lineIndent}subgraph ${toEscapedId( + module.id + )}Inner[ ]\n${lineIndent} direction BT\n\n${lineIndent}${futureList}\n${lineIndent}end\n\nstyle ${toEscapedId( + module.id + )}Inner fill:none,stroke:none`; + + const title = `${lineIndent}subgraph ${toEscapedId(module.id)}Padding["[ ${ + module.id + } ]"]\n${lineIndent} direction BT\n\n${lineIndent}${inner}\n${lineIndent}end\n\nstyle ${toEscapedId( + module.id + )}Padding fill:none,stroke:none`; + + const outer = `${lineIndent}subgraph ${toEscapedId( + module.id + )}[ ]\n${lineIndent} direction BT\n\n${lineIndent}${title}\n${lineIndent}end\n\nstyle ${toEscapedId( + module.id + )} fill:#fbfbfb,stroke:#e5e6e7`; + + return outer; + } + + const title = `${lineIndent}subgraph ${toEscapedId( + module.id + )}Padding["[ ${ + module.id + } ]"]\n${lineIndent} direction BT\n\n${lineIndent}end\n\nstyle ${toEscapedId( + module.id + )}Padding fill:none,stroke:none`; + + return `${lineIndent}subgraph ${toEscapedId( + module.id + )}[ ]\n${lineIndent} direction BT\n\n${lineIndent}${title}\n${lineIndent}end\n\nstyle ${toEscapedId( + module.id + )} fill:#fbfbfb,stroke:#e5e6e7`; +} + +function toLabel(f: Future): string { + switch (f.type) { + case FutureType.NAMED_ARTIFACT_CONTRACT_DEPLOYMENT: + return `Deploy ${f.contractName}`; + case FutureType.CONTRACT_DEPLOYMENT: + return `Deploy from artifact ${f.contractName}`; + case FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT: + return `Deploy library ${f.contractName}`; + case FutureType.LIBRARY_DEPLOYMENT: + return `Deploy library from artifact ${f.contractName}`; + case FutureType.CONTRACT_CALL: + return `Call ${f.contract.contractName}.${f.functionName}`; + case FutureType.STATIC_CALL: + return `Static call ${f.contract.contractName}.${f.functionName}`; + case FutureType.ENCODE_FUNCTION_CALL: + return `Encoded call ${f.contract.contractName}.${f.functionName}`; + case FutureType.NAMED_ARTIFACT_CONTRACT_AT: + return `Existing contract ${f.contractName} (${ + typeof f.address === "string" + ? f.address + : isFuture(f.address) + ? f.address.id + : argumentTypeToString(f.address) + })`; + case FutureType.CONTRACT_AT: + return `Existing contract from artifact ${f.contractName} (${ + typeof f.address === "string" + ? f.address + : isFuture(f.address) + ? f.address.id + : argumentTypeToString(f.address) + })`; + case FutureType.READ_EVENT_ARGUMENT: + return `Read event from future ${f.futureToReadFrom.id} (event ${f.eventName} argument ${f.nameOrIndex})`; + case FutureType.SEND_DATA: + return `Send data to ${ + typeof f.to === "string" + ? f.to + : isFuture(f.to) + ? f.to.id + : argumentTypeToString(f.to) + }`; + } +} diff --git a/packages/hardhat-ignition-ui/src/vite-env.d.ts b/packages/hardhat-ignition-ui/src/vite-env.d.ts new file mode 100644 index 0000000000..11f02fe2a0 --- /dev/null +++ b/packages/hardhat-ignition-ui/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/packages/hardhat-ignition-ui/test/to-mermaid.ts b/packages/hardhat-ignition-ui/test/to-mermaid.ts new file mode 100644 index 0000000000..6b1b758d35 --- /dev/null +++ b/packages/hardhat-ignition-ui/test/to-mermaid.ts @@ -0,0 +1,329 @@ +import { + Artifact, + IgnitionModule, + buildModule, +} from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; +import { toMermaid } from "../src/utils/to-mermaid.js"; + +describe("to-mermaid", () => { + it("should render a single deploy contract diagram", () => { + const moduleDefinition = buildModule("Module", (m) => { + const p = m.getParameter("p", 123); + const contract1 = m.contract("Contract1", [{ arr: [p] }]); + + return { contract1 }; + }); + + const expectedResult = testFormat` + flowchart BT + + Module + + subgraph Module[ ] + direction BT + + subgraph ModulePadding["[ Module ]"] + direction BT + + subgraph ModuleInner[ ] + direction BT + + Module______Contract1["Deploy Contract1"]:::futureNode + end + + style ModuleInner fill:none,stroke:none + end + + style ModulePadding fill:none,stroke:none + end + + style Module fill:#fbfbfb,stroke:#e5e6e7`; + + assertDiagram(moduleDefinition, expectedResult); + }); + + it("should render a module with a space in the name", () => { + const moduleDefinition = buildModule("Test_registrar", (m) => { + const p = m.getParameter("p", 123); + const contract1 = m.contract("Contract1", [{ arr: [p] }]); + + return { contract1 }; + }); + + const expectedResult = testFormat` + flowchart BT + + Test_registrar + + subgraph Test_registrar[ ] + direction BT + + subgraph Test_registrarPadding["[ Test_registrar ]"] + direction BT + + subgraph Test_registrarInner[ ] + direction BT + + Test_registrar______Contract1["Deploy Contract1"]:::futureNode + end + + style Test_registrarInner fill:none,stroke:none + end + + style Test_registrarPadding fill:none,stroke:none + end + + style Test_registrar fill:#fbfbfb,stroke:#e5e6e7`; + + assertDiagram(moduleDefinition, expectedResult); + }); + + it("should render a multi-module deploy diagram", () => { + const sub1 = buildModule("Submodule1", (m) => { + const contract1 = m.contract("Contract1", []); + + return { contract1 }; + }); + + const sub2 = buildModule("Submodule2", (m) => { + const contract2 = m.contract("Contract2", []); + + return { contract2 }; + }); + + const moduleDefinition = buildModule("Module", (m) => { + const { contract1 } = m.useModule(sub1); + const { contract2 } = m.useModule(sub2); + + const contract3 = m.contract("Contract3", [], { + after: [contract1, contract2], + }); + + return { contract3 }; + }); + + const expectedResult = testFormat` + flowchart BT + + Module + + subgraph Module[ ] + direction BT + + subgraph ModulePadding["[ Module ]"] + direction BT + + subgraph ModuleInner[ ] + direction BT + + Module______Contract3["Deploy Contract3"]:::futureNode + end + + style ModuleInner fill:none,stroke:none + end + + style ModulePadding fill:none,stroke:none + end + + style Module fill:#fbfbfb,stroke:#e5e6e7 + subgraph Submodule1[ ] + direction BT + + subgraph Submodule1Padding["[ Submodule1 ]"] + direction BT + + subgraph Submodule1Inner[ ] + direction BT + + Submodule1______Contract1["Deploy Contract1"]:::futureNode + end + + style Submodule1Inner fill:none,stroke:none + end + + style Submodule1Padding fill:none,stroke:none + end + + style Submodule1 fill:#fbfbfb,stroke:#e5e6e7 + subgraph Submodule2[ ] + direction BT + + subgraph Submodule2Padding["[ Submodule2 ]"] + direction BT + + subgraph Submodule2Inner[ ] + direction BT + + Submodule2______Contract2["Deploy Contract2"]:::futureNode + end + + style Submodule2Inner fill:none,stroke:none + end + + style Submodule2Padding fill:none,stroke:none + end + + style Submodule2 fill:#fbfbfb,stroke:#e5e6e7 + + Module______Contract3 --> Submodule1______Contract1 + Module______Contract3 --> Submodule2______Contract2 + + Module -.-> Submodule1 + Module -.-> Submodule2`; + + assertDiagram(moduleDefinition, expectedResult); + }); + + it("should render a complex diagram with all actions", () => { + const fakeArtifact: Artifact = { + abi: [], + contractName: "", + sourceName: "", + bytecode: "", + linkReferences: {}, + }; + + const libArtifact = fakeArtifact; + const withLibArtifact = fakeArtifact; + + const moduleDefinition = buildModule("Module", (m) => { + const basic = m.contract("BasicContract"); + const library = m.library("BasicLibrary"); + const libFromArtifact = m.library("BasicLibrary", libArtifact, { + id: "BasicLibrary2", + }); + const withLib = m.contract("ContractWithLibrary", withLibArtifact, [], { + libraries: { BasicLibrary: library }, + }); + + const call = m.call(basic, "basicFunction", [40]); + const eventArg = m.readEventArgument(call, "BasicEvent", "eventArg"); + m.staticCall(withLib, "readonlyFunction", [eventArg]); + + const duplicate = m.contractAt("BasicContract", basic, { + id: "BasicContract2", + }); + const duplicateWithLib = m.contractAt( + "ContractWithLibrary", + withLibArtifact, + withLib, + { id: "ContractWithLibrary2" } + ); + + m.send("test_send", duplicate, 123n); + + return { + basic, + library, + libFromArtifact, + withLib, + duplicate, + duplicateWithLib, + }; + }); + + const expectedResult = testFormat` + flowchart BT + + Module + + subgraph Module[ ] + direction BT + + subgraph ModulePadding["[ Module ]"] + direction BT + + subgraph ModuleInner[ ] + direction BT + + Module______BasicContract["Deploy BasicContract"]:::futureNode + Module______BasicLibrary["Deploy library BasicLibrary"]:::futureNode + Module______BasicLibrary2["Deploy library from artifact BasicLibrary"]:::futureNode + Module______ContractWithLibrary["Deploy from artifact ContractWithLibrary"]:::futureNode + Module______BasicContract.basicFunction["Call BasicContract.basicFunction"]:::futureNode + Module______BasicContract.BasicEvent.eventArg.0["Read event from future Module#BasicContract.basicFunction (event BasicEvent argument eventArg)"]:::futureNode + Module______ContractWithLibrary.readonlyFunction["Static call ContractWithLibrary.readonlyFunction"]:::futureNode + Module______BasicContract2["Existing contract BasicContract (Module#BasicContract)"]:::futureNode + Module______ContractWithLibrary2["Existing contract from artifact ContractWithLibrary (Module#ContractWithLibrary)"]:::futureNode + Module______test_send["Send data to Module#BasicContract2"]:::futureNode + end + + style ModuleInner fill:none,stroke:none + end + + style ModulePadding fill:none,stroke:none + end + + style Module fill:#fbfbfb,stroke:#e5e6e7 + + Module______ContractWithLibrary --> Module______BasicLibrary + Module______BasicContract.basicFunction --> Module______BasicContract + Module______BasicContract.BasicEvent.eventArg.0 --> Module______BasicContract.basicFunction + Module______ContractWithLibrary.readonlyFunction --> Module______ContractWithLibrary + Module______ContractWithLibrary.readonlyFunction --> Module______BasicContract.BasicEvent.eventArg.0 + Module______BasicContract2 --> Module______BasicContract + Module______ContractWithLibrary2 --> Module______ContractWithLibrary + Module______test_send --> Module______BasicContract2`; + + assertDiagram(moduleDefinition, expectedResult); + }); + + it("should render calls with args", () => { + const moduleDefinition = buildModule("Module", (m) => { + const resolver = m.contract("ens", []); + + m.call(resolver, "setAddr(bytes32,address)", [123, "0x0123"]); + m.staticCall(resolver, "getAddr(bytes32,address)", [123, "0x0123"]); + + return { resolver }; + }); + + const expectedResult = testFormat` + flowchart BT + + Module + + subgraph Module[ ] + direction BT + + subgraph ModulePadding["[ Module ]"] + direction BT + + subgraph ModuleInner[ ] + direction BT + + Module______ens["Deploy ens"]:::futureNode + Module______ens.setAddr__bytes32____address___["Call ens.setAddr(bytes32,address)"]:::futureNode + Module______ens.getAddr__bytes32____address___["Static call ens.getAddr(bytes32,address)"]:::futureNode + end + + style ModuleInner fill:none,stroke:none + end + + style ModulePadding fill:none,stroke:none + end + + style Module fill:#fbfbfb,stroke:#e5e6e7 + + Module______ens.setAddr__bytes32____address___ --> Module______ens + Module______ens.getAddr__bytes32____address___ --> Module______ens`; + + assertDiagram(moduleDefinition, expectedResult); + }); +}); + +function assertDiagram(ignitionModule: IgnitionModule, expectedResult: string) { + const result = toMermaid(ignitionModule); + + assert.equal(result, expectedResult); +} + +function testFormat(expected: TemplateStringsArray): string { + return expected + .toString() + .substring(1) + .split("\n") + .map((line) => line.substring(6)) + .join("\n"); +} diff --git a/packages/hardhat-ignition-ui/tsconfig.json b/packages/hardhat-ignition-ui/tsconfig.json new file mode 100644 index 0000000000..ba9d4f9595 --- /dev/null +++ b/packages/hardhat-ignition-ui/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + "target": "ESNext", + "lib": ["DOM", "DOM.Iterable", "ESNext"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [ + { "path": "./tsconfig.node.json" }, + { "path": "../hardhat-ignition-core" } + ] +} diff --git a/packages/hardhat-ignition-ui/tsconfig.node.json b/packages/hardhat-ignition-ui/tsconfig.node.json new file mode 100644 index 0000000000..eedfb78eea --- /dev/null +++ b/packages/hardhat-ignition-ui/tsconfig.node.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"], + "references": [{ "path": "../hardhat-ignition-core" }] +} diff --git a/packages/hardhat-ignition-ui/vite.config.ts b/packages/hardhat-ignition-ui/vite.config.ts new file mode 100644 index 0000000000..533d4623c0 --- /dev/null +++ b/packages/hardhat-ignition-ui/vite.config.ts @@ -0,0 +1,16 @@ +import react from "@vitejs/plugin-react"; +import { defineConfig } from "vite"; +import { viteSingleFile } from "vite-plugin-singlefile"; + +// https://vitejs.dev/config/ +export default defineConfig({ + plugins: [react(), viteSingleFile()], + optimizeDeps: { + include: ["@nomicfoundation/ignition-core/ui-helpers"], + }, + build: { + commonjsOptions: { + include: [/core/, /node_modules/], + }, + }, +}); diff --git a/packages/hardhat-ignition-viem/.eslintrc.js b/packages/hardhat-ignition-viem/.eslintrc.js new file mode 100644 index 0000000000..4f618a51d0 --- /dev/null +++ b/packages/hardhat-ignition-viem/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + extends: [`${__dirname}/../../config/eslint/eslintrc.js`], + parserOptions: { + project: `${__dirname}/tsconfig.json`, + sourceType: "module", + }, + ignorePatterns: [".eslintrc.js", "**/fixture-projects/**/*"], +}; diff --git a/packages/hardhat-ignition-viem/.gitignore b/packages/hardhat-ignition-viem/.gitignore new file mode 100644 index 0000000000..c1c475b6a3 --- /dev/null +++ b/packages/hardhat-ignition-viem/.gitignore @@ -0,0 +1,144 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* +*.ndjson + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* +.npmrc + +# Mac OSX garbage +.DS_Store + +# Custom workspace settings for VSCode +.vscode/settings.json + +# Webstorm files +.idea/ + +# npm lockfile since we use pnpm now +package-lock.json diff --git a/packages/hardhat-ignition-viem/.mocharc.json b/packages/hardhat-ignition-viem/.mocharc.json new file mode 100644 index 0000000000..f1a1008fdf --- /dev/null +++ b/packages/hardhat-ignition-viem/.mocharc.json @@ -0,0 +1,7 @@ +{ + "require": "ts-node/register/transpile-only", + "file": "./test/setup.ts", + "timeout": 20000, + "exit": true, + "ignore": ["**/fixture-projects/**/*"] +} diff --git a/packages/hardhat-ignition-viem/.npmignore b/packages/hardhat-ignition-viem/.npmignore new file mode 100644 index 0000000000..05c3ff7c9f --- /dev/null +++ b/packages/hardhat-ignition-viem/.npmignore @@ -0,0 +1,14 @@ +coverage/ +.nyc_output/ +*.tsbuildinfo +**/.eslintrc.js +post-build.js +.mocharc.json +.nycrc +.prettierignore +.prettierrc +dist/test +src/ +test/ +scripts/ +esbuild.js diff --git a/packages/hardhat-ignition-viem/.nycrc b/packages/hardhat-ignition-viem/.nycrc new file mode 100644 index 0000000000..d17e98940f --- /dev/null +++ b/packages/hardhat-ignition-viem/.nycrc @@ -0,0 +1,12 @@ +{ + "extends": "@istanbuljs/nyc-config-typescript", + "check-coverage": true, + "statements": 85, + "branches": 80, + "functions": 100, + "lines": 85, + "all": true, + "include": ["src/**/*.ts"], + "reporter": ["html", "lcov", "text", "text-summary"], + "report-dir": "coverage" +} diff --git a/packages/hardhat-ignition-viem/.prettierignore b/packages/hardhat-ignition-viem/.prettierignore new file mode 100644 index 0000000000..4ae5fe88f4 --- /dev/null +++ b/packages/hardhat-ignition-viem/.prettierignore @@ -0,0 +1,9 @@ +/node_modules +/dist +/test/fixture-projects/*/artifacts +/test/fixture-projects/*/cache +/coverage +/.nyc_output +/test/fixture-projects/*/deployments/*/artifacts +/test/fixture-projects/*/deployments/*/build-info + diff --git a/packages/hardhat-ignition-viem/CHANGELOG.md b/packages/hardhat-ignition-viem/CHANGELOG.md new file mode 100644 index 0000000000..aff2029422 --- /dev/null +++ b/packages/hardhat-ignition-viem/CHANGELOG.md @@ -0,0 +1,162 @@ +# Changelog + +## 0.15.11 + +### Patch Changes + +- 23280b8: Resolve all dependencies when using submodules in `after` + +## 0.15.10 + +### Patch Changes + +- d96c003: Fix for bug when we fail to save transaction hash + +## 0.15.9 - 2024-12-18 + +### Added + +- Standard Ignition UI can now be enabled when deploying via Hardhat scripts by setting `displayUi: true` in the `deploy` function options, @zoeyTM ([#843](https://github.com/NomicFoundation/hardhat-ignition/pull/843)) +- Ignition modules can now be set as a dependency in the `after` option of futures, @zoeyTM ([#828](https://github.com/NomicFoundation/hardhat-ignition/pull/828)) +- The `ignition transactions` command output will now include a link to view each transaction on the configured block explorer, @zoeyTM ([#849](https://github.com/NomicFoundation/hardhat-ignition/pull/849)) +- Module parameters can now be directly imported from a JSON file when deploying via Hardhat scripts by passing an absolute path to the file to the `parameters` option, @zoeyTM ([#850](https://github.com/NomicFoundation/hardhat-ignition/pull/850)) + +### Fixed + +- Properly handle errors when verifying deployments that use external artifacts, @zoeyTM ([#848](https://github.com/NomicFoundation/hardhat-ignition/pull/848)) +- Fix issue with `ignition status` command not working with deployments that use external artifacts, @zoeyTM ([#846](https://github.com/NomicFoundation/hardhat-ignition/pull/846)) + +## 0.15.8 - 2024-11-22 + +### Fixed + +- `transactions` command now properly serializes `bigint` values, @zoeyTM ([#837](https://github.com/NomicFoundation/hardhat-ignition/pull/837)) +- Additional validations added for global parameters, @kanej ([#832](https://github.com/NomicFoundation/hardhat-ignition/pull/832)) + +## 0.15.7 - 2024-10-24 + +### Added + +- New CLI command `ignition transactions` to list all transactions sent for a given deployment ID, @zoeyTM ([#821](https://github.com/NomicFoundation/hardhat-ignition/pull/821)) +- Module parameters can now be set at the global level using `$global`, @zoeyTM ([#819](https://github.com/NomicFoundation/hardhat-ignition/pull/819)) + +### Fixed + +- Gas fields are now properly set for Optimistic BNB, @zoeyTM ([#826](https://github.com/NomicFoundation/hardhat-ignition/pull/826)) +- Corrected resolution of artifacts when using fully qualified names in deployment modules, @kanej ([#822](https://github.com/NomicFoundation/hardhat-ignition/pull/822)) + +## 0.15.6 - 2024-09-25 + +### Added + +- Updates to the visualization UI, including the ability to zoom and pan the mermaid diagram ([#810](https://github.com/NomicFoundation/hardhat-ignition/pull/810)) +- `gasPrice` and `disableFeeBumping` config fields added as part of our L2 gas logic update ([#808](https://github.com/NomicFoundation/hardhat-ignition/pull/808)) +- Debug logging for communication errors with Hardhat Ledger ([#792](https://github.com/NomicFoundation/hardhat-ignition/pull/792)) +- JSON5 support for module parameters, thanks @erhant ([#800](https://github.com/NomicFoundation/hardhat-ignition/pull/800)) +- Add `writeLocalhostDeployment` flag to allow saving deployment artifacts when deploying to the ephemeral Hardhat network, thanks @SebastienGllmt ([#816](https://github.com/NomicFoundation/hardhat-ignition/pull/816)) + +### Fixed + +- Replace `this` with the class itself in `ViemIgnitionHelper`, thanks @iosh ([#796](https://github.com/NomicFoundation/hardhat-ignition/pull/796)) + +## 0.15.5 - 2024-06-17 + +### Added + +- New function `m.encodeFunctionCall` ([#761](https://github.com/NomicFoundation/hardhat-ignition/pull/761)) + +### Fixed + +- Adjusted regex to allow calling overloaded functions with array parameters ([#774](https://github.com/NomicFoundation/hardhat-ignition/pull/774)) +- Handle anvil response for `hardhat_setBalance` when deploying with create2 ([#773](https://github.com/NomicFoundation/hardhat-ignition/pull/773)) +- Properly resolve `verify` logic when dealing with circular or very deeply nested imports ([#772](https://github.com/NomicFoundation/hardhat-ignition/pull/772)) +- Exclude BNB Test Chain from zero fee configuration in gas fee logic, thanks @MukulKolpe ([#768](https://github.com/NomicFoundation/hardhat-ignition/pull/768)) + +## 0.15.4 - 2024-05-14 + +### Fixed + +- Reconcile address parameters with mismatched casings ([#748](https://github.com/NomicFoundation/hardhat-ignition/pull/748)) +- Display better error messages for insufficient funds ([#754](https://github.com/NomicFoundation/hardhat-ignition/pull/754)) + +## 0.15.3 - 2024-05-09 + +### Fixed + +- Exclude BNB Chain from zero fee configuration in gas fee logic, thanks @magicsih ([#755](https://github.com/NomicFoundation/hardhat-ignition/pull/755)) + +## 0.15.2 - 2024-05-02 + +### Added + +- Improved support for deploying via a Ledger Hardware wallet, [see our guide for details](https://hardhat.org/ignition/docs/guides/ledger) ([#720](https://github.com/NomicFoundation/hardhat-ignition/issues/720)) +- Support `maxPriorityFeePerGas` as a configuration parameter ([#728](https://github.com/NomicFoundation/hardhat-ignition/issues/728)) +- Use RPC call `eth_maxPriorityFeePerGas` in gas fee calculations when available ([#743](https://github.com/NomicFoundation/hardhat-ignition/issues/743)) +- Support zero gas fee chains (like private Besu chains), thanks @jimthematrix ([#730](https://github.com/NomicFoundation/hardhat-ignition/pull/730)) + +### Fixed + +- Use pre-EIP-1559 transactions for Polygon to avoid dropped transactions ([#735](https://github.com/NomicFoundation/hardhat-ignition/issues/735)) + +## 0.15.1 - 2024-04-04 + +### Added + +- Add a configurable upper limit for the maxFeePerGas ([#685](https://github.com/NomicFoundation/hardhat-ignition/issues/685)) +- Support writing and reading from deployments folder within tests and scripts ([#704](https://github.com/NomicFoundation/hardhat-ignition/pull/704)) +- Add `ignition deployments` task to list all the current deployments ([#646](https://github.com/NomicFoundation/hardhat-ignition/issues/646)) + +### Changed + +- Deploying to a cleared local hardhat node ignores previous deployment ([#650](https://github.com/NomicFoundation/hardhat-ignition/issues/650)) + +### Fixed + +- More resilent automine check ([#721](https://github.com/NomicFoundation/hardhat-ignition/issues/721)) +- `getCode` usage brought in line with Ethereum RPC standard ([#715](https://github.com/NomicFoundation/hardhat-ignition/issues/715)) +- Fixed unexpected next nonce on revert ([#676](https://github.com/NomicFoundation/hardhat-ignition/issues/676)) +- Reduce sources being passed to etherscan for verification ([#706](https://github.com/NomicFoundation/hardhat-ignition/issues/706)) + +## 0.15.0 - 2024-03-13 + +### Added + +- Support `create2` through strategies, for more details see [our `create2` guide](https://hardhat.org/ignition/docs/guides/create2). ([#629](https://github.com/NomicFoundation/hardhat-ignition/issues/629)) + +## 0.14.0 - 2024-02-21 + +### Added + +- Support BigInt values in Module Parameter files by encoding them as strings with the format /d+n/ ([#663](https://github.com/NomicFoundation/hardhat-ignition/issues/663)) + +### Changed + +- Upgrade to `viem@2`, a breaking change for scripts or tests that leverage viem contract instances returned from an Ignition deploy call, see [the viem@2 migration guide for more details](https://viem.sh/docs/migration-guide#2xx-breaking-changes) ([#692](https://github.com/NomicFoundation/hardhat-ignition/issues/692)) + +## 0.13.2 - 2024-01-25 + +### Fixed + +- Add memory pool lookup retry to reduce errors from slow propogation ([#667](https://github.com/NomicFoundation/hardhat-ignition/pull/667)) + +### Added + +- Improve Module API typescript doc comments to enhance intellisense experience ([#642](https://github.com/NomicFoundation/hardhat-ignition/issues/642)) +- Support module parameters taking accounts as the default value ([673](https://github.com/NomicFoundation/hardhat-ignition/issues/673)) + +## 0.13.1 - 2023-12-19 + +### Added + +- New flag `--reset` for `ignition deploy` to wipe the existing deployment state before running ([#649](https://github.com/NomicFoundation/hardhat-ignition/issues/649)) + +### Fixed + +- Fix bug with `process.stdout` being used in a non-tty context ([#644](https://github.com/NomicFoundation/hardhat-ignition/issues/644)) + +## 0.13.0 - 2023-12-13 + +### Added + +- Add `@nomicfoundation/hardhat-plugin-viem` package, that adds an `ignition` object to the Hardhat Runtime Environment that supports deploying Ignition modules and returning deployed contracts as [Viem](https://viem.sh/) contract instances, see the our [Viem guide](https://hardhat.org/ignition/docs/guides/viem) for more details ([#612](https://github.com/NomicFoundation/hardhat-ignition/pull/612)) +- Add support for setting the default sender account from tests and scripts ([#639](https://github.com/NomicFoundation/hardhat-ignition/issues/639)) diff --git a/packages/hardhat-ignition-viem/README.md b/packages/hardhat-ignition-viem/README.md new file mode 100644 index 0000000000..a171504942 --- /dev/null +++ b/packages/hardhat-ignition-viem/README.md @@ -0,0 +1,55 @@ +![hardhat_Ignition_banner](https://github.com/NomicFoundation/hardhat-ignition/assets/24030/cc73227b-8791-4bb3-bc9a-a39be69d215f) [![npm](https://img.shields.io/npm/v/@nomicfoundation/hardhat-ignition-viem.svg)](https://www.npmjs.com/package/@nomicfoundation/hardhat-ignition) [![hardhat](https://hardhat.org/buidler-plugin-badge.svg?1)](https://hardhat.org) + +--- + +# Hardhat Ignition with Viem + +> **Note:** This package includes support for [Viem](https://viem.sh/). To use Hardhat Ignition with Ethers instead, see the [Hardhat Ignition plugin](https://www.npmjs.com/search?q=%40nomicfoundation%2Fhardhat-ignition-ethers). + +Hardhat Ignition is a declarative system for deploying smart contracts on Ethereum. It enables you to define smart contract instances you want to deploy, and any operation you want to run on them. By taking over the deployment and execution, Hardhat Ignition lets you focus on your project instead of getting caught up in the deployment details. + +Built by the [Nomic Foundation](https://nomic.foundation/) for the Ethereum community. + +Join the Hardhat Ignition channel of our [Hardhat Community Discord server](https://hardhat.org/ignition-discord) to stay up to date on new releases and tutorials. + +## Installation + +```bash +npm install --save-dev @nomicfoundation/hardhat-ignition-viem +``` + +Import the plugin in your `hardhat.config.js``: + +```js +require("@nomicfoundation/hardhat-ignition-viem"); +``` + +Or if you are using TypeScript, in your `hardhat.config.ts``: + +```js +import "@nomicfoundation/hardhat-ignition-viem"; +``` + +## Documentation + +On [Hardhat Ignition's website](https://hardhat.org/ignition) you will find guides for: + +- [Getting started](https://hardhat.org/ignition/docs/getting-started) +- [Creating Modules](https://hardhat.org/ignition/docs/guides/creating-modules) +- [Deploying a module](https://hardhat.org/ignition/docs/guides/deploy) +- [Visualizing your module](https://hardhat.org/ignition/docs/guides/visualize) +- [Handling errors](https://hardhat.org/ignition/docs/guides/error-handling) +- [Modifying an existing module](https://hardhat.org/ignition/docs/guides/modifications) +- [Using Hardhat Ignition in your tests](https://hardhat.org/ignition/docs/guides/tests) + +## Contributing + +Contributions are always welcome! Feel free to open any issue or send a pull request. + +Go to [CONTRIBUTING.md](https://github.com/NomicFoundation/hardhat-ignition/blob/main/CONTRIBUTING.md) to learn about how to set up Hardhat Ignition's development environment. + +## Feedback, help and news + +[Hardhat Ignition on Discord](https://hardhat.org/ignition-discord): for questions and feedback. + +Follow [Hardhat](https://twitter.com/HardhatHQ) and [Nomic Foundation](https://twitter.com/NomicFoundation) on Twitter. diff --git a/packages/hardhat-ignition-viem/package.json b/packages/hardhat-ignition-viem/package.json new file mode 100644 index 0000000000..b02a26094a --- /dev/null +++ b/packages/hardhat-ignition-viem/package.json @@ -0,0 +1,76 @@ +{ + "name": "@nomicfoundation/hardhat-ignition-viem", + "version": "0.15.11", + "license": "MIT", + "author": "Nomic Foundation", + "homepage": "https://hardhat.org", + "description": "The Viem extension to Hardhat Ignition. Hardhat Ignition is a declarative system for deploying smart contracts on Ethereum. It enables you to define smart contract instances you want to deploy, and any operation you want to run on them. By taking over the deployment and execution, Hardhat Ignition lets you focus on your project instead of getting caught up in the deployment details.", + "repository": "github:NomicFoundation/hardhat-ignition", + "keywords": [ + "ethereum", + "smart-contracts", + "hardhat", + "blockchain", + "dapps", + "tooling", + "solidity", + "deployment", + "viem" + ], + "main": "dist/src/index.js", + "types": "dist/src/index.d.ts", + "scripts": { + "prebuild": "(tsc --build || true) && ts-node --project tsconfig.json ./scripts/compile-test-fixture-project.ts create2 && ts-node --project tsconfig.json ./scripts/compile-test-fixture-project.ts minimal", + "build": "tsc --build", + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", + "eslint": "eslint \"src/**/*.{ts,tsx}\" \"test/**/*.{ts,tsx}\"", + "prettier": "prettier \"**/*.{js,ts,md,json}\"", + "test": "mocha --recursive \"test/**/*.ts\"", + "test:debug": "DEBUG='hardhat-ignition-viem:*,ignition:*' pnpm test", + "test:coverage": "nyc mocha \"test/**/*.ts\"", + "test:build": "tsc --project ./test/", + "clean": "rimraf .nyc_output coverage dist tsconfig.tsbuildinfo ./test/fixture-projects/**/deployments ./test/fixture-projects/**/artifacts", + "prepack": "pnpm build" + }, + "devDependencies": { + "@istanbuljs/nyc-config-typescript": "1.0.2", + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/hardhat-ignition": "workspace:^", + "@nomicfoundation/hardhat-viem": "workspace:^2.0.0", + "@nomicfoundation/ignition-core": "workspace:^", + "@types/chai": "^4.2.22", + "@types/chai-as-promised": "^7.1.4", + "@types/mocha": "9.1.1", + "@types/node": "^18.0.0", + "@types/sinon": "^10.0.13", + "@typescript-eslint/eslint-plugin": "^5.57.1", + "@typescript-eslint/experimental-utils": "^5.62.0", + "@typescript-eslint/parser": "^5.57.1", + "chai": "^4.3.4", + "chai-as-promised": "7.1.1", + "eslint": "^8.38.0", + "eslint-config-prettier": "8.3.0", + "eslint-import-resolver-typescript": "^3.5.5", + "eslint-plugin-import": "2.29.0", + "eslint-plugin-mocha": "^9.0.0", + "eslint-plugin-no-only-tests": "3.1.0", + "eslint-plugin-prettier": "4.0.0", + "hardhat": "workspace:^2.18.0", + "mocha": "^9.1.3", + "nyc": "15.1.0", + "prettier": "2.8.8", + "rimraf": "3.0.2", + "sinon": "^14.0.0", + "ts-node": "10.9.1", + "typescript": "^5.0.2", + "viem": "^2.7.6" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-ignition": "workspace:^", + "@nomicfoundation/hardhat-viem": "workspace:^2.0.0", + "@nomicfoundation/ignition-core": "workspace:^", + "hardhat": "workspace:^2.18.0", + "viem": "^2.7.6" + } +} diff --git a/packages/hardhat-ignition-viem/scripts/compile-test-fixture-project.ts b/packages/hardhat-ignition-viem/scripts/compile-test-fixture-project.ts new file mode 100644 index 0000000000..b784b73c83 --- /dev/null +++ b/packages/hardhat-ignition-viem/scripts/compile-test-fixture-project.ts @@ -0,0 +1,24 @@ +import path from "node:path"; + +const main = async (projectToBuild: string) => { + console.log("Running compile on the test fixture project - ", projectToBuild); + + const fixtureProjectDir = path.join( + __dirname, + "../test/fixture-projects", + projectToBuild + ); + + process.chdir(fixtureProjectDir); + + const hre = require("hardhat"); + + await hre.run("compile", { quiet: true }); +}; + +const project = process.argv[2]; + +void main(project).catch((error) => { + console.error(error); + process.exit(1); +}); diff --git a/packages/hardhat-ignition-viem/src/ignition-module-results-to-viem-contracts.ts b/packages/hardhat-ignition-viem/src/ignition-module-results-to-viem-contracts.ts new file mode 100644 index 0000000000..e6575b48c4 --- /dev/null +++ b/packages/hardhat-ignition-viem/src/ignition-module-results-to-viem-contracts.ts @@ -0,0 +1,57 @@ +import { GetContractReturnType } from "@nomicfoundation/hardhat-viem/types"; +import { + ContractAtFuture, + ContractDeploymentFuture, + ContractFuture, + IgnitionModuleResult, +} from "@nomicfoundation/ignition-core"; +import { ArtifactsMap } from "hardhat/types"; + +export type IgnitionModuleResultsToViemContracts< + ContractNameT extends string, + IgnitionModuleResultsT extends IgnitionModuleResult +> = { + [resultKey in keyof IgnitionModuleResultsT]: ToContractType< + IgnitionModuleResultsT, + resultKey + >; +}; + +type ToContractType< + IgnitionModuleResultsT extends IgnitionModuleResult, + ResultKey extends keyof IgnitionModuleResultsT +> = IgnitionModuleResultsT[ResultKey] extends + | ContractDeploymentFuture + | ContractAtFuture + ? GetContractReturnType> + : LookupContractName< + IgnitionModuleResultsT, + ResultKey + > extends keyof ArtifactsMap + ? LookupContractReturnTypeForContractName< + LookupContractName + > + : never; + +type LookupContractReturnTypeForContractName< + ContractName extends keyof ArtifactsMap +> = GetContractReturnType; + +type LookupContractName< + IgnitionModuleResultsT extends IgnitionModuleResult, + ResultsContractKey extends keyof IgnitionModuleResultsT +> = ContractNameOfContractFuture; + +type ContractNameOfContractFuture = + ContractFutureT extends ContractFuture + ? ContractName + : never; + +export type AbiOf = + ContractDeploymentFutureT extends ContractDeploymentFuture< + infer ContractDeploymentAbi + > + ? ContractDeploymentAbi + : ContractDeploymentFutureT extends ContractAtFuture + ? ContractAbiT + : never; diff --git a/packages/hardhat-ignition-viem/src/index.ts b/packages/hardhat-ignition-viem/src/index.ts new file mode 100644 index 0000000000..dcb846fcd1 --- /dev/null +++ b/packages/hardhat-ignition-viem/src/index.ts @@ -0,0 +1,28 @@ +import "@nomicfoundation/hardhat-ignition"; +import "@nomicfoundation/hardhat-viem"; +import { extendEnvironment } from "hardhat/config"; +import { HardhatPluginError, lazyObject } from "hardhat/plugins"; + +import "./type-extensions"; + +/** + * Add an `ignition` object to the HRE. + */ +extendEnvironment((hre) => { + if ( + hre.ignition !== undefined && + hre.ignition.type !== "stub" && + hre.ignition.type !== "viem" + ) { + throw new HardhatPluginError( + "hardhat-ignition-viem", + `Found ${hre.ignition.type} and viem, but only one Hardhat Ignition extension plugin can be used at a time.` + ); + } + + hre.ignition = lazyObject(() => { + const { ViemIgnitionHelper } = require("./viem-ignition-helper"); + + return new ViemIgnitionHelper(hre); + }); +}); diff --git a/packages/hardhat-ignition-viem/src/type-extensions.ts b/packages/hardhat-ignition-viem/src/type-extensions.ts new file mode 100644 index 0000000000..8381d84fab --- /dev/null +++ b/packages/hardhat-ignition-viem/src/type-extensions.ts @@ -0,0 +1,7 @@ +import { ViemIgnitionHelper } from "./viem-ignition-helper"; + +declare module "hardhat/types/runtime" { + export interface HardhatRuntimeEnvironment { + ignition: ViemIgnitionHelper; + } +} diff --git a/packages/hardhat-ignition-viem/src/viem-ignition-helper.ts b/packages/hardhat-ignition-viem/src/viem-ignition-helper.ts new file mode 100644 index 0000000000..8de14c443b --- /dev/null +++ b/packages/hardhat-ignition-viem/src/viem-ignition-helper.ts @@ -0,0 +1,325 @@ +import type { GetContractReturnType } from "@nomicfoundation/hardhat-viem/types"; + +import { + HardhatArtifactResolver, + PrettyEventHandler, + errorDeploymentResultToExceptionMessage, + readDeploymentParameters, + resolveDeploymentId, +} from "@nomicfoundation/hardhat-ignition/helpers"; +import { + ContractAtFuture, + ContractDeploymentFuture, + ContractFuture, + DeployConfig, + DeploymentParameters, + DeploymentResultType, + EIP1193Provider, + Future, + FutureType, + IgnitionModule, + IgnitionModuleResult, + LibraryDeploymentFuture, + NamedArtifactContractAtFuture, + NamedArtifactContractDeploymentFuture, + NamedArtifactLibraryDeploymentFuture, + StrategyConfig, + SuccessfulDeploymentResult, + deploy, + isContractFuture, +} from "@nomicfoundation/ignition-core"; +import { HardhatPluginError } from "hardhat/plugins"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import path from "path"; + +import { IgnitionModuleResultsToViemContracts } from "./ignition-module-results-to-viem-contracts"; + +export class ViemIgnitionHelper { + public type = "viem"; + + private _provider: EIP1193Provider; + + constructor( + private _hre: HardhatRuntimeEnvironment, + private _config?: Partial, + provider?: EIP1193Provider + ) { + this._provider = provider ?? this._hre.network.provider; + } + + /** + * Deploys the given Ignition module and returns the results of the module + * as Viem contract instances. + * + * @param ignitionModule - The Ignition module to deploy. + * @param options - The options to use for the deployment. + * @returns Viem contract instances for each contract returned by the module. + */ + public async deploy< + ModuleIdT extends string, + ContractNameT extends string, + IgnitionModuleResultsT extends IgnitionModuleResult, + StrategyT extends keyof StrategyConfig = "basic" + >( + ignitionModule: IgnitionModule< + ModuleIdT, + ContractNameT, + IgnitionModuleResultsT + >, + { + parameters = {}, + config: perDeployConfig = {}, + defaultSender = undefined, + strategy, + strategyConfig, + deploymentId: givenDeploymentId = undefined, + displayUi = false, + }: { + parameters?: DeploymentParameters | string; + config?: Partial; + defaultSender?: string; + strategy?: StrategyT; + strategyConfig?: StrategyConfig[StrategyT]; + deploymentId?: string; + displayUi?: boolean; + } = { + parameters: {}, + config: {}, + defaultSender: undefined, + strategy: undefined, + strategyConfig: undefined, + deploymentId: undefined, + displayUi: undefined, + } + ): Promise< + IgnitionModuleResultsToViemContracts + > { + const accounts = (await this._hre.network.provider.request({ + method: "eth_accounts", + })) as string[]; + + const artifactResolver = new HardhatArtifactResolver(this._hre); + + const resolvedConfig: Partial = { + ...this._config, + ...perDeployConfig, + }; + + const resolvedStrategyConfig = + ViemIgnitionHelper._resolveStrategyConfig( + this._hre, + strategy, + strategyConfig + ); + + const chainId = Number( + await this._hre.network.provider.request({ + method: "eth_chainId", + }) + ); + + const deploymentId = resolveDeploymentId(givenDeploymentId, chainId); + + const deploymentDir = + this._hre.network.name === "hardhat" + ? undefined + : path.join( + this._hre.config.paths.ignition, + "deployments", + deploymentId + ); + + const executionEventListener = displayUi + ? new PrettyEventHandler() + : undefined; + + let deploymentParameters: DeploymentParameters; + + if (typeof parameters === "string") { + deploymentParameters = await readDeploymentParameters(parameters); + } else { + deploymentParameters = parameters; + } + + const result = await deploy({ + config: resolvedConfig, + provider: this._provider, + deploymentDir, + executionEventListener, + artifactResolver, + ignitionModule, + deploymentParameters, + accounts, + defaultSender, + strategy, + strategyConfig: resolvedStrategyConfig, + maxFeePerGasLimit: + this._hre.config.networks[this._hre.network.name]?.ignition + .maxFeePerGasLimit, + maxPriorityFeePerGas: + this._hre.config.networks[this._hre.network.name]?.ignition + .maxPriorityFeePerGas, + }); + + if (result.type !== DeploymentResultType.SUCCESSFUL_DEPLOYMENT) { + const message = errorDeploymentResultToExceptionMessage(result); + + throw new HardhatPluginError("hardhat-ignition-viem", message); + } + + return ViemIgnitionHelper._toViemContracts( + this._hre, + ignitionModule, + result + ); + } + + private static async _toViemContracts< + ModuleIdT extends string, + ContractNameT extends string, + IgnitionModuleResultsT extends IgnitionModuleResult + >( + hre: HardhatRuntimeEnvironment, + ignitionModule: IgnitionModule< + ModuleIdT, + ContractNameT, + IgnitionModuleResultsT + >, + result: SuccessfulDeploymentResult + ): Promise< + IgnitionModuleResultsToViemContracts + > { + return Object.fromEntries( + await Promise.all( + Object.entries(ignitionModule.results).map( + async ([name, contractFuture]) => [ + name, + await ViemIgnitionHelper._getContract( + hre, + contractFuture, + result.contracts[contractFuture.id] + ), + ] + ) + ) + ); + } + + private static async _getContract( + hre: HardhatRuntimeEnvironment, + future: Future, + deployedContract: { address: string } + ): Promise { + if (!isContractFuture(future)) { + throw new HardhatPluginError( + "hardhat-ignition-viem", + `Expected contract future but got ${future.id} with type ${future.type} instead` + ); + } + + return ViemIgnitionHelper._convertContractFutureToViemContract( + hre, + future, + deployedContract + ); + } + + private static async _convertContractFutureToViemContract( + hre: HardhatRuntimeEnvironment, + future: ContractFuture, + deployedContract: { address: string } + ) { + switch (future.type) { + case FutureType.NAMED_ARTIFACT_CONTRACT_DEPLOYMENT: + case FutureType.NAMED_ARTIFACT_LIBRARY_DEPLOYMENT: + case FutureType.NAMED_ARTIFACT_CONTRACT_AT: + return ViemIgnitionHelper._convertHardhatContractToViemContract( + hre, + future, + deployedContract + ); + case FutureType.CONTRACT_DEPLOYMENT: + case FutureType.LIBRARY_DEPLOYMENT: + case FutureType.CONTRACT_AT: + return ViemIgnitionHelper._convertArtifactToViemContract( + hre, + future, + deployedContract + ); + } + } + + private static _convertHardhatContractToViemContract( + hre: HardhatRuntimeEnvironment, + future: + | NamedArtifactContractDeploymentFuture + | NamedArtifactLibraryDeploymentFuture + | NamedArtifactContractAtFuture, + deployedContract: { address: string } + ): Promise { + return hre.viem.getContractAt( + future.contractName, + ViemIgnitionHelper._ensureAddressFormat(deployedContract.address) + ); + } + + private static async _convertArtifactToViemContract( + hre: HardhatRuntimeEnvironment, + future: + | ContractDeploymentFuture + | LibraryDeploymentFuture + | ContractAtFuture, + deployedContract: { address: string } + ): Promise { + const publicClient = await hre.viem.getPublicClient(); + const [walletClient] = await hre.viem.getWalletClients(); + + if (walletClient === undefined) { + throw new HardhatPluginError( + "hardhat-ignition-viem", + "No default wallet client found" + ); + } + + const viem = await import("viem"); + const contract = viem.getContract({ + address: ViemIgnitionHelper._ensureAddressFormat( + deployedContract.address + ), + abi: future.artifact.abi, + client: { + public: publicClient, + wallet: walletClient, + }, + }); + + return contract; + } + + private static _ensureAddressFormat(address: string): `0x${string}` { + if (!address.startsWith("0x")) { + return `0x${address}`; + } + + return `0x${address.slice(2)}`; + } + + private static _resolveStrategyConfig( + hre: HardhatRuntimeEnvironment, + strategyName: StrategyT | undefined, + strategyConfig: StrategyConfig[StrategyT] | undefined + ): StrategyConfig[StrategyT] | undefined { + if (strategyName === undefined) { + return undefined; + } + + if (strategyConfig === undefined) { + const fromHardhatConfig = + hre.config.ignition?.strategyConfig?.[strategyName]; + + return fromHardhatConfig; + } + + return strategyConfig; + } +} diff --git a/packages/hardhat-ignition-viem/test/.eslintrc.js b/packages/hardhat-ignition-viem/test/.eslintrc.js new file mode 100644 index 0000000000..757fe8a3ca --- /dev/null +++ b/packages/hardhat-ignition-viem/test/.eslintrc.js @@ -0,0 +1,15 @@ +module.exports = { + extends: [`${__dirname}/../.eslintrc.js`], + parserOptions: { + project: `${__dirname}/../tsconfig.json`, + sourceType: "module", + }, + rules: { + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: true, + }, + ], + }, +}; diff --git a/packages/hardhat-ignition-viem/test/default-sender.ts b/packages/hardhat-ignition-viem/test/default-sender.ts new file mode 100644 index 0000000000..320ca42c04 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/default-sender.ts @@ -0,0 +1,48 @@ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { useIgnitionProject } from "./test-helpers/use-ignition-project"; + +describe("support changing default sender", () => { + useIgnitionProject("minimal"); + + it("should deploy on the first HH account by default", async function () { + const [defaultAccount] = await this.hre.viem.getWalletClients(); + const defaultAccountAddress = defaultAccount.account.address; + + const moduleDefinition = buildModule("Module", (m) => { + const ownerSender = m.contract("OwnerSender"); + + return { ownerSender }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition, { + defaultSender: undefined, + }); + + assert.equal( + (await result.ownerSender.read.owner()).toLowerCase(), + defaultAccountAddress.toLowerCase() + ); + }); + + it("should allow changing the default sender that the ignition deployment runs against", async function () { + const [, notTheDefaultAccount] = await this.hre.viem.getWalletClients(); + const differentAccountAddress = notTheDefaultAccount.account.address; + + const moduleDefinition = buildModule("Module", (m) => { + const ownerSender = m.contract("OwnerSender"); + + return { ownerSender }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition, { + defaultSender: differentAccountAddress, + }); + + assert.equal( + (await result.ownerSender.read.owner()).toLowerCase(), + differentAccountAddress.toLowerCase() + ); + }); +}); diff --git a/packages/hardhat-ignition-viem/test/fixture-projects/.gitignore b/packages/hardhat-ignition-viem/test/fixture-projects/.gitignore new file mode 100644 index 0000000000..f1462f7a56 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/fixture-projects/.gitignore @@ -0,0 +1,3 @@ +artifacts/ +cache/ +deployments/ diff --git a/packages/hardhat-ignition-viem/test/fixture-projects/create2/contracts/Baz.sol b/packages/hardhat-ignition-viem/test/fixture-projects/create2/contracts/Baz.sol new file mode 100644 index 0000000000..7904b5189c --- /dev/null +++ b/packages/hardhat-ignition-viem/test/fixture-projects/create2/contracts/Baz.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +contract Baz { + bool public isBaz = true; +} diff --git a/packages/hardhat-ignition-viem/test/fixture-projects/create2/hardhat.config.js b/packages/hardhat-ignition-viem/test/fixture-projects/create2/hardhat.config.js new file mode 100644 index 0000000000..ddccd293ab --- /dev/null +++ b/packages/hardhat-ignition-viem/test/fixture-projects/create2/hardhat.config.js @@ -0,0 +1,12 @@ +require("../../../src/index"); + +module.exports = { + solidity: "0.8.19", + ignition: { + strategyConfig: { + create2: { + salt: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890aaaaaa", + }, + }, + }, +}; diff --git a/packages/hardhat-ignition-viem/test/fixture-projects/create2/modules/BazModule.js b/packages/hardhat-ignition-viem/test/fixture-projects/create2/modules/BazModule.js new file mode 100644 index 0000000000..a4b19a9b66 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/fixture-projects/create2/modules/BazModule.js @@ -0,0 +1,8 @@ +// eslint-disable-next-line import/no-unused-modules +const { buildModule } = require("@nomicfoundation/ignition-core"); + +module.exports = buildModule("BazModule", (m) => { + const foo = m.contract("Baz"); + + return { foo }; +}); diff --git a/packages/hardhat-ignition-viem/test/fixture-projects/minimal/contracts/Contracts.sol b/packages/hardhat-ignition-viem/test/fixture-projects/minimal/contracts/Contracts.sol new file mode 100644 index 0000000000..84cd328238 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/fixture-projects/minimal/contracts/Contracts.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +contract Foo { + event IncEvent(address indexed sender); + + bool public isFoo = true; + uint256 public x = 1; + + function inc() public { + x++; + emit IncEvent(msg.sender); + } + + function incByPositiveNumber(uint256 n) public returns (uint256) { + require(n > 0, "n must be positive"); + x += n; + return x; + } + + function incTwoNumbers(uint256 first, uint256 second) public { + x += first; + x += second; + } +} + +contract Bar { + bool public isBar = true; +} + +contract OwnerSender { + address public owner; + + constructor() { + owner = msg.sender; + } +} diff --git a/packages/hardhat-ignition-viem/test/fixture-projects/minimal/hardhat.config.js b/packages/hardhat-ignition-viem/test/fixture-projects/minimal/hardhat.config.js new file mode 100644 index 0000000000..791b28f337 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/fixture-projects/minimal/hardhat.config.js @@ -0,0 +1,12 @@ +require("../../../src/index"); + +module.exports = { + solidity: "0.8.19", + networks: { + hardhat: { + mining: { + auto: false, + }, + }, + }, +}; diff --git a/packages/hardhat-ignition-viem/test/fixture-projects/minimal/ignition/modules/MyModule.js b/packages/hardhat-ignition-viem/test/fixture-projects/minimal/ignition/modules/MyModule.js new file mode 100644 index 0000000000..f00a750bde --- /dev/null +++ b/packages/hardhat-ignition-viem/test/fixture-projects/minimal/ignition/modules/MyModule.js @@ -0,0 +1,13 @@ +// eslint-disable-next-line import/no-unused-modules +const { buildModule } = require("@nomicfoundation/ignition-core"); + +module.exports = buildModule("MyModule", (m) => { + const bar = m.contract("Bar"); + const usesContract = m.contract("UsesContract", [ + "0x0000000000000000000000000000000000000000", + ]); + + m.call(usesContract, "setAddress", [bar]); + + return { bar, usesContract }; +}); diff --git a/packages/hardhat-ignition-viem/test/fixture-projects/with-fake-helper/hardhat.config.js b/packages/hardhat-ignition-viem/test/fixture-projects/with-fake-helper/hardhat.config.js new file mode 100644 index 0000000000..7865980390 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/fixture-projects/with-fake-helper/hardhat.config.js @@ -0,0 +1,13 @@ +require("./index"); +require("../../../src/index"); + +module.exports = { + solidity: "0.8.19", + networks: { + hardhat: { + mining: { + auto: false, + }, + }, + }, +}; diff --git a/packages/hardhat-ignition-viem/test/fixture-projects/with-fake-helper/index.js b/packages/hardhat-ignition-viem/test/fixture-projects/with-fake-helper/index.js new file mode 100644 index 0000000000..f2c06ffd22 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/fixture-projects/with-fake-helper/index.js @@ -0,0 +1,7 @@ +const { extendEnvironment } = require("hardhat/config"); + +extendEnvironment((hre) => { + hre.ignition = { + type: "ethers", + }; +}); diff --git a/packages/hardhat-ignition-viem/test/ignition-helper-exclusivity.ts b/packages/hardhat-ignition-viem/test/ignition-helper-exclusivity.ts new file mode 100644 index 0000000000..f11b2c5e37 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/ignition-helper-exclusivity.ts @@ -0,0 +1,23 @@ +/* eslint-disable import/no-unused-modules */ +import { assert } from "chai"; +import { resetHardhatContext } from "hardhat/plugins-testing"; +import path from "path"; + +describe("ignition helper mutual exclusivity", () => { + before(function () { + process.chdir( + path.join(__dirname, "./fixture-projects", "with-fake-helper") + ); + }); + + after(function () { + resetHardhatContext(); + }); + + it("should error when loaded in conjunction with hardhat-ignition-ethers", async function () { + assert.throws( + () => require("hardhat"), + /Found ethers and viem, but only one Hardhat Ignition extension plugin can be used at a time\./ + ); + }); +}); diff --git a/packages/hardhat-ignition-viem/test/setup.ts b/packages/hardhat-ignition-viem/test/setup.ts new file mode 100644 index 0000000000..83ca4a5922 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/setup.ts @@ -0,0 +1,11 @@ +/* eslint-disable import/no-unused-modules */ +import chai from "chai"; +import chaiAsPromised from "chai-as-promised"; +import sinon from "sinon"; + +chai.use(chaiAsPromised); +chai.config.truncateThreshold = 1000; + +afterEach(() => { + sinon.restore(); +}); diff --git a/packages/hardhat-ignition-viem/test/strategies/helper-invocation.ts b/packages/hardhat-ignition-viem/test/strategies/helper-invocation.ts new file mode 100644 index 0000000000..c4cb7660d0 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/strategies/helper-invocation.ts @@ -0,0 +1,91 @@ +/* eslint-disable import/no-unused-modules */ +import { + NamedArtifactContractDeploymentFuture, + buildModule, +} from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { IgnitionModuleResultsToViemContracts } from "../../src/ignition-module-results-to-viem-contracts"; +import { useIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("strategies - invocation via helper", () => { + const example32ByteSalt = + "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"; + + describe("no Hardhat config setup", () => { + useIgnitionProject("minimal"); + + let result: IgnitionModuleResultsToViemContracts< + string, + { + foo: NamedArtifactContractDeploymentFuture<"Foo">; + } + >; + + it("should execute create2 when passed config programmatically via helper", async function () { + const moduleDefinition = buildModule("Module", (m) => { + const foo = m.contract("Foo"); + + return { foo }; + }); + + result = await this.hre.ignition.deploy(moduleDefinition, { + strategy: "create2", + strategyConfig: { + salt: example32ByteSalt, + }, + }); + + assert.equal( + result.foo.address, + "0x9318a275A28F46CA742f84402226E27463cA8050" + ); + }); + + it("should error on create2 when passed bad config", async function () { + const moduleDefinition = buildModule("Module", (m) => { + const foo = m.contract("Foo"); + + return { foo }; + }); + + await assert.isRejected( + this.hre.ignition.deploy(moduleDefinition, { + strategy: "create2", + strategyConfig: { + salt: undefined as any, + }, + }), + /IGN1102: Missing required strategy configuration parameter 'salt' for the strategy 'create2'/ + ); + }); + }); + + describe("Hardhat config setup with create2 config", () => { + useIgnitionProject("create2"); + + let result: IgnitionModuleResultsToViemContracts< + string, + { + baz: NamedArtifactContractDeploymentFuture<"Baz">; + } + >; + + it("should execute create2 with the helper loading the Hardhat config", async function () { + const moduleDefinition = buildModule("Module", (m) => { + const baz = m.contract("Baz"); + + return { baz }; + }); + + result = await this.hre.ignition.deploy(moduleDefinition, { + strategy: "create2", + }); + + assert.equal( + result.baz.address, + "0x8EFE40FAEF47066689Cb06b561F5EC63F9DeA616" + ); + }); + }); +}); diff --git a/packages/hardhat-ignition-viem/test/test-helpers/externally-loaded-contract.ts b/packages/hardhat-ignition-viem/test/test-helpers/externally-loaded-contract.ts new file mode 100644 index 0000000000..cd8f2a6172 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/test-helpers/externally-loaded-contract.ts @@ -0,0 +1,94 @@ +/** + * This is the artifact of a contract that is not part of the compilation output. + * + * Based on the following Solidity: + * + * ``` + contract ExternallyLoadedContract { + bool public isExternallyLoaded = true; + uint256 public x = 1; + + function buildMessage( + string memory message + ) public pure returns (string memory) { + return string.concat("A message: ", message); + } + + function inc() public returns (uint256) { + x++; + return x; + } + } + * ``` + */ +export const externallyLoadedContractArtifact = { + _format: "hh-sol-artifact-1", + contractName: "ExternallyLoadedContract", + sourceName: "contracts/Foo.sol", + abi: [ + { + inputs: [ + { + internalType: "string", + name: "message", + type: "string", + }, + ], + name: "buildMessage", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [], + name: "inc", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "isExternallyLoaded", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "x", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + ], + bytecode: + "0x608060405260016000806101000a81548160ff0219169083151502179055506001805534801561002e57600080fd5b506105208061003e6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80630c55699c14610051578063371303c01461006f578063ae78e06b1461008d578063c4a5693d146100ab575b600080fd5b6100596100db565b6040516100669190610156565b60405180910390f35b6100776100e1565b6040516100849190610156565b60405180910390f35b610095610103565b6040516100a2919061018c565b60405180910390f35b6100c560048036038101906100c09190610301565b610114565b6040516100d291906103c9565b60405180910390f35b60015481565b6000600160008154809291906100f69061041a565b9190505550600154905090565b60008054906101000a900460ff1681565b60608160405160200161012791906104c4565b6040516020818303038152906040529050919050565b6000819050919050565b6101508161013d565b82525050565b600060208201905061016b6000830184610147565b92915050565b60008115159050919050565b61018681610171565b82525050565b60006020820190506101a1600083018461017d565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61020e826101c5565b810181811067ffffffffffffffff8211171561022d5761022c6101d6565b5b80604052505050565b60006102406101a7565b905061024c8282610205565b919050565b600067ffffffffffffffff82111561026c5761026b6101d6565b5b610275826101c5565b9050602081019050919050565b82818337600083830152505050565b60006102a461029f84610251565b610236565b9050828152602081018484840111156102c0576102bf6101c0565b5b6102cb848285610282565b509392505050565b600082601f8301126102e8576102e76101bb565b5b81356102f8848260208601610291565b91505092915050565b600060208284031215610317576103166101b1565b5b600082013567ffffffffffffffff811115610335576103346101b6565b5b610341848285016102d3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610384578082015181840152602081019050610369565b60008484015250505050565b600061039b8261034a565b6103a58185610355565b93506103b5818560208601610366565b6103be816101c5565b840191505092915050565b600060208201905081810360008301526103e38184610390565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006104258261013d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610457576104566103eb565b5b600182019050919050565b7f41206d6573736167653a20000000000000000000000000000000000000000000815250565b600081905092915050565b600061049e8261034a565b6104a88185610488565b93506104b8818560208601610366565b80840191505092915050565b60006104cf82610462565b600b820191506104df8284610493565b91508190509291505056fea2646970667358221220d6f949c606fe2cf1b3274ef889cd952363a9558f9f5027ee18f03fe4c4cbaee864736f6c63430008130033", + deployedBytecode: + "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80630c55699c14610051578063371303c01461006f578063ae78e06b1461008d578063c4a5693d146100ab575b600080fd5b6100596100db565b6040516100669190610156565b60405180910390f35b6100776100e1565b6040516100849190610156565b60405180910390f35b610095610103565b6040516100a2919061018c565b60405180910390f35b6100c560048036038101906100c09190610301565b610114565b6040516100d291906103c9565b60405180910390f35b60015481565b6000600160008154809291906100f69061041a565b9190505550600154905090565b60008054906101000a900460ff1681565b60608160405160200161012791906104c4565b6040516020818303038152906040529050919050565b6000819050919050565b6101508161013d565b82525050565b600060208201905061016b6000830184610147565b92915050565b60008115159050919050565b61018681610171565b82525050565b60006020820190506101a1600083018461017d565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61020e826101c5565b810181811067ffffffffffffffff8211171561022d5761022c6101d6565b5b80604052505050565b60006102406101a7565b905061024c8282610205565b919050565b600067ffffffffffffffff82111561026c5761026b6101d6565b5b610275826101c5565b9050602081019050919050565b82818337600083830152505050565b60006102a461029f84610251565b610236565b9050828152602081018484840111156102c0576102bf6101c0565b5b6102cb848285610282565b509392505050565b600082601f8301126102e8576102e76101bb565b5b81356102f8848260208601610291565b91505092915050565b600060208284031215610317576103166101b1565b5b600082013567ffffffffffffffff811115610335576103346101b6565b5b610341848285016102d3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610384578082015181840152602081019050610369565b60008484015250505050565b600061039b8261034a565b6103a58185610355565b93506103b5818560208601610366565b6103be816101c5565b840191505092915050565b600060208201905081810360008301526103e38184610390565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006104258261013d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610457576104566103eb565b5b600182019050919050565b7f41206d6573736167653a20000000000000000000000000000000000000000000815250565b600081905092915050565b600061049e8261034a565b6104a88185610488565b93506104b8818560208601610366565b80840191505092915050565b60006104cf82610462565b600b820191506104df8284610493565b91508190509291505056fea2646970667358221220d6f949c606fe2cf1b3274ef889cd952363a9558f9f5027ee18f03fe4c4cbaee864736f6c63430008130033", + linkReferences: {}, + deployedLinkReferences: {}, +} as const; diff --git a/packages/hardhat-ignition-viem/test/test-helpers/use-ignition-project.ts b/packages/hardhat-ignition-viem/test/test-helpers/use-ignition-project.ts new file mode 100644 index 0000000000..42fc434fc0 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/test-helpers/use-ignition-project.ts @@ -0,0 +1,28 @@ +import { resetHardhatContext } from "hardhat/plugins-testing"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import path from "path"; + +declare module "mocha" { + interface Context { + hre: HardhatRuntimeEnvironment; + } +} + +export function useIgnitionProject(fixtureProjectName: string) { + beforeEach("Load environment", async function () { + process.chdir( + path.join(__dirname, "../fixture-projects", fixtureProjectName) + ); + + const hre = require("hardhat"); + + await hre.network.provider.send("evm_setAutomine", [true]); + await hre.run("compile", { quiet: true }); + + this.hre = hre; + }); + + afterEach("reset hardhat context", function () { + resetHardhatContext(); + }); +} diff --git a/packages/hardhat-ignition-viem/test/use-module.ts b/packages/hardhat-ignition-viem/test/use-module.ts new file mode 100644 index 0000000000..b89897e54b --- /dev/null +++ b/packages/hardhat-ignition-viem/test/use-module.ts @@ -0,0 +1,32 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { useIgnitionProject } from "./test-helpers/use-ignition-project"; + +describe("viem results should work across useModule boundaries", () => { + useIgnitionProject("minimal"); + + it("should only return properties for the properties of the module results", async function () { + const submoduleDefinition = buildModule("Submodule", (m) => { + const foo = m.contract("Foo"); + + return { foo }; + }); + + const moduleDefinition = buildModule("Module", (m) => { + const { foo } = m.useModule(submoduleDefinition); + + return { foo }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.equal(await result.foo.read.x(), 1n); + + await result.foo.write.inc(); + await result.foo.write.inc(); + + assert.equal(await result.foo.read.x(), 3n); + }); +}); diff --git a/packages/hardhat-ignition-viem/test/viem-instances/artifact-contract-at.ts b/packages/hardhat-ignition-viem/test/viem-instances/artifact-contract-at.ts new file mode 100644 index 0000000000..66d306d513 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/viem-instances/artifact-contract-at.ts @@ -0,0 +1,109 @@ +import { ContractAtFuture, buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { IgnitionModuleResultsToViemContracts } from "../../src/ignition-module-results-to-viem-contracts"; +import { externallyLoadedContractArtifact } from "../test-helpers/externally-loaded-contract"; +import { useIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("deploy converts ignition artifact contractAt to viem instance", () => { + useIgnitionProject("minimal"); + + let result: IgnitionModuleResultsToViemContracts< + string, + { + externallyLoadedContractAt: ContractAtFuture< + (typeof externallyLoadedContractArtifact)["abi"] + >; + } + >; + + beforeEach(async function () { + const moduleDefinition = buildModule("Module", (m) => { + const externallyLoadedContract = m.contract( + "ExternallyLoadedContract", + externallyLoadedContractArtifact, + [] + ); + + const externallyLoadedContractAt = m.contractAt( + "externallyLoadedContractAt", + externallyLoadedContractArtifact, + externallyLoadedContract, + { id: "externallyLoadedContractAt" } + ); + + return { externallyLoadedContractAt }; + }); + + result = await this.hre.ignition.deploy(moduleDefinition); + }); + + it("should provide the address", async function () { + assert.equal( + result.externallyLoadedContractAt.address, + "0x5FbDB2315678afecb367f032d93F642f64180aa3" + ); + }); + + it("should provide the abi", async function () { + assert.equal( + result.externallyLoadedContractAt.abi, + externallyLoadedContractArtifact.abi + ); + }); + + it("should allow reading the contract instance", async function () { + assert.equal( + await result.externallyLoadedContractAt.read.buildMessage([ + "Hello World", + ]), + "A message: Hello World" + ); + }); + + it("should allow writing to the contract instance", async function () { + await result.externallyLoadedContractAt.write.inc(); + await result.externallyLoadedContractAt.write.inc(); + await result.externallyLoadedContractAt.write.inc(); + + assert.equal(await result.externallyLoadedContractAt.read.x(), 4n); + }); + + it("should support simulating write function calls", async function () { + const { result: simulationResult } = + await result.externallyLoadedContractAt.simulate.inc(); + + assert.equal(simulationResult, 2n); + }); + + it("should support gas estimation of write function calls", async function () { + const estimation = + await result.externallyLoadedContractAt.estimateGas.inc(); + + assert.isDefined(estimation); + assert(typeof estimation === "bigint"); + }); + + it("should enforce the type is constrained to the contracts functions", async function () { + await assert.isRejected( + // @ts-expect-error + result.externallyLoadedContractAt.write.nonexistantWrite(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + await assert.isRejected( + // @ts-expect-error + result.externallyLoadedContractAt.read.nonexistantRead(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + await assert.isRejected( + // @ts-expect-error + result.externallyLoadedContractAt.estimateGas.nonexistantEstimate(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + await assert.isRejected( + // @ts-expect-error + result.externallyLoadedContractAt.simulate.nonexistantEstimate(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + }); +}); diff --git a/packages/hardhat-ignition-viem/test/viem-instances/artifact-deployment-contract.ts b/packages/hardhat-ignition-viem/test/viem-instances/artifact-deployment-contract.ts new file mode 100644 index 0000000000..1c0188b307 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/viem-instances/artifact-deployment-contract.ts @@ -0,0 +1,103 @@ +import { + ContractDeploymentFuture, + buildModule, +} from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { IgnitionModuleResultsToViemContracts } from "../../src/ignition-module-results-to-viem-contracts"; +import { externallyLoadedContractArtifact } from "../test-helpers/externally-loaded-contract"; +import { useIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("deploy converts ignition artifact contract to viem instance", () => { + useIgnitionProject("minimal"); + + let result: IgnitionModuleResultsToViemContracts< + string, + { + externallyLoadedContract: ContractDeploymentFuture< + (typeof externallyLoadedContractArtifact)["abi"] + >; + } + >; + + beforeEach(async function () { + const moduleDefinition = buildModule("Module", (m) => { + const externallyLoadedContract = m.contract( + "ExternallyLoadedContract", + externallyLoadedContractArtifact, + [], + { id: "ExternallyLoadedContract" } + ); + + return { externallyLoadedContract }; + }); + + result = await this.hre.ignition.deploy(moduleDefinition); + }); + + it("should provide the address", async function () { + assert.equal( + result.externallyLoadedContract.address, + "0x5FbDB2315678afecb367f032d93F642f64180aa3" + ); + }); + + it("should provide the abi", async function () { + assert.equal( + result.externallyLoadedContract.abi, + externallyLoadedContractArtifact.abi + ); + }); + + it("should allow reading the contract instance", async function () { + assert.equal( + await result.externallyLoadedContract.read.buildMessage(["Hello World"]), + "A message: Hello World" + ); + }); + + it("should allow writing to the contract instance", async function () { + await result.externallyLoadedContract.write.inc(); + await result.externallyLoadedContract.write.inc(); + await result.externallyLoadedContract.write.inc(); + + assert.equal(await result.externallyLoadedContract.read.x(), 4n); + }); + + it("should support simulating write function calls", async function () { + const { result: simulationResult } = + await result.externallyLoadedContract.simulate.inc(); + + assert.equal(simulationResult, 2n); + }); + + it("should support gas estimation of write function calls", async function () { + const estimation = await result.externallyLoadedContract.estimateGas.inc(); + + assert.isDefined(estimation); + assert(typeof estimation === "bigint"); + }); + + it("should enforce the type is constrained to the contracts functions", async function () { + await assert.isRejected( + // @ts-expect-error + result.externallyLoadedContract.write.nonexistantWrite(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + await assert.isRejected( + // @ts-expect-error + result.externallyLoadedContract.read.nonexistantRead(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + await assert.isRejected( + // @ts-expect-error + result.externallyLoadedContract.estimateGas.nonexistantEstimate(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + await assert.isRejected( + // @ts-expect-error + result.externallyLoadedContract.simulate.nonexistantEstimate(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + }); +}); diff --git a/packages/hardhat-ignition-viem/test/viem-instances/named-contract-at.ts b/packages/hardhat-ignition-viem/test/viem-instances/named-contract-at.ts new file mode 100644 index 0000000000..ac8f723226 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/viem-instances/named-contract-at.ts @@ -0,0 +1,103 @@ +import { + NamedArtifactContractAtFuture, + buildModule, +} from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { IgnitionModuleResultsToViemContracts } from "../../src/ignition-module-results-to-viem-contracts"; +import { useIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("deploy converts ignition named contractAt to viem instance", () => { + useIgnitionProject("minimal"); + + let result: IgnitionModuleResultsToViemContracts< + string, + { + contractAtFoo: NamedArtifactContractAtFuture<"Foo">; + } + >; + + beforeEach(async function () { + const moduleDefinition = buildModule("Module", (m) => { + const foo = m.contract("Foo"); + const contractAtFoo = m.contractAt("Foo", foo, { id: "ContractAtFoo" }); + + return { contractAtFoo }; + }); + + result = await this.hre.ignition.deploy(moduleDefinition); + }); + + it("should provide the address", async function () { + assert.equal( + result.contractAtFoo.address, + "0x5FbDB2315678afecb367f032d93F642f64180aa3" + ); + }); + + it("should provide the abi", async function () { + assert.isDefined(result.contractAtFoo.abi); + }); + + it("should allow reading the contract instance", async function () { + assert.equal(await result.contractAtFoo.read.x(), 1n); + }); + + it("should allow writing to the contract instance", async function () { + assert.equal(await result.contractAtFoo.read.x(), 1n); + + await result.contractAtFoo.write.inc(); + await result.contractAtFoo.write.inc(); + + assert.equal(await result.contractAtFoo.read.x(), 3n); + }); + + it("should support simulating write function calls", async function () { + const { result: addedNumberResult } = + await result.contractAtFoo.simulate.incByPositiveNumber([2n]); + + assert.equal(addedNumberResult, 3n); + }); + + it("should support gas estimation of write function calls", async function () { + const estimation = await result.contractAtFoo.estimateGas.inc(); + + assert.isDefined(estimation); + assert(typeof estimation === "bigint"); + }); + + it("should support events", async function () { + await result.contractAtFoo.write.inc(); + + const logs = await result.contractAtFoo.getEvents.IncEvent(); + + assert.equal(logs.length, 1); + assert.equal( + logs[0].args.sender, + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + ); + }); + + it("should enforce the type is constrained to the contracts functions", async function () { + await assert.isRejected( + // @ts-expect-error + result.contractAtFoo.write.nonexistantWrite(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + await assert.isRejected( + // @ts-expect-error + result.contractAtFoo.read.nonexistantRead(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + await assert.isRejected( + // @ts-expect-error + result.contractAtFoo.estimateGas.nonexistantEstimate(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + await assert.isRejected( + // @ts-expect-error + result.contractAtFoo.simulate.nonexistantEstimate(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + }); +}); diff --git a/packages/hardhat-ignition-viem/test/viem-instances/named-deployment-contract.ts b/packages/hardhat-ignition-viem/test/viem-instances/named-deployment-contract.ts new file mode 100644 index 0000000000..65861373ea --- /dev/null +++ b/packages/hardhat-ignition-viem/test/viem-instances/named-deployment-contract.ts @@ -0,0 +1,103 @@ +/* eslint-disable import/no-unused-modules */ +import { + NamedArtifactContractDeploymentFuture, + buildModule, +} from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { IgnitionModuleResultsToViemContracts } from "../../src/ignition-module-results-to-viem-contracts"; +import { useIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("deploy converts ignition named contract to viem instance", () => { + useIgnitionProject("minimal"); + + let result: IgnitionModuleResultsToViemContracts< + string, + { + foo: NamedArtifactContractDeploymentFuture<"Foo">; + } + >; + + beforeEach(async function () { + const moduleDefinition = buildModule("Module", (m) => { + const foo = m.contract("Foo"); + + return { foo }; + }); + + result = await this.hre.ignition.deploy(moduleDefinition); + }); + + it("should provide the address", async function () { + assert.equal( + result.foo.address, + "0x5FbDB2315678afecb367f032d93F642f64180aa3" + ); + }); + + it("should provide the abi", async function () { + assert.isDefined(result.foo.abi); + }); + + it("should allow reading the contract instance", async function () { + assert.equal(await result.foo.read.x(), 1n); + }); + + it("should allow writing to the contract instance", async function () { + assert.equal(await result.foo.read.x(), 1n); + + await result.foo.write.inc(); + await result.foo.write.inc(); + + assert.equal(await result.foo.read.x(), 3n); + }); + + it("should support simulating write function calls", async function () { + const { result: addedNumberResult } = + await result.foo.simulate.incByPositiveNumber([2n]); + + assert.equal(addedNumberResult, 3n); + }); + + it("should support gas estimation of write function calls", async function () { + const estimation = await result.foo.estimateGas.inc(); + assert.isDefined(estimation); + + assert(typeof estimation === "bigint"); + }); + + it("should support events", async function () { + await result.foo.write.inc(); + + const logs = await result.foo.getEvents.IncEvent(); + + assert.equal(logs.length, 1); + assert.equal( + logs[0].args.sender, + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + ); + }); + + it("should enforce the type is constrained to the contracts functions", async function () { + await assert.isRejected( + // @ts-expect-error + result.foo.write.nonexistantWrite(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + await assert.isRejected( + // @ts-expect-error + result.foo.read.nonexistantRead(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + await assert.isRejected( + // @ts-expect-error + result.foo.estimateGas.nonexistantEstimate(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + await assert.isRejected( + // @ts-expect-error + result.foo.simulate.nonexistantEstimate(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + }); +}); diff --git a/packages/hardhat-ignition-viem/test/viem-results.ts b/packages/hardhat-ignition-viem/test/viem-results.ts new file mode 100644 index 0000000000..67e1de8236 --- /dev/null +++ b/packages/hardhat-ignition-viem/test/viem-results.ts @@ -0,0 +1,80 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { externallyLoadedContractArtifact } from "./test-helpers/externally-loaded-contract"; +import { useIgnitionProject } from "./test-helpers/use-ignition-project"; + +describe("viem results", () => { + useIgnitionProject("minimal"); + + it("should only return properties for the properties of the module results", async function () { + const moduleDefinition = buildModule("Module", (m) => { + const foo = m.contract("Foo"); + + return { foo }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.isDefined(result.foo); + + // @ts-expect-error - only returned result keys should exist + assert.isUndefined(result.nonexistant); + }); + + it("should differentiate between different contracts in the type system", async function () { + const moduleDefinition = buildModule("Module", (m) => { + const foo = m.contract("Foo"); + const bar = m.contract("Bar"); + const baz = m.contract("Bas", externallyLoadedContractArtifact); + + return { foo, bar, baz }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.isTrue(await result.foo.read.isFoo()); + assert.isTrue(await result.bar.read.isBar()); + assert.isTrue(await result.baz.read.isExternallyLoaded()); + + // Calling the wrong method on a viem instance should throw, but more + // importantly give a type error. + + // foo shouldn't have bar or baz methods + await assert.isRejected( + // @ts-expect-error - isBar is not a method on Foo + result.foo.read.isBar(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + await assert.isRejected( + // @ts-expect-error - isBar is not a method on Foo + result.foo.read.isExternallyLoaded(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + + // bar shouldn't have foo or baz methods + await assert.isRejected( + // @ts-expect-error - isFoo is not a method on Bar + result.bar.read.isFoo(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + await assert.isRejected( + // @ts-expect-error - isExternallyLoaded is not a method on Bar + result.bar.read.isExternallyLoaded(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + + // baz shouldn't have foo or bar methods + await assert.isRejected( + // @ts-expect-error - isFoo is not a method on the externally loaded contract + result.baz.read.isFoo(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + await assert.isRejected( + // @ts-expect-error - isBar is not a method on the externally loaded contract + result.baz.read.isBar(), + /Make sure you are using the correct ABI and that the function exists on it./ + ); + }); +}); diff --git a/packages/hardhat-ignition-viem/tsconfig.json b/packages/hardhat-ignition-viem/tsconfig.json new file mode 100644 index 0000000000..d788dcf5b4 --- /dev/null +++ b/packages/hardhat-ignition-viem/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../config/typescript/tsconfig.json", + "compilerOptions": { + "target": "ES2022", + "outDir": "dist", + "composite": true, + "jsx": "react-jsx" + }, + "references": [ + { "path": "../hardhat-ignition-core" }, + { "path": "../hardhat-ignition" }, + { "path": "../hardhat-viem" }, + { "path": "../hardhat-core" } + ] +} diff --git a/packages/hardhat-ignition/.eslintrc.js b/packages/hardhat-ignition/.eslintrc.js new file mode 100644 index 0000000000..4285f9e252 --- /dev/null +++ b/packages/hardhat-ignition/.eslintrc.js @@ -0,0 +1,8 @@ +module.exports = { + extends: [`${__dirname}/../../config/eslint/eslintrc.js`], + parserOptions: { + project: `${__dirname}/tsconfig.json`, + sourceType: "module", + }, + ignorePatterns: [".eslintrc.js"], +}; diff --git a/packages/hardhat-ignition/.gitignore b/packages/hardhat-ignition/.gitignore new file mode 100644 index 0000000000..c1c475b6a3 --- /dev/null +++ b/packages/hardhat-ignition/.gitignore @@ -0,0 +1,144 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* +*.ndjson + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage +*.lcov + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) +web_modules/ + +# TypeScript cache +*.tsbuildinfo + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional stylelint cache +.stylelintcache + +# Microbundle cache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variable files +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) +.cache +.parcel-cache + +# Next.js build output +.next +out + +# Nuxt.js build / generate output +.nuxt +dist + +# Gatsby files +.cache/ +# Comment in the public line in if your project uses Gatsby and not Next.js +# https://nextjs.org/blog/next-9-1#public-directory-support +# public + +# vuepress build output +.vuepress/dist + +# vuepress v2.x temp and cache directory +.temp +.cache + +# Docusaurus cache and generated files +.docusaurus + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +# TernJS port file +.tern-port + +# Stores VSCode versions used for testing VSCode extensions +.vscode-test + +# yarn v2 +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* +.npmrc + +# Mac OSX garbage +.DS_Store + +# Custom workspace settings for VSCode +.vscode/settings.json + +# Webstorm files +.idea/ + +# npm lockfile since we use pnpm now +package-lock.json diff --git a/packages/hardhat-ignition/.mocharc.json b/packages/hardhat-ignition/.mocharc.json new file mode 100644 index 0000000000..3c924036ae --- /dev/null +++ b/packages/hardhat-ignition/.mocharc.json @@ -0,0 +1,6 @@ +{ + "require": "ts-node/register/transpile-only", + "file": "./test/setup.ts", + "timeout": 20000, + "exit": true +} diff --git a/packages/hardhat-ignition/.npmignore b/packages/hardhat-ignition/.npmignore new file mode 100644 index 0000000000..ecceab5f3a --- /dev/null +++ b/packages/hardhat-ignition/.npmignore @@ -0,0 +1,13 @@ +coverage/ +.nyc_output/ +*.tsbuildinfo +**/.eslintrc.js +post-build.js +.mocharc.json +.nycrc +.prettierignore +.prettierrc +dist/test +src/ +test/ +esbuild.js diff --git a/packages/hardhat-ignition/.nycrc b/packages/hardhat-ignition/.nycrc new file mode 100644 index 0000000000..0f9e436c71 --- /dev/null +++ b/packages/hardhat-ignition/.nycrc @@ -0,0 +1,12 @@ +{ + "extends": "@istanbuljs/nyc-config-typescript", + "check-coverage": true, + "statements": 70, + "branches": 50, + "functions": 60, + "lines": 70, + "all": true, + "include": ["src/**/*.ts"], + "reporter": ["html", "lcov", "text", "text-summary"], + "report-dir": "coverage" +} diff --git a/packages/hardhat-ignition/.prettierignore b/packages/hardhat-ignition/.prettierignore new file mode 100644 index 0000000000..4ae5fe88f4 --- /dev/null +++ b/packages/hardhat-ignition/.prettierignore @@ -0,0 +1,9 @@ +/node_modules +/dist +/test/fixture-projects/*/artifacts +/test/fixture-projects/*/cache +/coverage +/.nyc_output +/test/fixture-projects/*/deployments/*/artifacts +/test/fixture-projects/*/deployments/*/build-info + diff --git a/packages/hardhat-ignition/CHANGELOG.md b/packages/hardhat-ignition/CHANGELOG.md new file mode 100644 index 0000000000..7884f11de2 --- /dev/null +++ b/packages/hardhat-ignition/CHANGELOG.md @@ -0,0 +1,409 @@ +# Changelog + +## 0.15.11 + +### Patch Changes + +- 23280b8: Resolve all dependencies when using submodules in `after` + +## 0.15.10 + +### Patch Changes + +- d96c003: Fix for bug when we fail to save transaction hash + +## 0.15.9 - 2024-12-18 + +### Added + +- Standard Ignition UI can now be enabled when deploying via Hardhat scripts by setting `displayUi: true` in the `deploy` function options, @zoeyTM ([#843](https://github.com/NomicFoundation/hardhat-ignition/pull/843)) +- Ignition modules can now be set as a dependency in the `after` option of futures, @zoeyTM ([#828](https://github.com/NomicFoundation/hardhat-ignition/pull/828)) +- The `ignition transactions` command output will now include a link to view each transaction on the configured block explorer, @zoeyTM ([#849](https://github.com/NomicFoundation/hardhat-ignition/pull/849)) +- Module parameters can now be directly imported from a JSON file when deploying via Hardhat scripts by passing an absolute path to the file to the `parameters` option, @zoeyTM ([#850](https://github.com/NomicFoundation/hardhat-ignition/pull/850)) + +### Fixed + +- Properly handle errors when verifying deployments that use external artifacts, @zoeyTM ([#848](https://github.com/NomicFoundation/hardhat-ignition/pull/848)) +- Fix issue with `ignition status` command not working with deployments that use external artifacts, @zoeyTM ([#846](https://github.com/NomicFoundation/hardhat-ignition/pull/846)) + +## 0.15.8 - 2024-11-22 + +### Fixed + +- `transactions` command now properly serializes `bigint` values, @zoeyTM ([#837](https://github.com/NomicFoundation/hardhat-ignition/pull/837)) +- Additional validations added for global parameters, @kanej ([#832](https://github.com/NomicFoundation/hardhat-ignition/pull/832)) + +## 0.15.7 - 2024-10-24 + +### Added + +- New CLI command `ignition transactions` to list all transactions sent for a given deployment ID, @zoeyTM ([#821](https://github.com/NomicFoundation/hardhat-ignition/pull/821)) +- Module parameters can now be set at the global level using `$global`, @zoeyTM ([#819](https://github.com/NomicFoundation/hardhat-ignition/pull/819)) + +### Fixed + +- Gas fields are now properly set for Optimistic BNB, @zoeyTM ([#826](https://github.com/NomicFoundation/hardhat-ignition/pull/826)) +- Corrected resolution of artifacts when using fully qualified names in deployment modules, @kanej ([#822](https://github.com/NomicFoundation/hardhat-ignition/pull/822)) + +## 0.15.6 - 2024-09-25 + +### Added + +- Updates to the visualization UI, including the ability to zoom and pan the mermaid diagram ([#810](https://github.com/NomicFoundation/hardhat-ignition/pull/810)) +- `gasPrice` and `disableFeeBumping` config fields added as part of our L2 gas logic update ([#808](https://github.com/NomicFoundation/hardhat-ignition/pull/808)) +- Debug logging for communication errors with Hardhat Ledger ([#792](https://github.com/NomicFoundation/hardhat-ignition/pull/792)) +- JSON5 support for module parameters, thanks @erhant ([#800](https://github.com/NomicFoundation/hardhat-ignition/pull/800)) +- Add `writeLocalhostDeployment` flag to allow saving deployment artifacts when deploying to the ephemeral Hardhat network, thanks @SebastienGllmt ([#816](https://github.com/NomicFoundation/hardhat-ignition/pull/816)) + +### Fixed + +- Replace `this` with the class itself in `ViemIgnitionHelper`, thanks @iosh ([#796](https://github.com/NomicFoundation/hardhat-ignition/pull/796)) + +## 0.15.5 - 2024-06-17 + +### Added + +- New function `m.encodeFunctionCall` ([#761](https://github.com/NomicFoundation/hardhat-ignition/pull/761)) + +### Fixed + +- Adjusted regex to allow calling overloaded functions with array parameters ([#774](https://github.com/NomicFoundation/hardhat-ignition/pull/774)) +- Handle anvil response for `hardhat_setBalance` when deploying with create2 ([#773](https://github.com/NomicFoundation/hardhat-ignition/pull/773)) +- Properly resolve `verify` logic when dealing with circular or very deeply nested imports ([#772](https://github.com/NomicFoundation/hardhat-ignition/pull/772)) +- Exclude BNB Test Chain from zero fee configuration in gas fee logic, thanks @MukulKolpe ([#768](https://github.com/NomicFoundation/hardhat-ignition/pull/768)) + +## 0.15.4 - 2024-05-14 + +### Fixed + +- Reconcile address parameters with mismatched casings ([#748](https://github.com/NomicFoundation/hardhat-ignition/pull/748)) +- Display better error messages for insufficient funds ([#754](https://github.com/NomicFoundation/hardhat-ignition/pull/754)) + +## 0.15.3 - 2024-05-09 + +### Fixed + +- Exclude BNB Chain from zero fee configuration in gas fee logic, thanks @magicsih ([#755](https://github.com/NomicFoundation/hardhat-ignition/pull/755)) + +## 0.15.2 - 2024-05-02 + +### Added + +- Improved support for deploying via a Ledger Hardware wallet, [see our guide for details](https://hardhat.org/ignition/docs/guides/ledger) ([#720](https://github.com/NomicFoundation/hardhat-ignition/issues/720)) +- Support `maxPriorityFeePerGas` as a configuration parameter ([#728](https://github.com/NomicFoundation/hardhat-ignition/issues/728)) +- Use RPC call `eth_maxPriorityFeePerGas` in gas fee calculations when available ([#743](https://github.com/NomicFoundation/hardhat-ignition/issues/743)) +- Support zero gas fee chains (like private Besu chains), thanks @jimthematrix ([#730](https://github.com/NomicFoundation/hardhat-ignition/pull/730)) + +### Fixed + +- Use pre-EIP-1559 transactions for Polygon to avoid dropped transactions ([#735](https://github.com/NomicFoundation/hardhat-ignition/issues/735)) + +## 0.15.1 - 2024-04-04 + +### Added + +- Add a configurable upper limit for the maxFeePerGas ([#685](https://github.com/NomicFoundation/hardhat-ignition/issues/685)) +- Support writing and reading from deployments folder within tests and scripts ([#704](https://github.com/NomicFoundation/hardhat-ignition/pull/704)) +- Add `ignition deployments` task to list all the current deployments ([#646](https://github.com/NomicFoundation/hardhat-ignition/issues/646)) + +### Changed + +- Deploying to a cleared local hardhat node ignores previous deployment ([#650](https://github.com/NomicFoundation/hardhat-ignition/issues/650)) + +### Fixed + +- More resilent automine check ([#721](https://github.com/NomicFoundation/hardhat-ignition/issues/721)) +- `getCode` usage brought in line with Ethereum RPC standard ([#715](https://github.com/NomicFoundation/hardhat-ignition/issues/715)) +- Fixed unexpected next nonce on revert ([#676](https://github.com/NomicFoundation/hardhat-ignition/issues/676)) +- Reduce sources being passed to etherscan for verification ([#706](https://github.com/NomicFoundation/hardhat-ignition/issues/706)) + +## 0.15.0 - 2024-03-13 + +### Added + +- Support `create2` through strategies, for more details see [our `create2` guide](https://hardhat.org/ignition/docs/guides/create2). ([#629](https://github.com/NomicFoundation/hardhat-ignition/issues/629)) + +## 0.14.0 - 2024-02-21 + +### Added + +- Support BigInt values in Module Parameter files by encoding them as strings with the format /d+n/ ([#663](https://github.com/NomicFoundation/hardhat-ignition/issues/663)) + +## 0.13.2 - 2024-01-25 + +### Fixed + +- Add memory pool lookup retry to reduce errors from slow propogation ([#667](https://github.com/NomicFoundation/hardhat-ignition/pull/667)) + +### Added + +- Improve Module API typescript doc comments to enhance intellisense experience ([#642](https://github.com/NomicFoundation/hardhat-ignition/issues/642)) +- Support module parameters taking accounts as the default value ([673](https://github.com/NomicFoundation/hardhat-ignition/issues/673)) + +## 0.13.1 - 2023-12-19 + +### Added + +- New flag `--reset` for `ignition deploy` to wipe the existing deployment state before running ([#649](https://github.com/NomicFoundation/hardhat-ignition/issues/649)) + +### Fixed + +- Fix bug with `process.stdout` being used in a non-tty context ([#644](https://github.com/NomicFoundation/hardhat-ignition/issues/644)) + +## 0.13.0 - 2023-12-13 + +### Added + +- Add support for setting the default sender account from tests and scripts ([#639](https://github.com/NomicFoundation/hardhat-ignition/issues/639)) +- Add support for setting the default sender from the cli ([#620](https://github.com/NomicFoundation/hardhat-ignition/issues/620)) + +### Changed + +- Split out `ethers` support from `@nomicfoundation/hardhat-plugin`, to allow opting for either **ethers** or **Viem** in tests and scripts. If you were using `hre.ignition.deploy(...)` in tests or scripts you will need to install, and require in your Hardhat config, the `@nomicfoundation/hardhat-plugin-ethers` package. For more details on our [Viem support see our guide](https://hardhat.org/ignition/docs/guides/viem). ([#612](https://github.com/NomicFoundation/hardhat-ignition/pull/612)) + +## 0.12.0 - 2023-12-05 + +### Added + +- Add support for verification, see our [verification guide](https://hardhat.org/ignition/docs/guides/verify) for more information ([#630](https://github.com/NomicFoundation/hardhat-ignition/issues/630)) + +### Changed + +- Improved the error for fee exceeding block gas limit ([#594](https://github.com/NomicFoundation/hardhat-ignition/issues/594)) + +## 0.11.2 - 2023-11-06 + +### Added + +- Support account values in _send_ `to` in Module API ([#618](https://github.com/NomicFoundation/hardhat-ignition/issues/618)) +- Validation check for duplicate module ids ([#608](https://github.com/NomicFoundation/hardhat-ignition/issues/608)) + +### Fixed + +- Fix `ContractAt`s being recorded to `deployed_addresses.json` ([#607](https://github.com/NomicFoundation/hardhat-ignition/issues/607)) + +## 0.11.1 - 2023-10-30 + +### Added + +- Give visual indication that there was a gas bump in `deploy` task ([#587](https://github.com/NomicFoundation/hardhat-ignition/issues/587)) + +### Changed + +- When displaying an Ethereum Address at the cli, show in checksum format ([#600](https://github.com/NomicFoundation/hardhat-ignition/issues/600)) +- Show a better message when no futures were executed during a rerun ([#586](https://github.com/NomicFoundation/hardhat-ignition/issues/586)) +- Less confusing message for no modules folder error ([#602](https://github.com/NomicFoundation/hardhat-ignition/issues/602)) + +## 0.11.0 - 2023-10-23 + +First public launch 🚀 + +### Added + +- Display batching information in the visualize report ([#494](https://github.com/NomicFoundation/hardhat-ignition/issues/494)) +- Update styling of visualize report ([#493](https://github.com/NomicFoundation/hardhat-ignition/issues/493)) +- Expand Module API so value and from support staticCall/readEventArg as values ([#455](https://github.com/NomicFoundation/hardhat-ignition/issues/455)) +- Support fully qualified contract names ([#563](https://github.com/NomicFoundation/hardhat-ignition/pull/563)) + +### Changed + +- More compact command-line UI ([#495](https://github.com/NomicFoundation/hardhat-ignition/issues/495)) +- Ignition tasks are now scoped e.g. `npx hardhat ignition deploy` ([#442](https://github.com/NomicFoundation/hardhat-ignition/issues/442)) +- The `ignition-info` task has been renamed to `status`, and now shows the status of the current deployment not just the successes ([#496](https://github.com/NomicFoundation/hardhat-ignition/issues/496)) +- Modules now have to be inside a `modules` subfolder within the `./ignition` folder ([#511](https://github.com/NomicFoundation/hardhat-ignition/issues/511)) +- Import of `buildModule` now from `@nomicfoundation/hardhat-ignition/modules` ([#540](https://github.com/NomicFoundation/hardhat-ignition/issues/540)) +- A warning is displayed if you are running against an in-process hardhat network ([#553](https://github.com/NomicFoundation/hardhat-ignition/issues/553)) +- The default deployment id is now `chain-` ([#551](https://github.com/NomicFoundation/hardhat-ignition/issues/551)) +- The `contractAt` signature overload for artifact has been changed to match other artifact overload signatures ([#557](https://github.com/NomicFoundation/hardhat-ignition/issues/557)) + +### Fixed + +- Improve loading times for other non-ignition hh tasks, when Ignition is included ([#13](https://github.com/NomicFoundation/hardhat-ignition/issues/13)) +- Only open visualization report if supported ([#504](https://github.com/NomicFoundation/hardhat-ignition/issues/504)) +- Fixed nonce check failure on rerun ([#506](https://github.com/NomicFoundation/hardhat-ignition/issues/506)) +- Ensure future's senders meet nonce sync checks ([#411](https://github.com/NomicFoundation/hardhat-ignition/issues/411)) +- Show all deployed contracts at the end of a deployment ([#480](https://github.com/NomicFoundation/hardhat-ignition/issues/480)) +- Rerun blocked by sent transactions message IGN403 ([#574](https://github.com/NomicFoundation/hardhat-ignition/issues/574)) +- Rerun over multiple batches trigger error IGN405 ([#576](https://github.com/NomicFoundation/hardhat-ignition/issues/576)) + +## 0.4.0 - 2023-09-15 + +### Added + +- Advanced cli UI for deploy ([#401](https://github.com/NomicFoundation/ignition/pull/401)) +- Store artifact debug files as part of deployment directory ([#473](https://github.com/NomicFoundation/ignition/pull/473)) + +### Changed + +- Changed npm package name to `@nomicfoundation/hardhat-ignition` +- rename the `plan` task to `visualize` ([#471](https://github.com/NomicFoundation/ignition/pull/471)) +- Constrain module ids and action ids to better support storing deployments on windows ([#466](https://github.com/NomicFoundation/ignition/pull/466)) +- Rename `use-verbose` flag on `deploy` task to `simple-text-ui` ([#444](https://github.com/NomicFoundation/ignition/pull/444)) + +### Fixed + +- Fix batch completion on non-automining chains ([#467](https://github.com/NomicFoundation/ignition/pull/467)) + +## 0.3.0 - 2023-08-30 + +### Added + +- Support eip-1559 style transactions ([#8](https://github.com/NomicFoundation/ignition/issues/8)) +- Automatic gas bumping of transactions ([#294](https://github.com/NomicFoundation/ignition/issues/294)) +- Improve validation based on artifacts ([#390](https://github.com/NomicFoundation/ignition/issues/390)) + +### Changed + +- Switch peer dependency from ethers v5 to ethers v6 ([#338](https://github.com/NomicFoundation/ignition/issues/338)) +- Deprecate support for node 14, and add support for node 20 ([#370](https://github.com/NomicFoundation/ignition/issues/370)) + +## 0.2.0 - 2023-08-16 + +### Added + +- The execution config is now exposed through deploy and wired into the `hardhat-ignition` plugin config. + +### Fixed + +- Switch default deploy configurations depending on whether the current network is automined. + +## 0.1.2 - 2023-07-31 + +### Fixed + +- Fix validation error when using the result of a `staticCall` as the address of a `contractAt`/`contractAtFromArtifact` ([#354](https://github.com/NomicFoundation/ignition/issues/357)) +- Fix bug in `staticCall` execution logic preventing successful execution + +## 0.1.1 - 2023-07-30 + +### Fixed + +- Fix validation error when using the result of a `readEventArgument` as the address of a `contractAt`/`contractAtFromArtifact` ([#354](https://github.com/NomicFoundation/ignition/issues/354)) + +## 0.1.0 - 2023-07-27 + +### Added + +- Rerunning now uses a reconciliation phase to allow more leeway in changing a module between runs +- Deployments against real networks are recorded to `./ignition/deployments/`, including recording the deployed addresses and the artifacts (i.e. abi, build-info etc) used for each contract deploy + +### Changed + +- The _Module API_ has went through considerable restructuring, including _breaking changes_, please see the `./docs` for more details +- The plan task has been enhanced to give a module centric view rather than the lower level execution that was previously shown +- The _ui_ during a deployment has been reduced to showing the results, the full UI will be brought back in a coming release + +## 0.0.13 - 2023-04-18 + +### Added + +- Support static calls in the Module API ([#85](https://github.com/NomicFoundation/ignition/issues/85)) +- Add command, `ignition-info`, to list previously deployed contracts ([#111](https://github.com/NomicFoundation/ignition/issues/111)) + +## 0.0.12 - 2023-04-04 + +### Fixed + +- Support recursive types in `m.call` args ([#186](https://github.com/NomicFoundation/ignition/issues/186)) + +## 0.0.11 - 2023-03-29 + +### Changed + +- Replace `m.getBytesForArtifact("Foo")` with `m.getArtifact("Foo")` in the module api ([#155](https://github.com/NomicFoundation/ignition/issues/155)) + +### Fixed + +- Fix libraries in plan ([#131](https://github.com/NomicFoundation/ignition/issues/131)) + +## 0.0.10 - 2023-03-14 + +### Added + +- Make Hardhat network accounts available within modules ([#166](https://github.com/NomicFoundation/ignition/pull/166)) + +### Changed + +- Show file/line/column against validation errors, so that module problems can more easily be traced back to the source code ([#160](https://github.com/NomicFoundation/ignition/pull/160)) + +## 0.0.9 - 2023-03-02 + +### Added + +- Support defining modules in typescript ([#101](https://github.com/NomicFoundation/ignition/issues/101)) +- Allow rerunning deployment while ignoring journal history through a `--force` flag ([#132](https://github.com/NomicFoundation/ignition/issues/132)) + +### Changed + +- Do not ask for confirmation when deploying to a hardhat node ([#134](https://github.com/NomicFoundation/ignition/issues/134)) + +## 0.0.8 - 2023-02-16 + +### Added + +- Allow file paths to ignition modules on cli to support cli completions for file discovery ([#102](https://github.com/NomicFoundation/ignition/issues/102)) + +### Changed + +- Rename config option `gasIncrementPerRetry` to `gasPriceIncrementPerRetry` for clarity ([#143](https://github.com/NomicFoundation/ignition/pull/143)) + +### Fixed + +- Improve error messages display during module validation ([#141](https://github.com/NomicFoundation/ignition/issues/141)) +- Ban passing async functions to `buildModule` ([#138](https://github.com/NomicFoundation/ignition/issues/138)) + +## 0.0.7 - 2023-01-31 + +### Fixed + +- Resolve parameter args for deployed contracts during execution ([#125](https://github.com/NomicFoundation/ignition/pull/125)) + +## 0.0.6 - 2023-01-20 + +### Added + +- Support rerunning deployments that errored or went to on-hold on a previous run ([#70](https://github.com/NomicFoundation/ignition/pull/70)) +- Support sending `ETH` to a contract without having to make a call/deploy ([#79](https://github.com/NomicFoundation/ignition/pull/79)) +- Confirm dialog on deploys to non-hardhat networks ([#95](https://github.com/NomicFoundation/ignition/issues/95)) + +### Changed + +- Rename the `awaitEvent` action in the api to `event` ([#108](https://github.com/NomicFoundation/ignition/issues/108)) + +## 0.0.5 - 2022-12-20 + +### Added + +- Add params section to deploy display in cli ([#74](https://github.com/NomicFoundation/ignition/pull/74)) +- Expose config for pollingInterval ([#75](https://github.com/NomicFoundation/ignition/pull/75)) +- Support `getBytesForArtifact` in deployment api ([#76](https://github.com/NomicFoundation/ignition/pull/76)) +- Support use of emitted event args as futures for later deployment api calls ([#77](https://github.com/NomicFoundation/ignition/pull/77)) +- Support event params futures in `contractAt` ([#78](https://github.com/NomicFoundation/ignition/pull/78)) + +### Fixed + +- Fix for planning on modules with deploys from artifacts ([#73](https://github.com/NomicFoundation/ignition/pull/73)) + +## 0.0.4 - 2022-11-22 + +### Added + +- Support setting module params from JSON file ([#64](https://github.com/NomicFoundation/ignition/pull/64)) + +## 0.0.3 - 2022-11-09 + +### Added + +- Allow modules to depend on other calls ([#53](https://github.com/NomicFoundation/ignition/pull/53)) +- Allow depending on a module ([#54](https://github.com/NomicFoundation/ignition/pull/54)) + +### Changed + +- Dependening on returned module contract equivalent to depending on the module ([#55](https://github.com/NomicFoundation/ignition/pull/55)) + +## 0.0.2 - 2022-10-26 + +### Added + +- Add `deploy` task to hardhat via the plugin +- Add `plan` task to hardhat via the plugin diff --git a/packages/hardhat-ignition/README.md b/packages/hardhat-ignition/README.md new file mode 100644 index 0000000000..7acbb2377a --- /dev/null +++ b/packages/hardhat-ignition/README.md @@ -0,0 +1,65 @@ +![hardhat_Ignition_banner](https://github.com/NomicFoundation/hardhat-ignition/assets/24030/cc73227b-8791-4bb3-bc9a-a39be69d215f) [![npm](https://img.shields.io/npm/v/@nomicfoundation/hardhat-ignition.svg)](https://www.npmjs.com/package/@nomicfoundation/hardhat-ignition) [![hardhat](https://hardhat.org/buidler-plugin-badge.svg?1)](https://hardhat.org) [![Open in Dev Containers](https://img.shields.io/static/v1?label=Dev%20Containers&message=Open&color=blue&logo=visualstudiocode)](https://vscode.dev/redirect?url=vscode://ms-vscode-remote.remote-containers/cloneInVolume?url=https://github.com/NomicFoundation/hardhat-ignition.git) + +--- + +# Hardhat Ignition + +Hardhat Ignition is a declarative system for deploying smart contracts on Ethereum. It enables you to define smart contract instances you want to deploy, and any operation you want to run on them. By taking over the deployment and execution, Hardhat Ignition lets you focus on your project instead of getting caught up in the deployment details. + +Built by the [Nomic Foundation](https://nomic.foundation/) for the Ethereum community. + +Join the Hardhat Ignition channel of our [Hardhat Community Discord server](https://hardhat.org/ignition-discord) to stay up to date on new releases and tutorials. + +## Installation + +```bash +# ethers users +npm install --save-dev @nomicfoundation/hardhat-ignition-ethers + +# viem users +npm install --save-dev @nomicfoundation/hardhat-ignition-viem +``` + +Import the plugin in your `hardhat.config.js``: + +```js +// ethers users +require("@nomicfoundation/hardhat-ignition-ethers"); + +// viem users +require("@nomicfoundation/hardhat-ignition-viem"); +``` + +Or if you are using TypeScript, in your `hardhat.config.ts``: + +```js +// ethers users +import "@nomicfoundation/hardhat-ignition-ethers"; + +// viem users +import "@nomicfoundation/hardhat-ignition-viem"; +``` + +## Documentation + +On [Hardhat Ignition's website](https://hardhat.org/ignition) you will find guides for: + +- [Getting started](https://hardhat.org/ignition/docs/getting-started) +- [Creating Modules](https://hardhat.org/ignition/docs/guides/creating-modules) +- [Deploying a module](https://hardhat.org/ignition/docs/guides/deploy) +- [Visualizing your module](https://hardhat.org/ignition/docs/guides/visualize) +- [Handling errors](https://hardhat.org/ignition/docs/guides/error-handling) +- [Modifying an existing module](https://hardhat.org/ignition/docs/guides/modifications) +- [Using Hardhat Ignition in your tests](https://hardhat.org/ignition/docs/guides/tests) + +## Contributing + +Contributions are always welcome! Feel free to open any issue or send a pull request. + +Go to [CONTRIBUTING.md](https://github.com/NomicFoundation/hardhat-ignition/blob/main/CONTRIBUTING.md) to learn about how to set up Hardhat Ignition's development environment. + +## Feedback, help and news + +[Hardhat Ignition on Discord](https://hardhat.org/ignition-discord): for questions and feedback. + +Follow [Hardhat](https://twitter.com/HardhatHQ) and [Nomic Foundation](https://twitter.com/NomicFoundation) on Twitter. diff --git a/packages/hardhat-ignition/package.json b/packages/hardhat-ignition/package.json new file mode 100644 index 0000000000..d6c43c1f2e --- /dev/null +++ b/packages/hardhat-ignition/package.json @@ -0,0 +1,98 @@ +{ + "name": "@nomicfoundation/hardhat-ignition", + "version": "0.15.11", + "license": "MIT", + "author": "Nomic Foundation", + "homepage": "https://hardhat.org", + "description": "Hardhat Ignition is a declarative system for deploying smart contracts on Ethereum. It enables you to define smart contract instances you want to deploy, and any operation you want to run on them. By taking over the deployment and execution, Hardhat Ignition lets you focus on your project instead of getting caught up in the deployment details.", + "repository": "github:NomicFoundation/hardhat-ignition", + "keywords": [ + "ethereum", + "smart-contracts", + "hardhat", + "blockchain", + "dapps", + "tooling", + "solidity", + "deployment" + ], + "main": "dist/src/index.js", + "types": "dist/src/index.d.ts", + "exports": { + ".": "./dist/src/index.js", + "./modules": "./dist/src/modules.js", + "./helpers": "./dist/src/helpers.js" + }, + "typesVersions": { + "*": { + "modules": [ + "./dist/src/modules.d.ts" + ], + "helpers": [ + "./dist/src/helpers.d.ts" + ] + } + }, + "scripts": { + "prebuild": "pnpm run --dir ../hardhat-ignition-ui build", + "build": "tsc --build", + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", + "eslint": "eslint \"src/**/*.{ts,tsx}\" \"test/**/*.{ts,tsx}\"", + "prettier": "prettier \"**/*.{js,ts,md,json}\"", + "test": "mocha --recursive \"test/**/*.ts\"", + "test:debug": "DEBUG='hardhat-ignition:*,ignition:*' pnpm test", + "test:coverage": "nyc mocha \"test/**/*.ts\"", + "test:build": "tsc --project ./test/", + "clean": "rimraf .nyc_output coverage dist tsconfig.tsbuildinfo ./test/fixture-projects/**/deployments ./test/fixture-projects/**/artifacts", + "prepack": "pnpm build" + }, + "devDependencies": { + "@istanbuljs/nyc-config-typescript": "1.0.2", + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.9", + "@nomicfoundation/hardhat-verify": "workspace:^2.0.1", + "@types/chai": "^4.2.22", + "@types/chai-as-promised": "^7.1.4", + "@types/debug": "^4.1.7", + "@types/fs-extra": "^9.0.13", + "@types/mocha": "9.1.1", + "@types/node": "^18.0.0", + "@types/prompts": "^2.4.2", + "@types/sinon": "^10.0.13", + "@typescript-eslint/eslint-plugin": "^5.57.1", + "@typescript-eslint/experimental-utils": "^5.62.0", + "@typescript-eslint/parser": "^5.57.1", + "chai": "^4.3.4", + "chai-as-promised": "7.1.1", + "eslint": "^8.38.0", + "eslint-config-prettier": "8.3.0", + "eslint-import-resolver-typescript": "^3.5.5", + "eslint-plugin-import": "2.29.0", + "eslint-plugin-mocha": "^9.0.0", + "eslint-plugin-no-only-tests": "3.1.0", + "eslint-plugin-prettier": "4.0.0", + "hardhat": "workspace:^2.18.0", + "mocha": "^9.1.3", + "nyc": "15.1.0", + "prettier": "2.8.8", + "rimraf": "3.0.2", + "sinon": "^14.0.0", + "ts-node": "10.9.1", + "typescript": "^5.0.2", + "viem": "^2.7.6" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-verify": "workspace:^2.0.1", + "hardhat": "workspace:^2.18.0" + }, + "dependencies": { + "@nomicfoundation/ignition-core": "workspace:^", + "@nomicfoundation/ignition-ui": "workspace:^", + "chalk": "^4.0.0", + "debug": "^4.3.2", + "fs-extra": "^10.0.0", + "prompts": "^2.4.2", + "json5": "^2.2.3" + } +} diff --git a/packages/hardhat-ignition/src/hardhat-artifact-resolver.ts b/packages/hardhat-ignition/src/hardhat-artifact-resolver.ts new file mode 100644 index 0000000000..0b22d18998 --- /dev/null +++ b/packages/hardhat-ignition/src/hardhat-artifact-resolver.ts @@ -0,0 +1,75 @@ +import { + Artifact, + ArtifactResolver, + BuildInfo, +} from "@nomicfoundation/ignition-core"; +import fs from "fs"; +import { HardhatPluginError } from "hardhat/plugins"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import path from "path"; + +export class HardhatArtifactResolver implements ArtifactResolver { + constructor(private _hre: HardhatRuntimeEnvironment) {} + + public async getBuildInfo( + contractName: string + ): Promise { + // If a fully qualified name is used, we can can + // leverage the artifact manager directly to load the build + // info. + if (this._isFullyQualifiedName(contractName)) { + return this._hre.artifacts.getBuildInfo(contractName); + } + + // Otherwise we have only the contract name, and need to + // resolve the artifact for the contract ourselves. + // We can build on the assumption that the contract name + // is unique based on Module validation. + const artifactPath = await this._resolvePath(contractName); + + if (artifactPath === undefined) { + throw new HardhatPluginError( + "hardhat-ignition", + `Artifact path not found for ${contractName}` + ); + } + + const debugPath = artifactPath.replace(".json", ".dbg.json"); + const debugJson = await fs.promises.readFile(debugPath); + + const buildInfoPath = path.join( + path.parse(debugPath).dir, + JSON.parse(debugJson.toString()).buildInfo + ); + + const buildInfoJson = await fs.promises.readFile(buildInfoPath); + + return JSON.parse(buildInfoJson.toString()); + } + + private async _resolvePath( + contractName: string + ): Promise { + const artifactPaths = await this._hre.artifacts.getArtifactPaths(); + + const artifactPath = artifactPaths.find( + (p) => path.parse(p).name === contractName + ); + + return artifactPath; + } + + public loadArtifact(contractName: string): Promise { + return this._hre.artifacts.readArtifact(contractName); + } + + /** + * Returns true if a name is fully qualified, and not just a bare contract name. + * + * This is based on Hardhat's own test for fully qualified names, taken + * from `contract-names.ts` in `hardhat-core` utils. + */ + private _isFullyQualifiedName(contractName: string): boolean { + return contractName.includes(":"); + } +} diff --git a/packages/hardhat-ignition/src/helpers.ts b/packages/hardhat-ignition/src/helpers.ts new file mode 100644 index 0000000000..aa85a0adc8 --- /dev/null +++ b/packages/hardhat-ignition/src/helpers.ts @@ -0,0 +1,5 @@ +export { HardhatArtifactResolver } from "./hardhat-artifact-resolver"; +export { errorDeploymentResultToExceptionMessage } from "./utils/error-deployment-result-to-exception-message"; +export { resolveDeploymentId } from "./utils/resolve-deployment-id"; +export { PrettyEventHandler } from "./ui/pretty-event-handler"; +export { readDeploymentParameters } from "./utils/read-deployment-parameters"; diff --git a/packages/hardhat-ignition/src/index.ts b/packages/hardhat-ignition/src/index.ts new file mode 100644 index 0000000000..912f49f0e2 --- /dev/null +++ b/packages/hardhat-ignition/src/index.ts @@ -0,0 +1,815 @@ +import "@nomicfoundation/hardhat-verify"; +import { Etherscan } from "@nomicfoundation/hardhat-verify/etherscan"; +import { + DeploymentParameters, + IgnitionError, + ListTransactionsResult, + StatusResult, +} from "@nomicfoundation/ignition-core"; +import debug from "debug"; +import { ensureDir, pathExists, readdirSync, rm, writeJSON } from "fs-extra"; +import { extendConfig, extendEnvironment, scope } from "hardhat/config"; +import { NomicLabsHardhatPluginError } from "hardhat/plugins"; +import { parse as json5Parse } from "json5"; +import path from "path"; + +import "./type-extensions"; +import { calculateDeploymentStatusDisplay } from "./ui/helpers/calculate-deployment-status-display"; +import { bigintReviver } from "./utils/bigintReviver"; +import { getApiKeyAndUrls } from "./utils/getApiKeyAndUrls"; +import { readDeploymentParameters } from "./utils/read-deployment-parameters"; +import { resolveDeploymentId } from "./utils/resolve-deployment-id"; +import { shouldBeHardhatPluginError } from "./utils/shouldBeHardhatPluginError"; +import { verifyEtherscanContract } from "./utils/verifyEtherscanContract"; + +/* ignition config defaults */ +const IGNITION_DIR = "ignition"; + +const ignitionScope = scope( + "ignition", + "Deploy your smart contracts using Hardhat Ignition" +); + +const log = debug("hardhat:ignition"); + +extendConfig((config, userConfig) => { + /* setup path configs */ + const userPathsConfig = userConfig.paths ?? {}; + + config.paths = { + ...config.paths, + ignition: path.resolve( + config.paths.root, + userPathsConfig.ignition ?? IGNITION_DIR + ), + }; + + Object.keys(config.networks).forEach((networkName) => { + const userNetworkConfig = userConfig.networks?.[networkName] ?? {}; + + config.networks[networkName].ignition = { + maxFeePerGasLimit: userNetworkConfig.ignition?.maxFeePerGasLimit, + maxPriorityFeePerGas: userNetworkConfig.ignition?.maxPriorityFeePerGas, + gasPrice: userNetworkConfig.ignition?.gasPrice, + disableFeeBumping: userNetworkConfig.ignition?.disableFeeBumping, + explorerUrl: userNetworkConfig.ignition?.explorerUrl, + }; + }); + + /* setup core configs */ + const userIgnitionConfig = userConfig.ignition ?? {}; + + config.ignition = userIgnitionConfig; +}); + +/** + * Add an `ignition` stub to throw + */ +extendEnvironment((hre) => { + if ((hre as any).ignition === undefined) { + (hre as any).ignition = { + type: "stub", + deploy: () => { + throw new NomicLabsHardhatPluginError( + "hardhat-ignition", + "Please install either `@nomicfoundation/hardhat-ignition-viem` or `@nomicfoundation/hardhat-ignition-ethers` to use Ignition in your Hardhat tests" + ); + }, + }; + } +}); + +ignitionScope + .task("deploy") + .addPositionalParam("modulePath", "The path to the module file to deploy") + .addOptionalParam( + "parameters", + "A relative path to a JSON file to use for the module parameters" + ) + .addOptionalParam("deploymentId", "Set the id of the deployment") + .addOptionalParam( + "defaultSender", + "Set the default sender for the deployment" + ) + .addOptionalParam("strategy", "Set the deployment strategy to use", "basic") + .addFlag("reset", "Wipes the existing deployment state before deploying") + .addFlag("verify", "Verify the deployment on Etherscan") + .addFlag( + "writeLocalhostDeployment", + "Write deployment information to disk when deploying to the in-memory network" + ) + .setDescription("Deploy a module to the specified network") + .setAction( + async ( + { + modulePath, + parameters: parametersInput, + deploymentId: givenDeploymentId, + defaultSender, + reset, + verify, + strategy: strategyName, + writeLocalhostDeployment, + }: { + modulePath: string; + parameters?: string; + deploymentId: string | undefined; + defaultSender: string | undefined; + reset: boolean; + verify: boolean; + strategy: string; + writeLocalhostDeployment: boolean; + }, + hre + ) => { + const { default: chalk } = await import("chalk"); + const { default: Prompt } = await import("prompts"); + const { deploy } = await import("@nomicfoundation/ignition-core"); + + const { HardhatArtifactResolver } = await import( + "./hardhat-artifact-resolver" + ); + const { loadModule } = await import("./utils/load-module"); + const { PrettyEventHandler } = await import("./ui/pretty-event-handler"); + + if (verify) { + if ( + hre.config.etherscan === undefined || + hre.config.etherscan.apiKey === undefined || + hre.config.etherscan.apiKey === "" + ) { + throw new NomicLabsHardhatPluginError( + "@nomicfoundation/hardhat-ignition", + "No etherscan API key configured" + ); + } + } + + const chainId = Number( + await hre.network.provider.request({ + method: "eth_chainId", + }) + ); + + const deploymentId = resolveDeploymentId(givenDeploymentId, chainId); + + const deploymentDir = + hre.network.name === "hardhat" && !writeLocalhostDeployment + ? undefined + : path.join(hre.config.paths.ignition, "deployments", deploymentId); + if (chainId !== 31337) { + if (process.env.HARDHAT_IGNITION_CONFIRM_DEPLOYMENT === undefined) { + const prompt = await Prompt({ + type: "confirm", + name: "networkConfirmation", + message: `Confirm deploy to network ${hre.network.name} (${chainId})?`, + initial: false, + }); + + if (prompt.networkConfirmation !== true) { + console.log("Deploy cancelled"); + return; + } + } + + if (reset && process.env.HARDHAT_IGNITION_CONFIRM_RESET === undefined) { + const resetPrompt = await Prompt({ + type: "confirm", + name: "resetConfirmation", + message: `Confirm reset of deployment "${deploymentId}" on chain ${chainId}?`, + initial: false, + }); + + if (resetPrompt.resetConfirmation !== true) { + console.log("Deploy cancelled"); + return; + } + } + } else if (deploymentDir !== undefined) { + // since we're on hardhat-network + // check for a previous run of this deploymentId and compare instanceIds + // if they're different, wipe deployment state + const instanceFilePath = path.join( + hre.config.paths.cache, + ".hardhat-network-instances.json" + ); + const instanceFileExists = await pathExists(instanceFilePath); + + const instanceFile: { + [deploymentId: string]: string; + } = instanceFileExists ? require(instanceFilePath) : {}; + + const metadata = (await hre.network.provider.request({ + method: "hardhat_metadata", + })) as { instanceId: string }; + + if (instanceFile[deploymentId] !== metadata.instanceId) { + await rm(deploymentDir, { recursive: true, force: true }); + } + + // save current instanceId to instanceFile for future runs + instanceFile[deploymentId] = metadata.instanceId; + await ensureDir(path.dirname(instanceFilePath)); + await writeJSON(instanceFilePath, instanceFile, { spaces: 2 }); + } + + if (reset) { + if (deploymentDir === undefined) { + throw new NomicLabsHardhatPluginError( + "@nomicfoundation/hardhat-ignition", + "Deploy cancelled: Cannot reset deployment on ephemeral Hardhat network" + ); + } else { + await rm(deploymentDir, { recursive: true, force: true }); + } + } + + if (strategyName !== "basic" && strategyName !== "create2") { + throw new NomicLabsHardhatPluginError( + "hardhat-ignition", + "Invalid strategy name, must be either 'basic' or 'create2'" + ); + } + + await hre.run("compile", { quiet: true }); + + const userModule = loadModule(hre.config.paths.ignition, modulePath); + + if (userModule === undefined) { + throw new NomicLabsHardhatPluginError( + "@nomicfoundation/hardhat-ignition", + "No Ignition modules found" + ); + } + + let parameters: DeploymentParameters | undefined; + if (parametersInput === undefined) { + parameters = await resolveParametersFromModuleName( + userModule.id, + hre.config.paths.ignition + ); + } else if ( + parametersInput.endsWith(".json") || + parametersInput.endsWith(".json5") + ) { + parameters = await resolveParametersFromFileName(parametersInput); + } else { + parameters = resolveParametersString(parametersInput); + } + + const accounts = (await hre.network.provider.request({ + method: "eth_accounts", + })) as string[]; + + const artifactResolver = new HardhatArtifactResolver(hre); + + const executionEventListener = new PrettyEventHandler(); + + const strategyConfig = hre.config.ignition.strategyConfig?.[strategyName]; + + try { + const ledgerConnectionStart = () => + executionEventListener.ledgerConnectionStart(); + const ledgerConnectionSuccess = () => + executionEventListener.ledgerConnectionSuccess(); + const ledgerConnectionFailure = () => + executionEventListener.ledgerConnectionFailure(); + const ledgerConfirmationStart = () => + executionEventListener.ledgerConfirmationStart(); + const ledgerConfirmationSuccess = () => + executionEventListener.ledgerConfirmationSuccess(); + const ledgerConfirmationFailure = () => + executionEventListener.ledgerConfirmationFailure(); + + try { + await hre.network.provider.send("hardhat_setLedgerOutputEnabled", [ + false, + ]); + + hre.network.provider.once("connection_start", ledgerConnectionStart); + hre.network.provider.once( + "connection_success", + ledgerConnectionSuccess + ); + hre.network.provider.once( + "connection_failure", + ledgerConnectionFailure + ); + hre.network.provider.on( + "confirmation_start", + ledgerConfirmationStart + ); + hre.network.provider.on( + "confirmation_success", + ledgerConfirmationSuccess + ); + hre.network.provider.on( + "confirmation_failure", + ledgerConfirmationFailure + ); + } catch (error) { + log(error); + } + + const result = await deploy({ + config: hre.config.ignition, + provider: hre.network.provider, + executionEventListener, + artifactResolver, + deploymentDir, + ignitionModule: userModule, + deploymentParameters: parameters ?? {}, + accounts, + defaultSender, + strategy: strategyName, + strategyConfig, + maxFeePerGasLimit: + hre.config.networks[hre.network.name]?.ignition.maxFeePerGasLimit, + maxPriorityFeePerGas: + hre.config.networks[hre.network.name]?.ignition + .maxPriorityFeePerGas, + gasPrice: hre.config.networks[hre.network.name]?.ignition.gasPrice, + disableFeeBumping: + hre.config.ignition.disableFeeBumping ?? + hre.config.networks[hre.network.name]?.ignition.disableFeeBumping, + }); + + try { + await hre.network.provider.send("hardhat_setLedgerOutputEnabled", [ + true, + ]); + + hre.network.provider.off("connection_start", ledgerConnectionStart); + hre.network.provider.off( + "connection_success", + ledgerConnectionSuccess + ); + hre.network.provider.off( + "connection_failure", + ledgerConnectionFailure + ); + hre.network.provider.off( + "confirmation_start", + ledgerConfirmationStart + ); + hre.network.provider.off( + "confirmation_success", + ledgerConfirmationSuccess + ); + hre.network.provider.off( + "confirmation_failure", + ledgerConfirmationFailure + ); + } catch (error) { + log(error); + } + + if (result.type === "SUCCESSFUL_DEPLOYMENT" && verify) { + console.log(""); + console.log(chalk.bold("Verifying deployed contracts")); + console.log(""); + + await hre.run( + { scope: "ignition", task: "verify" }, + { deploymentId } + ); + } + + if (result.type !== "SUCCESSFUL_DEPLOYMENT") { + process.exitCode = 1; + } + } catch (e) { + if (e instanceof IgnitionError && shouldBeHardhatPluginError(e)) { + throw new NomicLabsHardhatPluginError( + "hardhat-ignition", + e.message, + e + ); + } + + throw e; + } + } + ); + +ignitionScope + .task("track-tx") + .addPositionalParam("txHash", "The hash of the transaction to track") + .addPositionalParam( + "deploymentId", + "The id of the deployment to add the tx to" + ) + .setDescription( + "Track a transaction that is missing from a given deployment. Only use if a Hardhat Ignition error message suggests to do so." + ) + .setAction( + async ( + { txHash, deploymentId }: { txHash: string; deploymentId: string }, + hre + ) => { + const { trackTransaction } = await import( + "@nomicfoundation/ignition-core" + ); + + const deploymentDir = path.join( + hre.config.paths.ignition, + "deployments", + deploymentId + ); + + let output: string | void; + try { + output = await trackTransaction( + deploymentDir, + txHash, + hre.network.provider, + hre.config.ignition.requiredConfirmations + ); + } catch (e) { + if (e instanceof IgnitionError && shouldBeHardhatPluginError(e)) { + throw new NomicLabsHardhatPluginError( + "hardhat-ignition", + e.message, + e + ); + } + + throw e; + } + + console.log( + output ?? + `Thanks for providing the transaction hash, your deployment has been fixed. + +Now you can re-run Hardhat Ignition to continue with your deployment.` + ); + } + ); + +ignitionScope + .task("visualize") + .addFlag("noOpen", "Disables opening report in browser") + .addPositionalParam("modulePath", "The path to the module file to visualize") + .setDescription("Visualize a module as an HTML report") + .setAction( + async ( + { noOpen = false, modulePath }: { noOpen: boolean; modulePath: string }, + hre + ) => { + const { IgnitionModuleSerializer, batches } = await import( + "@nomicfoundation/ignition-core" + ); + + const { loadModule } = await import("./utils/load-module"); + const { open } = await import("./utils/open"); + + const { writeVisualization } = await import( + "./visualization/write-visualization" + ); + + await hre.run("compile", { quiet: true }); + + const userModule = loadModule(hre.config.paths.ignition, modulePath); + + if (userModule === undefined) { + throw new NomicLabsHardhatPluginError( + "@nomicfoundation/hardhat-ignition", + "No Ignition modules found" + ); + } else { + try { + const serializedIgnitionModule = + IgnitionModuleSerializer.serialize(userModule); + + const batchInfo = batches(userModule); + + await writeVisualization( + { module: serializedIgnitionModule, batches: batchInfo }, + { + cacheDir: hre.config.paths.cache, + } + ); + } catch (e) { + if (e instanceof IgnitionError && shouldBeHardhatPluginError(e)) { + throw new NomicLabsHardhatPluginError( + "hardhat-ignition", + e.message, + e + ); + } + + throw e; + } + } + + if (!noOpen) { + const indexFile = path.join( + hre.config.paths.cache, + "visualization", + "index.html" + ); + + console.log(`Deployment visualization written to ${indexFile}`); + + open(indexFile); + } + } + ); + +ignitionScope + .task("status") + .addPositionalParam("deploymentId", "The id of the deployment to show") + .setDescription("Show the current status of a deployment") + .setAction(async ({ deploymentId }: { deploymentId: string }, hre) => { + const { status } = await import("@nomicfoundation/ignition-core"); + + const { HardhatArtifactResolver } = await import( + "./hardhat-artifact-resolver" + ); + + const deploymentDir = path.join( + hre.config.paths.ignition, + "deployments", + deploymentId + ); + + const artifactResolver = new HardhatArtifactResolver(hre); + + let statusResult: StatusResult; + try { + statusResult = await status(deploymentDir, artifactResolver); + } catch (e) { + if (e instanceof IgnitionError && shouldBeHardhatPluginError(e)) { + throw new NomicLabsHardhatPluginError("hardhat-ignition", e.message, e); + } + + throw e; + } + + console.log(calculateDeploymentStatusDisplay(deploymentId, statusResult)); + }); + +ignitionScope + .task("deployments") + .setDescription("List all deployment IDs") + .setAction(async (_, hre) => { + const { listDeployments } = await import("@nomicfoundation/ignition-core"); + + const deploymentDir = path.join(hre.config.paths.ignition, "deployments"); + + try { + const deployments = await listDeployments(deploymentDir); + + for (const deploymentId of deployments) { + console.log(deploymentId); + } + } catch (e) { + if (e instanceof IgnitionError && shouldBeHardhatPluginError(e)) { + throw new NomicLabsHardhatPluginError("hardhat-ignition", e.message, e); + } + + throw e; + } + }); + +ignitionScope + .task("wipe") + .addPositionalParam( + "deploymentId", + "The id of the deployment with the future to wipe" + ) + .addPositionalParam("futureId", "The id of the future to wipe") + .setDescription("Reset a deployment's future to allow rerunning") + .setAction( + async ( + { deploymentId, futureId }: { deploymentId: string; futureId: string }, + hre + ) => { + const { wipe } = await import("@nomicfoundation/ignition-core"); + + const { HardhatArtifactResolver } = await import( + "./hardhat-artifact-resolver" + ); + + const deploymentDir = path.join( + hre.config.paths.ignition, + "deployments", + deploymentId + ); + + try { + await wipe(deploymentDir, new HardhatArtifactResolver(hre), futureId); + } catch (e) { + if (e instanceof IgnitionError && shouldBeHardhatPluginError(e)) { + throw new NomicLabsHardhatPluginError( + "hardhat-ignition", + e.message, + e + ); + } + + throw e; + } + + console.log(`${futureId} state has been cleared`); + } + ); + +ignitionScope + .task("verify") + .addFlag( + "includeUnrelatedContracts", + "Include all compiled contracts in the verification" + ) + .addPositionalParam("deploymentId", "The id of the deployment to verify") + .setDescription( + "Verify contracts from a deployment against the configured block explorers" + ) + .setAction( + async ( + { + deploymentId, + includeUnrelatedContracts = false, + }: { deploymentId: string; includeUnrelatedContracts: boolean }, + hre + ) => { + const { getVerificationInformation } = await import( + "@nomicfoundation/ignition-core" + ); + + const deploymentDir = path.join( + hre.config.paths.ignition, + "deployments", + deploymentId + ); + + if ( + hre.config.etherscan === undefined || + hre.config.etherscan.apiKey === undefined || + hre.config.etherscan.apiKey === "" + ) { + throw new NomicLabsHardhatPluginError( + "@nomicfoundation/hardhat-ignition", + "No etherscan API key configured" + ); + } + + try { + for await (const [ + chainConfig, + contractInfo, + ] of getVerificationInformation( + deploymentDir, + hre.config.etherscan.customChains, + includeUnrelatedContracts + )) { + if (chainConfig === null) { + console.log( + `Could not resolve contract artifacts for contract "${contractInfo}". Skipping verification.` + ); + console.log(""); + continue; + } + + const apiKeyAndUrls = getApiKeyAndUrls( + hre.config.etherscan.apiKey, + chainConfig + ); + + const instance = new Etherscan(...apiKeyAndUrls); + + console.log( + `Verifying contract "${contractInfo.name}" for network ${chainConfig.network}...` + ); + + const result = await verifyEtherscanContract(instance, contractInfo); + + if (result.type === "success") { + console.log( + `Successfully verified contract "${contractInfo.name}" for network ${chainConfig.network}:\n - ${result.contractURL}` + ); + console.log(""); + } else { + if (/already verified/gi.test(result.reason.message)) { + const contractURL = instance.getContractUrl(contractInfo.address); + console.log( + `Contract ${contractInfo.name} already verified on network ${chainConfig.network}:\n - ${contractURL}` + ); + console.log(""); + continue; + } else { + if (!includeUnrelatedContracts) { + throw new NomicLabsHardhatPluginError( + "hardhat-ignition", + `Verification failed. Please run \`hardhat ignition verify ${deploymentId} --include-unrelated-contracts\` to attempt verifying all contracts.` + ); + } else { + throw new NomicLabsHardhatPluginError( + "hardhat-ignition", + result.reason.message + ); + } + } + } + } + } catch (e) { + if (e instanceof IgnitionError && shouldBeHardhatPluginError(e)) { + throw new NomicLabsHardhatPluginError( + "hardhat-ignition", + e.message, + e + ); + } + + throw e; + } + } + ); + +ignitionScope + .task("transactions") + .addPositionalParam( + "deploymentId", + "The id of the deployment to show transactions for" + ) + .setDescription("Show all transactions for a given deployment") + .setAction(async ({ deploymentId }: { deploymentId: string }, hre) => { + const { listTransactions } = await import("@nomicfoundation/ignition-core"); + + const { HardhatArtifactResolver } = await import( + "./hardhat-artifact-resolver" + ); + const { calculateListTransactionsDisplay } = await import( + "./ui/helpers/calculate-list-transactions-display" + ); + + const deploymentDir = path.join( + hre.config.paths.ignition, + "deployments", + deploymentId + ); + + const artifactResolver = new HardhatArtifactResolver(hre); + + let listTransactionsResult: ListTransactionsResult; + try { + listTransactionsResult = await listTransactions( + deploymentDir, + artifactResolver + ); + } catch (e) { + if (e instanceof IgnitionError && shouldBeHardhatPluginError(e)) { + throw new NomicLabsHardhatPluginError("hardhat-ignition", e.message, e); + } + + throw e; + } + + console.log( + calculateListTransactionsDisplay( + deploymentId, + listTransactionsResult, + hre.config.networks[hre.network.name]?.ignition?.explorerUrl + ) + ); + }); + +async function resolveParametersFromModuleName( + moduleName: string, + ignitionPath: string +): Promise { + const files = readdirSync(ignitionPath); + const configFilename = `${moduleName}.config.json`; + + return files.includes(configFilename) + ? readDeploymentParameters(path.resolve(ignitionPath, configFilename)) + : undefined; +} + +async function resolveParametersFromFileName( + fileName: string +): Promise { + const filepath = path.resolve(process.cwd(), fileName); + + return readDeploymentParameters(filepath); +} + +function resolveParametersString(paramString: string): DeploymentParameters { + try { + return json5Parse(paramString, bigintReviver); + } catch (e) { + if (e instanceof NomicLabsHardhatPluginError) { + throw e; + } + + if (e instanceof Error) { + throw new NomicLabsHardhatPluginError( + "@nomicfoundation/hardhat-ignition", + "Could not parse JSON parameters", + e + ); + } + + throw e; + } +} diff --git a/packages/hardhat-ignition/src/modules.ts b/packages/hardhat-ignition/src/modules.ts new file mode 100644 index 0000000000..840e207281 --- /dev/null +++ b/packages/hardhat-ignition/src/modules.ts @@ -0,0 +1 @@ +export { buildModule } from "@nomicfoundation/ignition-core"; diff --git a/packages/hardhat-ignition/src/type-extensions.ts b/packages/hardhat-ignition/src/type-extensions.ts new file mode 100644 index 0000000000..3a0c6cda8e --- /dev/null +++ b/packages/hardhat-ignition/src/type-extensions.ts @@ -0,0 +1,67 @@ +/* eslint-disable import/no-unused-modules */ +import "hardhat/types/config"; +import "hardhat/types/runtime"; + +import { DeployConfig, StrategyConfig } from "@nomicfoundation/ignition-core"; + +declare module "hardhat/types/config" { + export interface ProjectPathsUserConfig { + ignition?: string; + } + + export interface ProjectPathsConfig { + ignition: string; + } + + export interface HardhatNetworkUserConfig { + ignition?: { + maxFeePerGasLimit?: bigint; + maxPriorityFeePerGas?: bigint; + gasPrice?: bigint; + disableFeeBumping?: boolean; + explorerUrl?: string; + }; + } + + export interface HardhatNetworkConfig { + ignition: { + maxFeePerGasLimit?: bigint; + maxPriorityFeePerGas?: bigint; + gasPrice?: bigint; + disableFeeBumping?: boolean; + explorerUrl?: string; + }; + } + + export interface HttpNetworkUserConfig { + ignition?: { + maxFeePerGasLimit?: bigint; + maxPriorityFeePerGas?: bigint; + gasPrice?: bigint; + disableFeeBumping?: boolean; + explorerUrl?: string; + }; + } + + export interface HttpNetworkConfig { + ignition: { + maxFeePerGasLimit?: bigint; + maxPriorityFeePerGas?: bigint; + gasPrice?: bigint; + disableFeeBumping?: boolean; + explorerUrl?: string; + }; + } + + export interface HardhatUserConfig { + ignition?: Partial & { + strategyConfig?: Partial; + }; + } + + export interface HardhatConfig { + ignition: Partial & { + strategyConfig?: Partial; + }; + } +} diff --git a/packages/hardhat-ignition/src/ui/helpers/calculate-batch-display.ts b/packages/hardhat-ignition/src/ui/helpers/calculate-batch-display.ts new file mode 100644 index 0000000000..f5fcb2d4c8 --- /dev/null +++ b/packages/hardhat-ignition/src/ui/helpers/calculate-batch-display.ts @@ -0,0 +1,53 @@ +import { UiFuture, UiFutureStatusType, UiState } from "../types"; + +export function calculateBatchDisplay(state: UiState): { + text: string; + height: number; +} { + const batch = state.batches[state.currentBatch - 1]; + const height = batch.length + (state.ledgerMessageIsDisplayed ? 4 : 2); + + let text = `Batch #${state.currentBatch}\n`; + + text += batch + .sort((a, b) => a.futureId.localeCompare(b.futureId)) + .map((v) => _futureStatus(v, state.gasBumps, state.maxFeeBumps)) + .join("\n"); + + text += "\n"; + + if (state.ledger) { + text += `\n Ledger: ${state.ledgerMessage}\n`; + } + + return { text, height }; +} + +function _futureStatus( + future: UiFuture, + gasBumps: Record, + maxFeeBumps: number +): string { + switch (future.status.type) { + case UiFutureStatusType.UNSTARTED: { + const gas = gasBumps[future.futureId]; + return ` Executing ${future.futureId}${ + gas !== undefined + ? ` - bumping gas fee (${gas}/${maxFeeBumps})...` + : "..." + }`; + } + case UiFutureStatusType.SUCCESS: { + return ` Executed ${future.futureId}`; + } + case UiFutureStatusType.TIMEDOUT: { + return ` Timed out ${future.futureId}`; + } + case UiFutureStatusType.ERRORED: { + return ` Failed ${future.futureId}`; + } + case UiFutureStatusType.HELD: { + return ` Held ${future.futureId}`; + } + } +} diff --git a/packages/hardhat-ignition/src/ui/helpers/calculate-deploying-module-panel.ts b/packages/hardhat-ignition/src/ui/helpers/calculate-deploying-module-panel.ts new file mode 100644 index 0000000000..638b1b8b99 --- /dev/null +++ b/packages/hardhat-ignition/src/ui/helpers/calculate-deploying-module-panel.ts @@ -0,0 +1,48 @@ +import chalk from "chalk"; + +import { UiState } from "../types"; + +import { pathFromCwd } from "./cwd-relative-path"; + +export function calculateDeployingModulePanel(state: UiState): string { + let deployingMessage = `Hardhat Ignition 🚀 + +`; + + if (state.isResumed === true) { + deployingMessage += `${chalk.bold( + `Resuming existing deployment from ${pathFromCwd(state.deploymentDir!)}` + )} + +`; + } + + deployingMessage += `${chalk.bold( + `Deploying [ ${state.moduleName ?? "unknown"} ]${_calculateStrategySuffix( + state + )}` + )} +`; + + if (state.warnings.length > 0) { + deployingMessage += `\n${chalk.yellow( + "Warning - previously executed futures are not in the module:" + )}\n`; + + deployingMessage += state.warnings + .map((futureId) => chalk.yellow(` - ${futureId}`)) + .join("\n"); + + deployingMessage += "\n"; + } + + return deployingMessage; +} + +function _calculateStrategySuffix(state: UiState) { + if (state.strategy === "basic") { + return ""; + } + + return ` with strategy ${state.strategy ?? "unknown"}`; +} diff --git a/packages/hardhat-ignition/src/ui/helpers/calculate-deployment-complete-display.ts b/packages/hardhat-ignition/src/ui/helpers/calculate-deployment-complete-display.ts new file mode 100644 index 0000000000..dfb457d6ac --- /dev/null +++ b/packages/hardhat-ignition/src/ui/helpers/calculate-deployment-complete-display.ts @@ -0,0 +1,201 @@ +import { + DeploymentCompleteEvent, + DeploymentResultType, + ExecutionErrorDeploymentResult, + PreviousRunErrorDeploymentResult, + ReconciliationErrorDeploymentResult, + SuccessfulDeploymentResult, + ValidationErrorDeploymentResult, +} from "@nomicfoundation/ignition-core"; +import chalk from "chalk"; + +import { UiState } from "../types"; + +import { pathFromCwd } from "./cwd-relative-path"; +import { wasAnythingExecuted } from "./was-anything-executed"; + +export function calculateDeploymentCompleteDisplay( + event: DeploymentCompleteEvent, + uiState: Pick< + UiState, + "moduleName" | "isResumed" | "batches" | "deploymentDir" + > +): string { + const moduleName = uiState.moduleName ?? "unknown"; + const isResumed = uiState.isResumed ?? false; + + switch (event.result.type) { + case DeploymentResultType.SUCCESSFUL_DEPLOYMENT: { + const isRerunWithNoChanges: boolean = + isResumed && !wasAnythingExecuted(uiState); + + return _displaySuccessfulDeployment(event.result, { + moduleName, + isRerunWithNoChanges, + deploymentDir: uiState.deploymentDir, + }); + } + case DeploymentResultType.VALIDATION_ERROR: { + return _displayValidationErrors(event.result, { moduleName }); + } + case DeploymentResultType.RECONCILIATION_ERROR: { + return _displayReconciliationErrors(event.result, { moduleName }); + } + case DeploymentResultType.PREVIOUS_RUN_ERROR: { + return _displayPreviousRunErrors(event.result, { moduleName }); + } + case DeploymentResultType.EXECUTION_ERROR: { + return _displayExecutionErrors(event.result, { moduleName }); + } + } +} + +function _displaySuccessfulDeployment( + result: SuccessfulDeploymentResult, + { + moduleName, + isRerunWithNoChanges, + deploymentDir, + }: { + moduleName: string; + isRerunWithNoChanges: boolean; + deploymentDir: string | null | undefined; + } +): string { + const fillerText = isRerunWithNoChanges + ? `Nothing new to deploy based on previous execution stored in ${pathFromCwd( + deploymentDir ?? "Not provided" + )}` + : `successfully deployed 🚀`; + + let text = `[ ${moduleName} ] ${fillerText} + +${chalk.bold("Deployed Addresses")} + +`; + + const deployedContracts = Object.values(result.contracts); + + if (deployedContracts.length > 0) { + text += deployedContracts + .map((contract) => `${contract.id} - ${contract.address}`) + .join("\n"); + } else { + text += `${chalk.italic("No contracts were deployed")}`; + } + + return text; +} + +function _displayValidationErrors( + result: ValidationErrorDeploymentResult, + { moduleName }: { moduleName: string } +): string { + let text = `[ ${moduleName} ] validation failed ⛔ + +The module contains futures that would fail to execute: + +`; + + text += Object.entries(result.errors) + .map(([futureId, errors]) => { + let futureSection = `${futureId}:\n`; + + futureSection += errors.map((error) => ` - ${error}`).join("\n"); + + return futureSection; + }) + .join("\n\n"); + + text += `\n\nUpdate the invalid futures and rerun the deployment.`; + + return text; +} + +function _displayReconciliationErrors( + result: ReconciliationErrorDeploymentResult, + { moduleName }: { moduleName: string } +): string { + let text = `[ ${moduleName} ] reconciliation failed ⛔ + +The module contains changes to executed futures: + +`; + + text += Object.entries(result.errors) + .map(([futureId, errors]) => { + let errorSection = `${futureId}:\n`; + + errorSection += errors.map((error) => ` - ${error}`).join("\n"); + + return errorSection; + }) + .join("\n\n"); + + text += `\n\nConsider modifying your module to remove the inconsistencies with deployed futures.`; + + return text; +} + +function _displayPreviousRunErrors( + result: PreviousRunErrorDeploymentResult, + { moduleName }: { moduleName: string } +): string { + let text = `[ ${moduleName} ] deployment cancelled ⛔\n\n`; + + text += `These futures failed or timed out on a previous run:\n`; + + text += Object.keys(result.errors) + .map((futureId) => ` - ${futureId}`) + .join("\n"); + + text += `\n\nUse the ${chalk.italic("wipe")} task to reset them.`; + + return text; +} + +function _displayExecutionErrors( + result: ExecutionErrorDeploymentResult, + { moduleName }: { moduleName: string } +) { + const sections: string[] = []; + + let text = `[ ${moduleName} ] failed ⛔\n\n`; + + if (result.timedOut.length > 0) { + let timedOutSection = `Futures timed out with transactions unconfirmed after maximum fee bumps:\n`; + + timedOutSection += Object.values(result.timedOut) + .map(({ futureId }) => ` - ${futureId}`) + .join("\n"); + + sections.push(timedOutSection); + } + + if (result.failed.length > 0) { + let failedSection = `Futures failed during execution:\n`; + + failedSection += Object.values(result.failed) + .map(({ futureId, error }) => ` - ${futureId}: ${error}`) + .join("\n"); + + failedSection += + "\n\nTo learn how to handle these errors: https://hardhat.org/ignition-errors"; + + sections.push(failedSection); + } + + if (result.held.length > 0) { + let heldSection = `Held:\n`; + + heldSection += Object.values(result.held) + .map(({ futureId, reason }) => ` - ${futureId}: ${reason}`) + .join("\n"); + + sections.push(heldSection); + } + + text += sections.join("\n\n"); + + return text; +} diff --git a/packages/hardhat-ignition/src/ui/helpers/calculate-deployment-status-display.ts b/packages/hardhat-ignition/src/ui/helpers/calculate-deployment-status-display.ts new file mode 100644 index 0000000000..49c461e174 --- /dev/null +++ b/packages/hardhat-ignition/src/ui/helpers/calculate-deployment-status-display.ts @@ -0,0 +1,95 @@ +import { StatusResult } from "@nomicfoundation/ignition-core"; +import chalk from "chalk"; + +export function calculateDeploymentStatusDisplay( + deploymentId: string, + statusResult: StatusResult +): string { + if (statusResult.started.length > 0) { + return _calculateStartedButUnfinished(deploymentId, statusResult); + } + + if ( + statusResult.timedOut.length > 0 || + statusResult.failed.length > 0 || + statusResult.held.length > 0 + ) { + return _calculateFailed(deploymentId, statusResult); + } + + return _calculateSuccess(deploymentId, statusResult); +} + +function _calculateSuccess(deploymentId: string, statusResult: StatusResult) { + let successText = `Deployment ${deploymentId} (chainId: ${statusResult.chainId}) was successful\n\n`; + + if (Object.values(statusResult.contracts).length === 0) { + successText += chalk.italic("No contracts were deployed"); + } else { + successText += `${chalk.bold("Deployed Addresses")}\n\n`; + + successText += Object.values(statusResult.contracts) + .map((contract) => `${contract.id} - ${contract.address}`) + .join("\n"); + } + + return successText; +} + +function _calculateStartedButUnfinished( + deploymentId: string, + statusResult: StatusResult +) { + let startedText = `Deployment ${deploymentId} (chainId: ${statusResult.chainId}) has futures that have started but not completed\n\n`; + + startedText += Object.values(statusResult.started) + .map((futureId) => ` - ${futureId}`) + .join("\n"); + + startedText += "\n\nPlease rerun your deployment."; + + return startedText; +} + +function _calculateFailed(deploymentId: string, statusResult: StatusResult) { + let failedExecutionText = `Deployment ${deploymentId} (chainId: ${statusResult.chainId}) failed\n`; + + const sections: string[] = []; + + if (statusResult.timedOut.length > 0) { + let timedOutSection = `\nFutures timed out with transactions unconfirmed after maximum fee bumps:\n`; + + timedOutSection += Object.values(statusResult.timedOut) + .map(({ futureId }) => ` - ${futureId}`) + .join("\n"); + + sections.push(timedOutSection); + } + + if (statusResult.failed.length > 0) { + let failedSection = `\nFutures failed during execution:\n`; + + failedSection += Object.values(statusResult.failed) + .map(({ futureId, error }) => ` - ${futureId}: ${error}`) + .join("\n"); + + failedSection += + "\n\nTo learn how to handle these errors: https://hardhat.org/ignition-errors"; + + sections.push(failedSection); + } + + if (statusResult.held.length > 0) { + let heldSection = `\nFutures where held by the strategy:\n`; + + heldSection += Object.values(statusResult.held) + .map(({ futureId, reason }) => ` - ${futureId}: ${reason}`) + .join("\n"); + + sections.push(heldSection); + } + + failedExecutionText += sections.join("\n"); + + return failedExecutionText; +} diff --git a/packages/hardhat-ignition/src/ui/helpers/calculate-list-transactions-display.ts b/packages/hardhat-ignition/src/ui/helpers/calculate-list-transactions-display.ts new file mode 100644 index 0000000000..4bb9c839d2 --- /dev/null +++ b/packages/hardhat-ignition/src/ui/helpers/calculate-list-transactions-display.ts @@ -0,0 +1,89 @@ +import { ListTransactionsResult } from "@nomicfoundation/ignition-core"; +import { NomicLabsHardhatPluginError } from "hardhat/plugins"; +import { stringify } from "json5"; + +export function calculateListTransactionsDisplay( + deploymentId: string, + listTransactionsResult: ListTransactionsResult, + configUrl?: string +): string { + let text = `Logging transactions for deployment ${deploymentId}\n\n`; + + for (const [index, transaction] of listTransactionsResult.entries()) { + const txLink = getTransactionLink( + transaction.txHash, + configUrl ?? transaction.browserUrl + ); + + text += `Transaction ${index + 1}${txLink === undefined ? "" : txLink}:\n`; + text += ` - Type: ${transactionTypeToDisplayType(transaction.type)}\n`; + text += ` - Status: ${transaction.status}\n`; + text += ` - TxHash: ${transaction.txHash}\n`; + text += ` - From: ${transaction.from}\n`; + + if (transaction.to !== undefined) { + text += ` - To: ${transaction.to}\n`; + } + + if (transaction.name !== undefined) { + text += ` - Name: ${transaction.name}\n`; + } + + if (transaction.address !== undefined) { + text += ` - Address: ${transaction.address}\n`; + } + + if (transaction.params !== undefined) { + text += ` - Params: ${stringify( + transaction.params, + transactionDisplaySerializeReplacer + )}\n`; + } + + if (transaction.value !== undefined) { + text += ` - Value: '${transaction.value}n'\n`; + } + + text += "\n"; + } + + return text; +} + +function transactionTypeToDisplayType(type: string): string { + switch (type) { + case "DEPLOYMENT_EXECUTION_STATE": + return "Contract Deployment"; + case "CALL_EXECUTION_STATE": + return "Function Call"; + case "SEND_DATA_EXECUTION_STATE": + return "Generic Transaction"; + default: + throw new NomicLabsHardhatPluginError( + "hardhat-ignition", + `Unknown transaction type: ${type}` + ); + } +} + +export function transactionDisplaySerializeReplacer( + _key: string, + value: unknown +) { + if (typeof value === "bigint") { + return `${value}n`; + } + + return value; +} + +function getTransactionLink( + txHash: string, + browserURL?: string +): string | undefined { + if (browserURL === undefined) { + return undefined; + } + + return `\x1b]8;;${browserURL}/tx/${txHash}\x1b\\ (🔗 view on block explorer)\x1b]8;;\x1b\\`; +} diff --git a/packages/hardhat-ignition/src/ui/helpers/calculate-starting-message.ts b/packages/hardhat-ignition/src/ui/helpers/calculate-starting-message.ts new file mode 100644 index 0000000000..a199fe6f56 --- /dev/null +++ b/packages/hardhat-ignition/src/ui/helpers/calculate-starting-message.ts @@ -0,0 +1,30 @@ +import chalk from "chalk"; + +/** + * Display the temporary starting message. Note this does not print a newline. + * + * @param state - the UI state + */ +export function calculateStartingMessage({ + moduleName, + deploymentDir, +}: { + moduleName: string | null; + deploymentDir: string | undefined | null; +}): string { + const warningMessage = chalk.yellow( + chalk.bold( + `You are running Hardhat Ignition against an in-process instance of Hardhat Network. +This will execute the deployment, but the results will be lost. +You can use --network to deploy to a different network.` + ) + ); + + const startingMessage = `Hardhat Ignition starting for [ ${ + moduleName ?? "unknown" + } ]...`; + + return deploymentDir === undefined + ? `${warningMessage}\n\n${startingMessage}` + : startingMessage; +} diff --git a/packages/hardhat-ignition/src/ui/helpers/cwd-relative-path.ts b/packages/hardhat-ignition/src/ui/helpers/cwd-relative-path.ts new file mode 100644 index 0000000000..ed6eeee013 --- /dev/null +++ b/packages/hardhat-ignition/src/ui/helpers/cwd-relative-path.ts @@ -0,0 +1,12 @@ +import path from "path"; +import process from "process"; + +export function pathFromCwd(thePath: string): string { + const cwd = process.cwd(); + + if (thePath.startsWith(cwd)) { + return `.${path.sep}${path.relative(process.cwd(), thePath)}`; + } + + return thePath; +} diff --git a/packages/hardhat-ignition/src/ui/helpers/was-anything-executed.ts b/packages/hardhat-ignition/src/ui/helpers/was-anything-executed.ts new file mode 100644 index 0000000000..f81919113d --- /dev/null +++ b/packages/hardhat-ignition/src/ui/helpers/was-anything-executed.ts @@ -0,0 +1,11 @@ +import { UiState } from "../types"; + +/** + * Was anything executed during the deployment. We determine this based + * on whether the batcher indicates that there was at least one batch. + */ +export function wasAnythingExecuted({ + batches, +}: Pick): boolean { + return batches.length > 0; +} diff --git a/packages/hardhat-ignition/src/ui/pretty-event-handler.ts b/packages/hardhat-ignition/src/ui/pretty-event-handler.ts new file mode 100644 index 0000000000..a5d7070fe4 --- /dev/null +++ b/packages/hardhat-ignition/src/ui/pretty-event-handler.ts @@ -0,0 +1,568 @@ +import { + BatchInitializeEvent, + BeginNextBatchEvent, + CallExecutionStateCompleteEvent, + CallExecutionStateInitializeEvent, + ContractAtExecutionStateInitializeEvent, + DeploymentCompleteEvent, + DeploymentExecutionStateCompleteEvent, + DeploymentExecutionStateInitializeEvent, + DeploymentInitializeEvent, + DeploymentParameters, + DeploymentResult, + DeploymentResultType, + DeploymentStartEvent, + EncodeFunctionCallExecutionStateInitializeEvent, + ExecutionEventListener, + ExecutionEventResult, + ExecutionEventResultType, + NetworkInteractionRequestEvent, + OnchainInteractionBumpFeesEvent, + OnchainInteractionDroppedEvent, + OnchainInteractionReplacedByUserEvent, + OnchainInteractionTimeoutEvent, + ReadEventArgExecutionStateInitializeEvent, + ReconciliationWarningsEvent, + RunStartEvent, + SendDataExecutionStateCompleteEvent, + SendDataExecutionStateInitializeEvent, + SetModuleIdEvent, + SetStrategyEvent, + StaticCallCompleteEvent, + StaticCallExecutionStateCompleteEvent, + StaticCallExecutionStateInitializeEvent, + TransactionConfirmEvent, + TransactionSendEvent, + WipeApplyEvent, +} from "@nomicfoundation/ignition-core"; +import readline from "readline"; + +import { calculateBatchDisplay } from "./helpers/calculate-batch-display"; +import { calculateDeployingModulePanel } from "./helpers/calculate-deploying-module-panel"; +import { calculateDeploymentCompleteDisplay } from "./helpers/calculate-deployment-complete-display"; +import { calculateStartingMessage } from "./helpers/calculate-starting-message"; +import { wasAnythingExecuted } from "./helpers/was-anything-executed"; +import { + UiBatches, + UiFuture, + UiFutureErrored, + UiFutureHeld, + UiFutureStatus, + UiFutureStatusType, + UiFutureSuccess, + UiState, + UiStateDeploymentStatus, +} from "./types"; + +export class PrettyEventHandler implements ExecutionEventListener { + private _uiState: UiState = { + status: UiStateDeploymentStatus.UNSTARTED, + chainId: null, + moduleName: null, + deploymentDir: null, + batches: [], + currentBatch: 0, + result: null, + warnings: [], + isResumed: null, + maxFeeBumps: 0, + disableFeeBumping: null, + gasBumps: {}, + strategy: null, + ledger: false, + ledgerMessage: "", + ledgerMessageIsDisplayed: false, + }; + + constructor( + private _deploymentParams: DeploymentParameters = {}, + private _disableOutput = false + ) {} + + public get state(): UiState { + return this._uiState; + } + + public set state(uiState: UiState) { + this._uiState = uiState; + } + + public deploymentStart(event: DeploymentStartEvent): void { + this.state = { + ...this.state, + status: UiStateDeploymentStatus.DEPLOYING, + moduleName: event.moduleName, + deploymentDir: event.deploymentDir, + isResumed: event.isResumed, + maxFeeBumps: event.maxFeeBumps, + disableFeeBumping: event.disableFeeBumping, + }; + + process.stdout.write(calculateStartingMessage(this.state)); + } + + public deploymentInitialize(event: DeploymentInitializeEvent): void { + this.state = { + ...this.state, + chainId: event.chainId, + }; + } + + public runStart(_event: RunStartEvent): void { + this._clearCurrentLine(); + console.log(calculateDeployingModulePanel(this.state)); + } + + public beginNextBatch(_event: BeginNextBatchEvent): void { + // rerender the previous batch + if (this.state.currentBatch > 0) { + this._redisplayCurrentBatch(); + } + + this.state = { + ...this.state, + currentBatch: this.state.currentBatch + 1, + }; + + if (this.state.currentBatch === 0) { + return; + } + + // render the new batch + console.log(calculateBatchDisplay(this.state).text); + } + + public wipeApply(event: WipeApplyEvent): void { + const batches: UiBatches = []; + + for (const batch of this.state.batches) { + const futureBatch: UiFuture[] = []; + + for (const future of batch) { + if (future.futureId === event.futureId) { + continue; + } else { + futureBatch.push(future); + } + } + + batches.push(futureBatch); + } + + this.state = { + ...this.state, + batches, + }; + } + + public deploymentExecutionStateInitialize( + event: DeploymentExecutionStateInitializeEvent + ): void { + this._setFutureStatusInitializedAndRedisplayBatch(event); + } + + public deploymentExecutionStateComplete( + event: DeploymentExecutionStateCompleteEvent + ): void { + this._setFutureStatusCompleteAndRedisplayBatch(event); + } + + public callExecutionStateInitialize( + event: CallExecutionStateInitializeEvent + ): void { + this._setFutureStatusInitializedAndRedisplayBatch(event); + } + + public callExecutionStateComplete( + event: CallExecutionStateCompleteEvent + ): void { + this._setFutureStatusCompleteAndRedisplayBatch(event); + } + + public staticCallExecutionStateInitialize( + event: StaticCallExecutionStateInitializeEvent + ): void { + this._setFutureStatusInitializedAndRedisplayBatch(event); + } + + public staticCallExecutionStateComplete( + event: StaticCallExecutionStateCompleteEvent + ): void { + this._setFutureStatusCompleteAndRedisplayBatch(event); + } + + public sendDataExecutionStateInitialize( + event: SendDataExecutionStateInitializeEvent + ): void { + this._setFutureStatusInitializedAndRedisplayBatch(event); + } + + public sendDataExecutionStateComplete( + event: SendDataExecutionStateCompleteEvent + ): void { + this._setFutureStatusCompleteAndRedisplayBatch(event); + } + + public contractAtExecutionStateInitialize( + event: ContractAtExecutionStateInitializeEvent + ): void { + this._setFutureStatusAndRedisplayBatch(event.futureId, { + type: UiFutureStatusType.SUCCESS, + }); + } + + public readEventArgumentExecutionStateInitialize( + event: ReadEventArgExecutionStateInitializeEvent + ): void { + this._setFutureStatusAndRedisplayBatch(event.futureId, { + type: UiFutureStatusType.SUCCESS, + }); + } + + public encodeFunctionCallExecutionStateInitialize( + event: EncodeFunctionCallExecutionStateInitializeEvent + ): void { + this._setFutureStatusAndRedisplayBatch(event.futureId, { + type: UiFutureStatusType.SUCCESS, + }); + } + + public batchInitialize(event: BatchInitializeEvent): void { + const batches: UiBatches = []; + + for (const batch of event.batches) { + const futureBatch: UiFuture[] = []; + + for (const futureId of batch) { + futureBatch.push({ + futureId, + status: { + type: UiFutureStatusType.UNSTARTED, + }, + }); + } + + batches.push(futureBatch); + } + + this.state = { + ...this.state, + batches, + }; + } + + public networkInteractionRequest( + _event: NetworkInteractionRequestEvent + ): void {} + + public transactionSend(_event: TransactionSendEvent): void {} + + public transactionConfirm(_event: TransactionConfirmEvent): void {} + + public staticCallComplete(_event: StaticCallCompleteEvent): void {} + + public onchainInteractionBumpFees( + event: OnchainInteractionBumpFeesEvent + ): void { + if (this._uiState.gasBumps[event.futureId] === undefined) { + this._uiState.gasBumps[event.futureId] = 0; + } + + this._uiState.gasBumps[event.futureId] += 1; + + this._redisplayCurrentBatch(); + } + + public onchainInteractionDropped( + _event: OnchainInteractionDroppedEvent + ): void {} + + public onchainInteractionReplacedByUser( + _event: OnchainInteractionReplacedByUserEvent + ): void {} + + public onchainInteractionTimeout( + _event: OnchainInteractionTimeoutEvent + ): void {} + + public deploymentComplete(event: DeploymentCompleteEvent): void { + this.state = { + ...this.state, + status: UiStateDeploymentStatus.COMPLETE, + result: event.result, + batches: this._applyResultToBatches(this.state.batches, event.result), + }; + + // If batches where executed, rerender the last batch + if (wasAnythingExecuted(this.state)) { + this._redisplayCurrentBatch(); + } else { + // Otherwise only the completion panel will be shown so clear + // the Starting Ignition line. + this._clearCurrentLine(); + } + + console.log(calculateDeploymentCompleteDisplay(event, this.state)); + } + + public reconciliationWarnings(event: ReconciliationWarningsEvent): void { + this.state = { + ...this.state, + warnings: [...this.state.warnings, ...event.warnings], + }; + } + + public setModuleId(event: SetModuleIdEvent): void { + this.state = { + ...this.state, + moduleName: event.moduleName, + }; + } + + public setStrategy(event: SetStrategyEvent): void { + this.state = { + ...this.state, + strategy: event.strategy, + }; + } + + public ledgerConnectionStart(): void { + this.state = { + ...this.state, + ledger: true, + ledgerMessage: "Connecting wallet", + }; + + this._redisplayCurrentBatch(); + + this.state = { + ...this.state, + ledgerMessageIsDisplayed: true, + }; + } + + public ledgerConnectionSuccess(): void { + this.state = { + ...this.state, + ledgerMessage: "Wallet connected", + }; + + this._redisplayCurrentBatch(); + } + + public ledgerConnectionFailure(): void { + this.state = { + ...this.state, + ledgerMessage: "Wallet connection failed", + }; + + this._redisplayCurrentBatch(); + } + + public ledgerConfirmationStart(): void { + this.state = { + ...this.state, + ledger: true, + ledgerMessage: "Waiting for confirmation on device", + }; + + this._redisplayCurrentBatch(); + + this.state = { + ...this.state, + ledgerMessageIsDisplayed: true, + }; + } + + public ledgerConfirmationSuccess(): void { + this.state = { + ...this.state, + ledgerMessage: "Transaction approved by device", + }; + + this._redisplayCurrentBatch(); + + this.state = { + ...this.state, + ledger: false, + }; + } + + public ledgerConfirmationFailure(): void { + this.state = { + ...this.state, + ledgerMessage: "Transaction confirmation failed", + }; + + this._redisplayCurrentBatch(); + } + + private _setFutureStatusInitializedAndRedisplayBatch({ + futureId, + }: { + futureId: string; + }) { + this._setFutureStatusAndRedisplayBatch(futureId, { + type: UiFutureStatusType.UNSTARTED, + }); + } + + private _setFutureStatusCompleteAndRedisplayBatch({ + futureId, + result, + }: { + futureId: string; + result: ExecutionEventResult; + }) { + this._setFutureStatusAndRedisplayBatch( + futureId, + this._getFutureStatusFromEventResult(result) + ); + + this.state = { + ...this.state, + ledgerMessageIsDisplayed: false, + }; + } + + private _setFutureStatusAndRedisplayBatch( + futureId: string, + status: UiFutureStatus + ) { + const updatedFuture: UiFuture = { + futureId, + status, + }; + + this.state = { + ...this.state, + batches: this._applyUpdateToBatchFuture(updatedFuture), + }; + + this._redisplayCurrentBatch(); + } + + private _applyUpdateToBatchFuture(updatedFuture: UiFuture): UiBatches { + const batches: UiBatches = []; + + for (const batch of this.state.batches) { + const futureBatch: UiFuture[] = []; + + for (const future of batch) { + if (future.futureId === updatedFuture.futureId) { + futureBatch.push(updatedFuture); + } else { + futureBatch.push(future); + } + } + + batches.push(futureBatch); + } + + return batches; + } + + private _getFutureStatusFromEventResult( + result: ExecutionEventResult + ): UiFutureSuccess | UiFutureErrored | UiFutureHeld { + switch (result.type) { + case ExecutionEventResultType.SUCCESS: { + return { + type: UiFutureStatusType.SUCCESS, + result: result.result, + }; + } + case ExecutionEventResultType.ERROR: { + return { + type: UiFutureStatusType.ERRORED, + message: result.error, + }; + } + case ExecutionEventResultType.HELD: { + return { + type: UiFutureStatusType.HELD, + heldId: result.heldId, + reason: result.reason, + }; + } + } + } + + private _applyResultToBatches( + batches: UiBatches, + result: DeploymentResult + ): UiBatches { + const newBatches: UiBatches = []; + + for (const oldBatch of batches) { + const newBatch = []; + for (const future of oldBatch) { + const updatedFuture = this._hasUpdatedResult(future.futureId, result); + + newBatch.push(updatedFuture ?? future); + } + + newBatches.push(newBatch); + } + + return newBatches; + } + + private _hasUpdatedResult( + futureId: string, + result: DeploymentResult + ): UiFuture | null { + if (result.type !== DeploymentResultType.EXECUTION_ERROR) { + return null; + } + + const failed = result.failed.find((f) => f.futureId === futureId); + + if (failed !== undefined) { + const f: UiFuture = { + futureId, + status: { + type: UiFutureStatusType.ERRORED, + message: failed.error, + }, + }; + + return f; + } + + const timedout = result.timedOut.find((f) => f.futureId === futureId); + + if (timedout !== undefined) { + const f: UiFuture = { + futureId, + status: { + type: UiFutureStatusType.TIMEDOUT, + }, + }; + + return f; + } + + return null; + } + + private _redisplayCurrentBatch() { + if (!this._disableOutput) { + const { height, text: batch } = calculateBatchDisplay(this.state); + + this._clearUpToHeight(height); + + console.log(batch); + } + } + + private _clearCurrentLine(): void { + readline.clearLine(process.stdout, 0); + readline.cursorTo(process.stdout, 0); + } + + private _clearUpToHeight(height: number) { + readline.moveCursor(process.stdout, 0, -height); + readline.clearScreenDown(process.stdout); + } +} diff --git a/packages/hardhat-ignition/src/ui/types.ts b/packages/hardhat-ignition/src/ui/types.ts new file mode 100644 index 0000000000..1eb6a1563d --- /dev/null +++ b/packages/hardhat-ignition/src/ui/types.ts @@ -0,0 +1,76 @@ +import { DeploymentResult } from "@nomicfoundation/ignition-core"; + +export enum UiFutureStatusType { + UNSTARTED = "UNSTARTED", + SUCCESS = "SUCCESS", + TIMEDOUT = "TIMEDOUT", + ERRORED = "ERRORED", + HELD = "HELD", +} + +export enum UiStateDeploymentStatus { + UNSTARTED = "UNSTARTED", + DEPLOYING = "DEPLOYING", + COMPLETE = "COMPLETE", +} + +export interface UiFutureUnstarted { + type: UiFutureStatusType.UNSTARTED; +} + +export interface UiFutureSuccess { + type: UiFutureStatusType.SUCCESS; + result?: string; +} + +export interface UiFutureTimedOut { + type: UiFutureStatusType.TIMEDOUT; +} + +export interface UiFutureErrored { + type: UiFutureStatusType.ERRORED; + message: string; +} + +export interface UiFutureHeld { + type: UiFutureStatusType.HELD; + heldId: number; + reason: string; +} + +export type UiFutureStatus = + | UiFutureUnstarted + | UiFutureSuccess + | UiFutureTimedOut + | UiFutureErrored + | UiFutureHeld; + +export interface UiFuture { + status: UiFutureStatus; + futureId: string; +} + +export type UiBatches = UiFuture[][]; + +export interface UiState { + status: UiStateDeploymentStatus; + chainId: number | null; + moduleName: string | null; + deploymentDir: string | undefined | null; + batches: UiBatches; + currentBatch: number; + result: DeploymentResult | null; + warnings: string[]; + isResumed: boolean | null; + maxFeeBumps: number; + gasBumps: Record; + disableFeeBumping: boolean | null; + strategy: string | null; + ledger: boolean; + ledgerMessage: string; + ledgerMessageIsDisplayed: boolean; +} + +export interface AddressMap { + [label: string]: string; +} diff --git a/packages/hardhat-ignition/src/ui/verbose-event-handler.ts b/packages/hardhat-ignition/src/ui/verbose-event-handler.ts new file mode 100644 index 0000000000..ad1491a4f5 --- /dev/null +++ b/packages/hardhat-ignition/src/ui/verbose-event-handler.ts @@ -0,0 +1,287 @@ +import { + BatchInitializeEvent, + BeginNextBatchEvent, + CallExecutionStateCompleteEvent, + CallExecutionStateInitializeEvent, + ContractAtExecutionStateInitializeEvent, + DeploymentCompleteEvent, + DeploymentExecutionStateCompleteEvent, + DeploymentExecutionStateInitializeEvent, + DeploymentInitializeEvent, + DeploymentStartEvent, + EncodeFunctionCallExecutionStateInitializeEvent, + ExecutionEventListener, + ExecutionEventNetworkInteractionType, + ExecutionEventResultType, + NetworkInteractionRequestEvent, + OnchainInteractionBumpFeesEvent, + OnchainInteractionDroppedEvent, + OnchainInteractionReplacedByUserEvent, + OnchainInteractionTimeoutEvent, + ReadEventArgExecutionStateInitializeEvent, + ReconciliationWarningsEvent, + RunStartEvent, + SendDataExecutionStateCompleteEvent, + SendDataExecutionStateInitializeEvent, + SetModuleIdEvent, + SetStrategyEvent, + StaticCallCompleteEvent, + StaticCallExecutionStateCompleteEvent, + StaticCallExecutionStateInitializeEvent, + TransactionConfirmEvent, + TransactionSendEvent, + WipeApplyEvent, +} from "@nomicfoundation/ignition-core"; + +export class VerboseEventHandler implements ExecutionEventListener { + public deploymentInitialize(event: DeploymentInitializeEvent): void { + console.log(`Deployment initialized for chainId: ${event.chainId}`); + } + + public wipeApply(event: WipeApplyEvent): void { + console.log(`Removing the execution of future ${event.futureId}`); + } + + public deploymentExecutionStateInitialize( + event: DeploymentExecutionStateInitializeEvent + ): void { + console.log(`Starting to execute the deployment future ${event.futureId}`); + } + + public deploymentExecutionStateComplete( + event: DeploymentExecutionStateCompleteEvent + ): void { + switch (event.result.type) { + case ExecutionEventResultType.SUCCESS: { + return console.log( + `Successfully completed the execution of deployment future ${ + event.futureId + } with address ${event.result.result ?? "undefined"}` + ); + } + case ExecutionEventResultType.ERROR: { + return console.log( + `Execution of future ${event.futureId} failed with reason: ${event.result.error}` + ); + } + case ExecutionEventResultType.HELD: { + return console.log( + `Execution of future ${event.futureId}/${event.result.heldId} held with reason: ${event.result.reason}` + ); + } + } + } + + public callExecutionStateInitialize( + event: CallExecutionStateInitializeEvent + ): void { + console.log(`Starting to execute the call future ${event.futureId}`); + } + + public callExecutionStateComplete( + event: CallExecutionStateCompleteEvent + ): void { + switch (event.result.type) { + case ExecutionEventResultType.SUCCESS: { + return console.log( + `Successfully completed the execution of call future ${event.futureId}` + ); + } + case ExecutionEventResultType.ERROR: { + return console.log( + `Execution of call future ${event.futureId} failed with reason: ${event.result.error}` + ); + } + case ExecutionEventResultType.HELD: { + return console.log( + `Execution of call future ${event.futureId}/${event.result.heldId} held with reason: ${event.result.reason}` + ); + } + } + } + + public staticCallExecutionStateInitialize( + event: StaticCallExecutionStateInitializeEvent + ): void { + console.log(`Starting to execute the static call future ${event.futureId}`); + } + + public staticCallExecutionStateComplete( + event: StaticCallExecutionStateCompleteEvent + ): void { + switch (event.result.type) { + case ExecutionEventResultType.SUCCESS: { + return console.log( + `Successfully completed the execution of static call future ${ + event.futureId + } with result ${event.result.result ?? "undefined"}` + ); + } + case ExecutionEventResultType.ERROR: { + return console.log( + `Execution of static call future ${event.futureId} failed with reason: ${event.result.error}` + ); + } + case ExecutionEventResultType.HELD: { + return console.log( + `Execution of static call future ${event.futureId}/${event.result.heldId} held with reason: ${event.result.reason}` + ); + } + } + } + + public sendDataExecutionStateInitialize( + event: SendDataExecutionStateInitializeEvent + ): void { + console.log(`Started to execute the send data future ${event.futureId}`); + } + + public sendDataExecutionStateComplete( + event: SendDataExecutionStateCompleteEvent + ): void { + switch (event.result.type) { + case ExecutionEventResultType.SUCCESS: { + return console.log( + `Successfully completed the execution of send data future ${ + event.futureId + } in tx ${event.result.result ?? "undefined"}` + ); + } + case ExecutionEventResultType.ERROR: { + return console.log( + `Execution of future ${event.futureId} failed with reason: ${event.result.error}` + ); + } + case ExecutionEventResultType.HELD: { + return console.log( + `Execution of send future ${event.futureId}/${event.result.heldId} held with reason: ${event.result.reason}` + ); + } + } + } + + public contractAtExecutionStateInitialize( + event: ContractAtExecutionStateInitializeEvent + ): void { + console.log(`Executed contract at future ${event.futureId}`); + } + + public readEventArgumentExecutionStateInitialize( + event: ReadEventArgExecutionStateInitializeEvent + ): void { + console.log( + `Executed read event argument future ${event.futureId} with result ${ + event.result.result ?? "undefined" + }` + ); + } + + public encodeFunctionCallExecutionStateInitialize( + event: EncodeFunctionCallExecutionStateInitializeEvent + ): void { + console.log( + `Executed encode function call future ${event.futureId} with result ${ + event.result.result ?? "undefined" + }` + ); + } + + public networkInteractionRequest( + event: NetworkInteractionRequestEvent + ): void { + if ( + event.networkInteractionType === + ExecutionEventNetworkInteractionType.ONCHAIN_INTERACTION + ) { + console.log( + `New onchain interaction requested for future ${event.futureId}` + ); + } else { + console.log(`New static call requested for future ${event.futureId}`); + } + } + + public transactionSend(event: TransactionSendEvent): void { + console.log( + `Transaction ${event.hash} sent for onchain interaction of future ${event.futureId}` + ); + } + + public transactionConfirm(event: TransactionConfirmEvent): void { + console.log(`Transaction ${event.hash} confirmed`); + } + + public staticCallComplete(event: StaticCallCompleteEvent): void { + console.log(`Static call completed for future ${event.futureId}`); + } + + public onchainInteractionBumpFees( + event: OnchainInteractionBumpFeesEvent + ): void { + console.log( + `A transaction with higher fees will be sent for onchain interaction of future ${event.futureId}` + ); + } + + public onchainInteractionDropped( + event: OnchainInteractionDroppedEvent + ): void { + console.log( + `Transactions for onchain interaction of future ${event.futureId} has been dropped and will be resent` + ); + } + + public onchainInteractionReplacedByUser( + event: OnchainInteractionReplacedByUserEvent + ): void { + console.log( + `Transactions for onchain interaction of future ${event.futureId} has been replaced by the user and the onchain interaction exection will start again` + ); + } + + public onchainInteractionTimeout( + event: OnchainInteractionTimeoutEvent + ): void { + console.log( + `Onchain interaction of future ${event.futureId} failed due to being resent too many times and not having confirmed` + ); + } + + public batchInitialize(event: BatchInitializeEvent): void { + console.log( + `Starting execution for batches: ${JSON.stringify(event.batches)}` + ); + } + + public deploymentStart(_event: DeploymentStartEvent): void { + console.log(`Starting execution for new deployment`); + } + + public beginNextBatch(_event: BeginNextBatchEvent): void { + console.log(`Starting execution for next batch`); + } + + public deploymentComplete(_event: DeploymentCompleteEvent): void { + console.log(`Deployment complete`); + } + + public reconciliationWarnings(event: ReconciliationWarningsEvent): void { + console.log( + `Deployment produced reconciliation warnings:\n${event.warnings.join( + " -" + )}` + ); + } + + public setModuleId(event: SetModuleIdEvent): void { + console.log(`Starting validation for module: ${event.moduleName}`); + } + + public setStrategy(event: SetStrategyEvent): void { + console.log(`Starting execution with strategy: ${event.strategy}`); + } + + public runStart(_event: RunStartEvent): void { + console.log("Execution run starting"); + } +} diff --git a/packages/hardhat-ignition/src/utils/bigintReviver.ts b/packages/hardhat-ignition/src/utils/bigintReviver.ts new file mode 100644 index 0000000000..11bb67e3e9 --- /dev/null +++ b/packages/hardhat-ignition/src/utils/bigintReviver.ts @@ -0,0 +1,16 @@ +import { NomicLabsHardhatPluginError } from "hardhat/plugins"; + +export function bigintReviver(key: string, value: any): any { + if (typeof value === "string" && /^\d+n$/.test(value)) { + return BigInt(value.slice(0, -1)); + } + + if (typeof value === "number" && value > Number.MAX_SAFE_INTEGER) { + throw new NomicLabsHardhatPluginError( + "hardhat-ignition", + `Parameter "${key}" exceeds maximum safe integer size. Encode the value as a string using bigint notation: \`$\{value\}n\`` + ); + } + + return value; +} diff --git a/packages/hardhat-ignition/src/utils/error-deployment-result-to-exception-message.ts b/packages/hardhat-ignition/src/utils/error-deployment-result-to-exception-message.ts new file mode 100644 index 0000000000..db02b53b1f --- /dev/null +++ b/packages/hardhat-ignition/src/utils/error-deployment-result-to-exception-message.ts @@ -0,0 +1,141 @@ +import { + DeploymentResultType, + ExecutionErrorDeploymentResult, + PreviousRunErrorDeploymentResult, + ReconciliationErrorDeploymentResult, + ValidationErrorDeploymentResult, +} from "@nomicfoundation/ignition-core"; +import { HardhatPluginError } from "hardhat/plugins"; + +/** + * Converts the result of an errored deployment into a message that can + * be shown to the user in an exception. + * + * @param result - the errored deployment's result + * @returns the text of the message + */ +export function errorDeploymentResultToExceptionMessage( + result: + | ValidationErrorDeploymentResult + | ReconciliationErrorDeploymentResult + | ExecutionErrorDeploymentResult + | PreviousRunErrorDeploymentResult +): string { + switch (result.type) { + case DeploymentResultType.VALIDATION_ERROR: + return _convertValidationError(result); + case DeploymentResultType.RECONCILIATION_ERROR: + return _convertReconciliationError(result); + case DeploymentResultType.EXECUTION_ERROR: + return _convertExecutionError(result); + case DeploymentResultType.PREVIOUS_RUN_ERROR: + return _convertPreviousRunError(result); + } +} + +function _convertValidationError( + result: ValidationErrorDeploymentResult +): string { + const errorsList = Object.entries(result.errors).flatMap( + ([futureId, errors]) => errors.map((err) => ` * ${futureId}: ${err}`) + ); + + return `The deployment wasn't run because of the following validation errors: + +${errorsList.join("\n")}`; +} + +function _convertReconciliationError( + result: ReconciliationErrorDeploymentResult +) { + const errorsList = Object.entries(result.errors).flatMap( + ([futureId, errors]) => errors.map((err) => ` * ${futureId}: ${err}`) + ); + + return `The deployment wasn't run because of the following reconciliation errors: + +${errorsList.join("\n")}`; +} + +function _convertExecutionError(result: ExecutionErrorDeploymentResult) { + const sections: string[] = []; + + const messageDetails = { + timeouts: result.timedOut.length > 0, + failures: result.failed.length > 0, + held: result.held.length > 0, + }; + + if (messageDetails.timeouts) { + const timeoutList = result.timedOut.map( + ({ futureId, networkInteractionId }) => + ` * ${futureId}/${networkInteractionId}` + ); + + sections.push(`Timed out:\n\n${timeoutList.join("\n")}`); + } + + if (messageDetails.failures) { + const errorList = result.failed.map( + ({ futureId, networkInteractionId, error }) => + ` * ${futureId}/${networkInteractionId}: ${error}` + ); + + sections.push(`Failures:\n\n${errorList.join("\n")}`); + } + + if (messageDetails.held) { + const reasonList = result.held.map( + ({ futureId, heldId, reason }) => ` * ${futureId}/${heldId}: ${reason}` + ); + + sections.push(`Held:\n\n${reasonList.join("\n")}`); + } + + return `The deployment wasn't successful, there were ${_toText( + messageDetails + )}: + +${sections.join("\n\n")}`; +} + +function _convertPreviousRunError(result: PreviousRunErrorDeploymentResult) { + const errorsList = Object.entries(result.errors).flatMap( + ([futureId, errors]) => errors.map((err) => ` * ${futureId}: ${err}`) + ); + + return `The deployment wasn't run because of the following errors in a previous run: + +${errorsList.join("\n")}`; +} + +function _toText({ + timeouts, + failures, + held, +}: { + timeouts: boolean; + failures: boolean; + held: boolean; +}): string { + if (timeouts && failures && held) { + return "timeouts, failures and holds"; + } else if (timeouts && failures) { + return "timeouts and failures"; + } else if (failures && held) { + return "failures and holds"; + } else if (timeouts && held) { + return "timeouts and holds"; + } else if (timeouts) { + return "timeouts"; + } else if (failures) { + return "failures"; + } else if (held) { + return "holds"; + } + + throw new HardhatPluginError( + "@nomicfoundation/hardhat-ignition", + "Invariant violated: neither timeouts or failures" + ); +} diff --git a/packages/hardhat-ignition/src/utils/getApiKeyAndUrls.ts b/packages/hardhat-ignition/src/utils/getApiKeyAndUrls.ts new file mode 100644 index 0000000000..4b34e8feaa --- /dev/null +++ b/packages/hardhat-ignition/src/utils/getApiKeyAndUrls.ts @@ -0,0 +1,22 @@ +import type { ChainConfig } from "@nomicfoundation/hardhat-verify/types"; + +import { NomicLabsHardhatPluginError } from "hardhat/plugins"; + +export function getApiKeyAndUrls( + etherscanApiKey: string | Record, + chainConfig: ChainConfig +): [apiKey: string, apiUrl: string, webUrl: string] { + const apiKey: string = + typeof etherscanApiKey === "string" + ? etherscanApiKey + : etherscanApiKey[chainConfig.network]; + + if (apiKey === undefined) { + throw new NomicLabsHardhatPluginError( + "@nomicfoundation/hardhat-ignition", + `No etherscan API key configured for network ${chainConfig.network}` + ); + } + + return [apiKey, chainConfig.urls.apiURL, chainConfig.urls.browserURL]; +} diff --git a/packages/hardhat-ignition/src/utils/load-module.ts b/packages/hardhat-ignition/src/utils/load-module.ts new file mode 100644 index 0000000000..09c3380843 --- /dev/null +++ b/packages/hardhat-ignition/src/utils/load-module.ts @@ -0,0 +1,92 @@ +import { IgnitionError, IgnitionModule } from "@nomicfoundation/ignition-core"; +import setupDebug from "debug"; +import { pathExistsSync } from "fs-extra"; +import { + HardhatPluginError, + NomicLabsHardhatPluginError, +} from "hardhat/plugins"; +import path from "path"; + +import { shouldBeHardhatPluginError } from "./shouldBeHardhatPluginError"; + +const debug = setupDebug("hardhat-ignition:modules"); + +const MODULES_FOLDER = "modules"; + +export function loadModule( + ignitionDirectory: string, + modulePath: string +): IgnitionModule | undefined { + const fullModulesDirectoryName = path.resolve( + ignitionDirectory, + MODULES_FOLDER + ); + + const shortModulesDirectoryName = path.join( + ignitionDirectory, + MODULES_FOLDER + ); + + debug(`Loading user modules from '${fullModulesDirectoryName}'`); + + const fullpathToModule = path.resolve(modulePath); + + if (!pathExistsSync(fullpathToModule)) { + throw new HardhatPluginError( + "hardhat-ignition", + `Could not find a module file at the path: ${modulePath}` + ); + } + + if (!isInModuleDirectory(fullModulesDirectoryName, fullpathToModule)) { + throw new HardhatPluginError( + "hardhat-ignition", + `The referenced module file ${modulePath} is outside the module directory ${shortModulesDirectoryName}` + ); + } + + debug(`Loading module file '${fullpathToModule}'`); + + let module; + try { + module = require(fullpathToModule); + } catch (e) { + if (e instanceof IgnitionError) { + /** + * Errors thrown from within ModuleBuilder use this errorNumber. + * + * They have a stack trace that's useful to the user, so we display it here, instead of + * wrapping the error in a NomicLabsHardhatPluginError. + */ + if (e.errorNumber === 702) { + console.error(e); + + throw new NomicLabsHardhatPluginError( + "hardhat-ignition", + "Module validation failed. Check the stack trace above to identify the issue and its source code location." + ); + } + + if (shouldBeHardhatPluginError(e)) { + throw new NomicLabsHardhatPluginError("hardhat-ignition", e.message, e); + } + } + + throw e; + } + + return module.default ?? module; +} + +function isInModuleDirectory(modulesDirectory: string, modulePath: string) { + const resolvedModulesDirectory = path.resolve(modulesDirectory); + const moduleRelativeToModuleDir = path.relative( + resolvedModulesDirectory, + modulePath + ); + + return ( + !moduleRelativeToModuleDir.startsWith("..") && + !path.isAbsolute(moduleRelativeToModuleDir) + ); +} diff --git a/packages/hardhat-ignition/src/utils/open.ts b/packages/hardhat-ignition/src/utils/open.ts new file mode 100644 index 0000000000..eb5b1ee6b8 --- /dev/null +++ b/packages/hardhat-ignition/src/utils/open.ts @@ -0,0 +1,22 @@ +import { execSync } from "child_process"; +import os from "os"; + +export function open(filePath: string): void { + let command: string; + switch (os.platform()) { + case "win32": + command = "start"; + break; + case "darwin": + command = "open"; + break; + default: + command = "xdg-open"; + } + + try { + execSync(`${command} ${filePath}`, { stdio: "ignore" }); + } catch { + // do nothing + } +} diff --git a/packages/hardhat-ignition/src/utils/read-deployment-parameters.ts b/packages/hardhat-ignition/src/utils/read-deployment-parameters.ts new file mode 100644 index 0000000000..fb6bee8cd6 --- /dev/null +++ b/packages/hardhat-ignition/src/utils/read-deployment-parameters.ts @@ -0,0 +1,30 @@ +import { DeploymentParameters } from "@nomicfoundation/ignition-core"; +import { readFile } from "fs-extra"; +import { NomicLabsHardhatPluginError } from "hardhat/plugins"; +import { parse as json5Parse } from "json5"; + +import { bigintReviver } from "./bigintReviver"; + +export async function readDeploymentParameters( + filepath: string +): Promise { + try { + const rawFile = await readFile(filepath); + + return await json5Parse(rawFile.toString(), bigintReviver); + } catch (e) { + if (e instanceof NomicLabsHardhatPluginError) { + throw e; + } + + if (e instanceof Error) { + throw new NomicLabsHardhatPluginError( + "@nomicfoundation/hardhat-ignition", + `Could not parse parameters from ${filepath}`, + e + ); + } + + throw e; + } +} diff --git a/packages/hardhat-ignition/src/utils/resolve-deployment-id.ts b/packages/hardhat-ignition/src/utils/resolve-deployment-id.ts new file mode 100644 index 0000000000..ad9aaf2504 --- /dev/null +++ b/packages/hardhat-ignition/src/utils/resolve-deployment-id.ts @@ -0,0 +1,43 @@ +import { NomicLabsHardhatPluginError } from "hardhat/plugins"; + +/** + * A regex that captures Ignitions rules for deployment-ids, specifically + * that they can only contain alphanumerics, dashes and underscores, + * and that they start with a letter. + */ +const ignitionDeploymentIdRegex = /^[a-zA-Z][a-zA-Z0-9_\-]*$/; + +/** + * Determine the deploymentId, using either the user provided id, + * throwing if it is invalid, or generating one from the chainId + * if none was provided. + * + * @param givenDeploymentId - the user provided deploymentId if + * they provided one undefined otherwise + * @param chainId - the chainId of the network being deployed to + * + * @returns the deploymentId + */ +export function resolveDeploymentId( + givenDeploymentId: string | undefined, + chainId: number +) { + if ( + givenDeploymentId !== undefined && + !_isValidDeploymentIdentifier(givenDeploymentId) + ) { + throw new NomicLabsHardhatPluginError( + "hardhat-ignition", + `The deployment-id "${givenDeploymentId}" contains banned characters, ids can only contain alphanumerics, dashes or underscores` + ); + } + + return givenDeploymentId ?? `chain-${chainId}`; +} + +/** + * Determine if the given identifier the rules for a valid deployment id. + * */ +export function _isValidDeploymentIdentifier(identifier: string): boolean { + return ignitionDeploymentIdRegex.test(identifier); +} diff --git a/packages/hardhat-ignition/src/utils/shouldBeHardhatPluginError.ts b/packages/hardhat-ignition/src/utils/shouldBeHardhatPluginError.ts new file mode 100644 index 0000000000..add829bb5b --- /dev/null +++ b/packages/hardhat-ignition/src/utils/shouldBeHardhatPluginError.ts @@ -0,0 +1,20 @@ +import type { IgnitionError } from "@nomicfoundation/ignition-core"; + +/** + * This is a whitelist of error codes that should be rethrown as NomicLabsHardhatPluginError. + * + * The rules for adding an error code to this list are: + * - If an exception is used to tell the user that they did something wrong, it should be added. + * - If an exception is used to indicate some failure and terminate the current process/deployment, that shouldn't be added. + * - If there's an exception that doesn't fit in either category, let's discuss it and review the categories. + */ +const whitelist = [ + 200, 201, 202, 203, 204, 403, 404, 405, 406, 407, 408, 409, 411, 600, 601, + 602, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, 712, 713, + 714, 715, 716, 717, 718, 719, 720, 721, 722, 723, 724, 725, 726, 800, 900, + 1000, 1001, 1002, 1101, 1102, 1103, 1300, 1301, 1302, 1303, 1304, 1305, +]; + +export function shouldBeHardhatPluginError(error: IgnitionError): boolean { + return whitelist.includes(error.errorNumber); +} diff --git a/packages/hardhat-ignition/src/utils/verifyEtherscanContract.ts b/packages/hardhat-ignition/src/utils/verifyEtherscanContract.ts new file mode 100644 index 0000000000..d43f861e63 --- /dev/null +++ b/packages/hardhat-ignition/src/utils/verifyEtherscanContract.ts @@ -0,0 +1,37 @@ +import type { Etherscan } from "@nomicfoundation/hardhat-verify/etherscan"; +import type { VerifyInfo } from "@nomicfoundation/ignition-core"; + +export async function verifyEtherscanContract( + etherscanInstance: Etherscan, + { address, compilerVersion, sourceCode, name, args }: VerifyInfo +): Promise< + { type: "success"; contractURL: string } | { type: "failure"; reason: Error } +> { + try { + const { message: guid } = await etherscanInstance.verify( + address, + sourceCode, + name, + compilerVersion, + args + ); + + const verificationStatus = await etherscanInstance.getVerificationStatus( + guid + ); + + if (verificationStatus.isSuccess()) { + const contractURL = etherscanInstance.getContractUrl(address); + return { type: "success", contractURL }; + } else { + // todo: what case would cause verification status not to succeed without throwing? + return { type: "failure", reason: new Error(verificationStatus.message) }; + } + } catch (e) { + if (e instanceof Error) { + return { type: "failure", reason: e }; + } else { + throw e; + } + } +} diff --git a/packages/hardhat-ignition/src/visualization/write-visualization.ts b/packages/hardhat-ignition/src/visualization/write-visualization.ts new file mode 100644 index 0000000000..1c5c8df308 --- /dev/null +++ b/packages/hardhat-ignition/src/visualization/write-visualization.ts @@ -0,0 +1,37 @@ +import { SerializedIgnitionModule } from "@nomicfoundation/ignition-core"; +import { ensureDir, pathExists, readFile, writeFile } from "fs-extra"; +import { NomicLabsHardhatPluginError } from "hardhat/plugins"; +import path from "path"; + +export async function writeVisualization( + visualizationPayload: { + module: SerializedIgnitionModule; + batches: string[][]; + }, + { cacheDir }: { cacheDir: string } +) { + const templateDir = path.join( + require.resolve("@nomicfoundation/ignition-ui/package.json"), + "../dist" + ); + + const templateDirExists = await pathExists(templateDir); + + if (!templateDirExists) { + throw new NomicLabsHardhatPluginError( + "@nomicfouncation/hardhat-ignition", + `Unable to find template directory: ${templateDir}` + ); + } + + const visualizationDir = path.join(cacheDir, "visualization"); + + await ensureDir(visualizationDir); + + const indexHtml = await readFile(path.join(templateDir, "index.html")); + const updatedHtml = indexHtml + .toString() + .replace('{ "unloaded": true }', JSON.stringify(visualizationPayload)); + + await writeFile(path.join(visualizationDir, "index.html"), updatedHtml); +} diff --git a/packages/hardhat-ignition/test/.eslintrc.js b/packages/hardhat-ignition/test/.eslintrc.js new file mode 100644 index 0000000000..757fe8a3ca --- /dev/null +++ b/packages/hardhat-ignition/test/.eslintrc.js @@ -0,0 +1,15 @@ +module.exports = { + extends: [`${__dirname}/../.eslintrc.js`], + parserOptions: { + project: `${__dirname}/../tsconfig.json`, + sourceType: "module", + }, + rules: { + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: true, + }, + ], + }, +}; diff --git a/packages/hardhat-ignition/test/config.ts b/packages/hardhat-ignition/test/config.ts new file mode 100644 index 0000000000..05cc7a6c2f --- /dev/null +++ b/packages/hardhat-ignition/test/config.ts @@ -0,0 +1,105 @@ +/* eslint-disable import/no-unused-modules */ + +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; +import { HardhatConfig } from "hardhat/types"; + +import { KeyListOf } from "./test-helpers/type-helper"; +import { useEphemeralIgnitionProject } from "./test-helpers/use-ignition-project"; + +describe("config", () => { + describe("loading", () => { + useEphemeralIgnitionProject("with-config"); + + let loadedOptions: Partial; + + beforeEach(function () { + loadedOptions = this.hre.config.ignition; + }); + + it("should apply requiredConfirmations", async function () { + assert.equal(loadedOptions.requiredConfirmations, 10); + }); + + it("should apply blockPollingInterval", async function () { + assert.equal(loadedOptions.blockPollingInterval, 100); + }); + + it("should apply timeBeforeBumpingFees", async function () { + assert.equal(loadedOptions.timeBeforeBumpingFees, 60 * 1000); + }); + + it("should apply maxFeeBumps", async function () { + assert.equal(loadedOptions.maxFeeBumps, 2); + }); + + it("should apply strategyConfig", async function () { + assert.deepStrictEqual(loadedOptions.strategyConfig, { + create2: { salt: "custom-salt" }, + }); + }); + + it("should apply disableFeeBumping at the top level", async function () { + assert.equal(loadedOptions.disableFeeBumping, true); + }); + + it("should apply maxFeePerGasLimit", async function () { + assert.equal( + this.hre.config.networks.hardhat.ignition.maxFeePerGasLimit, + 2n + ); + }); + + it("should apply maxPriorityFeePerGas", async function () { + assert.equal( + this.hre.config.networks.hardhat.ignition.maxPriorityFeePerGas, + 3n + ); + }); + + it("should apply gasPrice", async function () { + assert.equal(this.hre.config.networks.hardhat.ignition.gasPrice, 1n); + }); + + it("should apply disableFeeBumping at the network level", async function () { + assert.equal( + this.hre.config.networks.hardhat.ignition.disableFeeBumping, + false + ); + }); + + it("should only have known config", () => { + const configOptions: KeyListOf = [ + "blockPollingInterval", + "disableFeeBumping", + "maxFeeBumps", + "requiredConfirmations", + "strategyConfig", + "timeBeforeBumpingFees", + ]; + + assert.deepStrictEqual(Object.keys(loadedOptions).sort(), configOptions); + }); + }); + + describe("validating", () => { + useEphemeralIgnitionProject("with-invalid-config"); + + it("should throw when given a `requiredConfirmations` value less than 1", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const foo = m.contract("Foo"); + + return { foo }; + }); + + await assert.isRejected( + this.hre.ignition.deploy(moduleDefinition, { + config: { + requiredConfirmations: 0, + }, + }), + `Configured value 'requiredConfirmations' cannot be less than 1. Value given: '0'` + ); + }); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/default-sender.ts b/packages/hardhat-ignition/test/deploy/default-sender.ts new file mode 100644 index 0000000000..6247eb7e71 --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/default-sender.ts @@ -0,0 +1,47 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("default sender", function () { + useEphemeralIgnitionProject("minimal"); + + it("should throw if default sender is not in configured accounts", async function () { + await assert.isRejected( + this.hre.run( + { scope: "ignition", task: "deploy" }, + { + modulePath: "ignition/modules/OwnModule.js", + defaultSender: "0x1234567890abcdef1234567890abcdef12345678", + } + ), + /IGN700: Default sender 0x1234567890abcdef1234567890abcdef12345678 is not part of the configured accounts./ + ); + }); + + it("should allow setting default sender via cli", async function () { + const secondAccountAddress = "0x70997970C51812dc3A010C7d01b50e0d17dc79C8"; + + await this.hre.run( + { scope: "ignition", task: "deploy" }, + { + modulePath: "ignition/modules/OwnModule.js", + defaultSender: secondAccountAddress, + } + ); + + const existingModule = buildModule("ExistingModule", (m) => { + const bar = m.contractAt( + "Ownable", + "0x8464135c8F25Da09e49BC8782676a84730C318bC" + ); + + return { bar }; + }); + + const result = await this.hre.ignition.deploy(existingModule); + + assert.equal(await result.bar.read.owner(), secondAccountAddress); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/gas-estimation.ts b/packages/hardhat-ignition/test/deploy/gas-estimation.ts new file mode 100644 index 0000000000..bc8cbdf8aa --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/gas-estimation.ts @@ -0,0 +1,27 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("gas estimation", function () { + useEphemeralIgnitionProject("minimal"); + + it("should throw with simulation error if sender account has less ETH than gas estimate", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const foo = m.contract("Fails"); + + return { foo }; + }); + + await this.hre.network.provider.send("hardhat_setBalance", [ + "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + "0x1", + ]); + + await assert.isRejected( + this.hre.ignition.deploy(moduleDefinition), + /Simulating the transaction failed with error: Reverted with reason "Constructor failed"/ + ); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/module-patterns/index-pattern.ts b/packages/hardhat-ignition/test/deploy/module-patterns/index-pattern.ts new file mode 100644 index 0000000000..077903af73 --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/module-patterns/index-pattern.ts @@ -0,0 +1,104 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { useEphemeralIgnitionProject } from "../../test-helpers/use-ignition-project"; + +describe("index pattern deployments", function () { + useEphemeralIgnitionProject("index-pattern-success"); + + it("should succeed for a standard case", async function () { + const Mod1 = buildModule("Mod1", (m) => { + const F1 = m.contract("F1"); + + m.call(F1, "first"); + + return { F1 }; + }); + + const Mod2 = buildModule("Mod2", (m) => { + const { F1 } = m.useModule(Mod1); + + const F2 = m.contract("F2", [F1]); + + m.call(F2, "second"); + + return { F2 }; + }); + + const IndexMod = buildModule("IndexMod", (m) => { + const { F2 } = m.useModule(Mod2); + + return { F2 }; + }); + + const moduleDefinition = buildModule("DeployModule", (m) => { + const { F1 } = m.useModule(Mod1); + + m.call(F1, "third", [], { after: [Mod1, IndexMod] }); + + return { F1 }; + }); + + await assert.isFulfilled(this.hre.ignition.deploy(moduleDefinition)); + }); + + it("should succeed for a malaga case", async function () { + const Mod1 = buildModule("Mod1", (m) => { + const F1 = m.contract("F1"); + + return { F1 }; + }); + + const Mod2 = buildModule("Mod2", (m) => { + const { F1 } = m.useModule(Mod1); + + const F2 = m.contract("F2", [F1]); + + const firstCall = m.call(F2, "unrelatedFunc"); + const secondCall = m.call(F2, "unrelatedFunc", [], { + after: [firstCall], + id: "secondCall", + }); + const lastCall = m.call(F2, "unrelatedFunc", [], { + after: [secondCall], + id: "lastCall", + }); + + m.call(F2, "mustBeCalledByTwoSeparateContracts", [], { + after: [lastCall], + }); + + return { F2 }; + }); + + const Mod3 = buildModule("Mod3", (m) => { + const { F1 } = m.useModule(Mod1); + + const F3 = m.contract("F2", [F1], { id: "F3" }); + + return { F3 }; + }); + + const IndexMod = buildModule("IndexMod", (m) => { + const { F1 } = m.useModule(Mod1); + const { F2 } = m.useModule(Mod2); + const { F3 } = m.useModule(Mod3); + + const lastCall = m.call(F3, "mustBeCalledByTwoSeparateContracts"); + const NewF1 = m.contractAt("F1", F1, { after: [lastCall], id: "NewF1" }); + + return { NewF1, F2, F3 }; + }); + + const moduleDefinition = buildModule("DeployModule", (m) => { + const { NewF1 } = m.useModule(IndexMod); + + m.call(NewF1, "throwsIfNotCalledTwice"); + + return {}; + }); + + await assert.isFulfilled(this.hre.ignition.deploy(moduleDefinition)); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/multiple-batch-contract-deploy.ts b/packages/hardhat-ignition/test/deploy/multiple-batch-contract-deploy.ts new file mode 100644 index 0000000000..d92ed7422f --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/multiple-batch-contract-deploy.ts @@ -0,0 +1,76 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { sleep } from "../test-helpers/sleep"; +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +/** + * Deploy a multiple contracts over several batches. + * + * The intent here is to test batching. + */ +describe("execution - multiple batch contract deploy", function () { + useEphemeralIgnitionProject("minimal"); + + it("should deploy over multiple batches", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const contract1 = m.contract("Foo", [], { id: "Contract1" }); + const contractA = m.contract("Foo", [], { id: "ContractA" }); + + const contract2 = m.contract("Foo", [], { + id: "Contract2", + after: [contract1], + }); + const contractB = m.contract("Foo", [], { + id: "ContractB", + after: [contractA], + }); + + const contract3 = m.contract("Foo", [], { + id: "Contract3", + after: [contract2], + }); + const contractC = m.contract("Foo", [], { + id: "ContractC", + after: [contractB], + }); + + return { + contract1, + contractA, + contract2, + contractB, + contract3, + contractC, + }; + }); + + const deployPromise = this.hre.ignition.deploy(moduleDefinition); + + await sleep(300); + await this.hre.network.provider.send("evm_mine"); + + await sleep(300); + await this.hre.network.provider.send("evm_mine"); + + await sleep(300); + await this.hre.network.provider.send("evm_mine"); + + const result = await deployPromise; + + const x1 = await result.contract1.read.x(); + const xA = await result.contractA.read.x(); + const x2 = await result.contract2.read.x(); + const xB = await result.contractB.read.x(); + const x3 = await result.contract3.read.x(); + const xC = await result.contractC.read.x(); + + assert.equal(x1, 1n); + assert.equal(xA, 1n); + assert.equal(x2, 1n); + assert.equal(xB, 1n); + assert.equal(x3, 1n); + assert.equal(xC, 1n); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/nonce-checks/error-on-pending-user-transactions.ts b/packages/hardhat-ignition/test/deploy/nonce-checks/error-on-pending-user-transactions.ts new file mode 100644 index 0000000000..460c582b59 --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/nonce-checks/error-on-pending-user-transactions.ts @@ -0,0 +1,77 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; +import { createWalletClient, custom } from "viem"; +import { hardhat } from "viem/chains"; + +import { mineBlock } from "../../test-helpers/mine-block"; +import { + TestChainHelper, + useFileIgnitionProject, +} from "../../test-helpers/use-ignition-project"; +import { waitForPendingTxs } from "../../test-helpers/wait-for-pending-txs"; + +/** + * For all accounts that will be used during the deployment we check + * to see if there are pending transactions (not from previous runs) + * and error if there are any. + */ +describe("execution - error on pending user transactions", () => { + useFileIgnitionProject( + "minimal", + "error-on-rerun-with-replaced-pending-user-transaction" + ); + + it("should error if a transaction is in flight for an account used in the deploy", async function () { + // Setup a module with a contract deploy on accounts[2] + const moduleDefinition = buildModule("FooModule", (m) => { + const account2 = m.getAccount(2); + + const foo = m.contract("Foo", [], { from: account2 }); + + return { + foo, + }; + }); + + const FooArtifact = this.hre.artifacts.readArtifactSync("Foo"); + + // Before deploy, put a valid transaction into the mempool for accounts[2] + const [, , signer2] = (await this.hre.network.provider.request({ + method: "eth_accounts", + })) as string[]; + + const walletClient = createWalletClient({ + chain: hardhat, + transport: custom(this.hre.network.provider), + }); + + const deployPromise = walletClient.deployContract({ + abi: FooArtifact.abi, + bytecode: FooArtifact.bytecode as `0x${string}`, + args: [], + account: signer2 as `0x${string}`, + }); + + await waitForPendingTxs(this.hre, 1, deployPromise); + + // Deploying the module that uses accounts[2] throws with a warning + await assert.isRejected( + this.runControlledDeploy( + moduleDefinition, + async (_c: TestChainHelper) => {} + ), + "IGN403: You have sent transactions from 0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc and they interfere with Hardhat Ignition. Please wait until they get 1 confirmations before running Hardhat Ignition again." + ); + + // Now mine the user interference transaction + await mineBlock(this.hre); + + // The users interfering transaction completes normally + const outsideFoo = await deployPromise; + assert.equal( + outsideFoo, + "0x3d0ac80b8daf180b4d03e0ff107caa7089b5494cdbd81ba9d7619cc4d710caae" + ); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/nonce-checks/error-on-rerun-with-replaced-pending-user-transaction.ts b/packages/hardhat-ignition/test/deploy/nonce-checks/error-on-rerun-with-replaced-pending-user-transaction.ts new file mode 100644 index 0000000000..3d3ec36546 --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/nonce-checks/error-on-rerun-with-replaced-pending-user-transaction.ts @@ -0,0 +1,83 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; +import { createWalletClient, custom, parseEther } from "viem"; +import { hardhat } from "viem/chains"; + +import { + TestChainHelper, + useFileIgnitionProject, +} from "../../test-helpers/use-ignition-project"; + +/** + * Run an initial deploy, that starts but does not finish several on-chain + * transactions via Ignition. The user then replaces a transaction by + * reusing a nonce with a higher gas value. On the rerun we should + * error that there is a pending non-ignition transaction. + */ +describe("execution - error on rerun with replaced pending user transaction", () => { + useFileIgnitionProject( + "minimal", + "error-on-rerun-with-replaced-pending-user-transaction" + ); + + it("should error on the second run", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const account2 = m.getAccount(2); + + // batch 1 + const foo1 = m.contract("Foo", [], { id: "Foo1", from: account2 }); + const foo2 = m.contract("Foo", [], { id: "Foo2", from: account2 }); + const foo3 = m.contract("Foo", [], { id: "Foo3", from: account2 }); + + return { + foo1, + foo2, + foo3, + }; + }); + + // Start the deployment, but exit before processing a block, + // so transactions are in memory pool but not confirmed + await this.runControlledDeploy( + moduleDefinition, + async (c: TestChainHelper) => { + // Wait for the submission of foo1 foo2 and foo3 to mempool + await c.waitForPendingTxs(3); + + // Then kill before any blocks + c.exitDeploy(); + } + ); + + const FooArtifact = this.hre.artifacts.readArtifactSync("Foo"); + + // Send user interefering deploy transaction, between runs + // so it is in mempool, overriding the existing nonce 2 + // transaction + const [, , signer2] = (await this.hre.network.provider.request({ + method: "eth_accounts", + })) as string[]; + + const walletClient = createWalletClient({ + chain: hardhat, + transport: custom(this.hre.network.provider), + }); + + void walletClient.deployContract({ + abi: FooArtifact.abi, + bytecode: FooArtifact.bytecode as `0x${string}`, + args: [], + account: signer2 as `0x${string}`, + gasPrice: parseEther("500", "gwei"), + nonce: 2, + }); + + // On the second run, we should detect the user interference + // and error + await assert.isRejected( + this.hre.ignition.deploy(moduleDefinition), + "IGN403: You have sent transactions from 0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc and they interfere with Hardhat Ignition. Please wait until they get 5 confirmations before running Hardhat Ignition again." + ); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/nonce-checks/error-on-transaction-dropped.ts b/packages/hardhat-ignition/test/deploy/nonce-checks/error-on-transaction-dropped.ts new file mode 100644 index 0000000000..f555836dee --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/nonce-checks/error-on-transaction-dropped.ts @@ -0,0 +1,55 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { + TestChainHelper, + useFileIgnitionProject, +} from "../../test-helpers/use-ignition-project"; + +/** + * On running a deploy, if a transaction is dropped from the mempool + * before it is confirmed, then we halt and display an error. + */ +describe("execution - error on transaction dropped", () => { + useFileIgnitionProject("minimal", "error-on-transaction-dropped"); + + it("should error on the drop being detected", async function () { + // Setup a module with two contract deploys (foo1 and foo2) over 2 batches + const moduleDefinition = buildModule("FooModule", (m) => { + const account2 = m.getAccount(2); + + // batch 1 + const foo1 = m.contract("Foo", [], { id: "Foo1", from: account2 }); + + // batch 2 + const foo2 = m.contract("Foo", [], { + id: "Foo2", + from: account2, + after: [foo1], + }); + + return { + foo1, + foo2, + }; + }); + + // The deploy should exception once the dropped transaction for foo2 + // is detected + + await assert.isRejected( + this.runControlledDeploy(moduleDefinition, async (c: TestChainHelper) => { + // Process block 1 confirming foo1 + await c.mineBlock(1); + + // Wait for foo2 to be pending, then wipe it from memory pool + await c.clearMempool(1); + + // Mine further block allowing foo2 to be checked again + await c.mineBlock(); + }), + "IGN401: Error while executing FooModule#Foo2: all the transactions of its network interaction 1 were dropped. Please try rerunning Hardhat Ignition." + ); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/nonce-checks/error-on-user-transaction-sent.ts b/packages/hardhat-ignition/test/deploy/nonce-checks/error-on-user-transaction-sent.ts new file mode 100644 index 0000000000..ba5f88e346 --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/nonce-checks/error-on-user-transaction-sent.ts @@ -0,0 +1,80 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; +import { createWalletClient, custom } from "viem"; +import { hardhat } from "viem/chains"; + +import { + TestChainHelper, + useFileIgnitionProject, +} from "../../test-helpers/use-ignition-project"; + +/** + * On running a deploy, if a transaction is pending and the user + * sends a new transaction outside Ignition on the same account + * we should error and halt immediately + */ +describe("execution - error on user transaction sent", () => { + useFileIgnitionProject("minimal", "error-on-user-transaction-sent"); + + it("should error on the drop being detected", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const account2 = m.getAccount(2); + + // batch 1 + const foo1 = m.contract("Foo", [], { id: "Foo1", from: account2 }); + + // batch 2 + const foo2 = m.contract("Foo", [], { + id: "Foo2", + from: account2, + after: [foo1], + }); + + return { + foo1, + foo2, + }; + }); + + // The deploy should exception when the additional user interfering + // transaction is detected + await assert.isRejected( + this.runControlledDeploy(moduleDefinition, async (c: TestChainHelper) => { + // wait for foo1 to be submitted + await c.waitForPendingTxs(1); + + const FooArtifact = this.hre.artifacts.readArtifactSync("Foo"); + + // Submit user interference transaction to mempool (note a fresh + // nonce is used, so no replacement) + const [, , signer2] = (await this.hre.network.provider.request({ + method: "eth_accounts", + })) as string[]; + + const walletClient = createWalletClient({ + chain: hardhat, + transport: custom(this.hre.network.provider), + }); + + const deployPromise = walletClient.deployContract({ + abi: FooArtifact.abi, + bytecode: FooArtifact.bytecode as `0x${string}`, + args: [], + account: signer2 as `0x${string}`, + gasPrice: 500_000_000_000n, + }); + + // Process block 1 with foo1 + await c.mineBlock(1); + + const fooAddress = await deployPromise; + assert.equal( + fooAddress, + "0x9154ff20c97a7ebf9d2ebbb3f8b7e24bf99caee050a24c50f1162492c0b6af79" + ); + }), + "IGN405: The next nonce for 0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc should be 1, but is 2. Please make sure not to send transactions from 0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc while running this deployment and try again." + ); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/nonce-checks/rerun-with-dropped-ignition-transaction.ts b/packages/hardhat-ignition/test/deploy/nonce-checks/rerun-with-dropped-ignition-transaction.ts new file mode 100644 index 0000000000..d943fdb18c --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/nonce-checks/rerun-with-dropped-ignition-transaction.ts @@ -0,0 +1,59 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { clearPendingTransactionsFromMemoryPool } from "../../test-helpers/clear-pending-transactions-from-memory-pool"; +import { mineBlock } from "../../test-helpers/mine-block"; +import { + TestChainHelper, + useFileIgnitionProject, +} from "../../test-helpers/use-ignition-project"; + +/** + * Run an initial deploy, that starts but does not finish an on-chain + * transaction. The transaction is dropped from the memory pool. On rerun + * the transaction should be resubmitted. + */ +describe("execution - rerun with dropped ignition transactions", () => { + useFileIgnitionProject("minimal", "rerun-with-dropped-ignition-transactions"); + + it("should deploy successfully on second run", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const foo = m.contract("Foo", []); + + return { + foo, + }; + }); + + // Start the deploy + await this.runControlledDeploy( + moduleDefinition, + async (c: TestChainHelper) => { + // Wait for the submission of foo to mempool + await c.waitForPendingTxs(1); + + // kill the deployment before confirming foo + c.exitDeploy(); + } + ); + + // remove the submitted foo deploy from mempool + await clearPendingTransactionsFromMemoryPool(this.hre); + + // Further blocks with no pending transactions + await mineBlock(this.hre); + await mineBlock(this.hre); + + // Rerun the deployment + const result = await this.runControlledDeploy( + moduleDefinition, + async (c: TestChainHelper) => { + // this block shound include deployment of foo via resend + await c.mineBlock(1); + } + ); + + assert.equal(await result.foo.read.x(), 1n); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/nonce-checks/rerun-with-now-complete-ignition-transactions.ts b/packages/hardhat-ignition/test/deploy/nonce-checks/rerun-with-now-complete-ignition-transactions.ts new file mode 100644 index 0000000000..b45d53c4f9 --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/nonce-checks/rerun-with-now-complete-ignition-transactions.ts @@ -0,0 +1,105 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { mineBlock } from "../../test-helpers/mine-block"; +import { + TestChainHelper, + useFileIgnitionProject, +} from "../../test-helpers/use-ignition-project"; + +/** + * Run an initial deploy, that sumbit but does not confirm several on-chain + * transactions via Ignition. Those ignition transactions now confirm before + * a second run completes the deploy. + */ +describe("execution - rerun with now complete ignition transactions", () => { + useFileIgnitionProject( + "minimal", + "rerun-with-now-complete-ignition-transactions" + ); + + it("should complete the run on the second attempt", async function () { + // Setup a module with 6 foo contracts deployed in pairs of 2 over 3 batches + const moduleDefinition = buildModule("FooModule", (m) => { + const account2 = m.getAccount(2); + + // batch 1 + const foo1 = m.contract("Foo", [], { id: "Foo1", from: account2 }); + const foo2 = m.contract("Foo", [], { id: "Foo2", from: account2 }); + + // batch 2 + const foo3 = m.contract("Foo", [], { + id: "Foo3", + from: account2, + after: [foo1], + }); + const foo4 = m.contract("Foo", [], { + id: "Foo4", + from: account2, + after: [foo2], + }); + + // batch 3 + const foo5 = m.contract("Foo", [], { + id: "Foo5", + from: account2, + after: [foo3], + }); + const foo6 = m.contract("Foo", [], { + id: "Foo6", + from: account2, + after: [foo4], + }); + + return { + foo1, + foo2, + foo3, + foo4, + foo5, + foo6, + }; + }); + + await this.runControlledDeploy( + moduleDefinition, + async (c: TestChainHelper) => { + // Process the first block, include foo1 and foo2 + await c.mineBlock(2); + + // Kill the deployment, after foo3 and foo4 are submitted to mempool + await c.waitForPendingTxs(2); + c.exitDeploy(); + } + ); + + // Further blocks are processed confirming foo3 and foo4 + await mineBlock(this.hre); + await mineBlock(this.hre); + + // Rerun the deployment, with foo3 and foo3 now confirmed + const result = await this.runControlledDeploy( + moduleDefinition, + async (c: TestChainHelper) => { + await c.mineBlock(2); + } + ); + + assert.isDefined(result); + + const x1 = await result.foo1.read.x(); + const x2 = await result.foo2.read.x(); + const x3 = await result.foo3.read.x(); + const x4 = await result.foo4.read.x(); + const x5 = await result.foo5.read.x(); + const x6 = await result.foo6.read.x(); + + assert.equal(x1, 1n); + assert.equal(x2, 1n); + assert.equal(x3, 1n); + assert.equal(x4, 1n); + assert.equal(x5, 1n); + assert.equal(x6, 1n); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/nonce-checks/rerun-with-pending-ignition-transactions.ts b/packages/hardhat-ignition/test/deploy/nonce-checks/rerun-with-pending-ignition-transactions.ts new file mode 100644 index 0000000000..261a7d0123 --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/nonce-checks/rerun-with-pending-ignition-transactions.ts @@ -0,0 +1,102 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { + TestChainHelper, + useFileIgnitionProject, +} from "../../test-helpers/use-ignition-project"; + +/** + * Run an initial deploy, that starts but does not finish several on-chain + * transactions via Ignition. Perform another run picking the deployment + * up where the first run left off and without any other user transactions. + */ +describe("execution - rerun with pending ignition transactions", () => { + useFileIgnitionProject("minimal", "rerun-with-pending-ignition-transactions"); + + it("should complete the run on the second attempt", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const account2 = m.getAccount(2); + + // batch 1 + const foo1 = m.contract("Foo", [], { id: "Foo1", from: account2 }); + const foo2 = m.contract("Foo", [], { id: "Foo2", from: account2 }); + + // batch 2 + const foo3 = m.contract("Foo", [], { + id: "Foo3", + from: account2, + after: [foo1], + }); + const foo4 = m.contract("Foo", [], { + id: "Foo4", + from: account2, + after: [foo2], + }); + + // batch 3 + const foo5 = m.contract("Foo", [], { + id: "Foo5", + from: account2, + after: [foo3], + }); + const foo6 = m.contract("Foo", [], { + id: "Foo6", + from: account2, + after: [foo4], + }); + + return { + foo1, + foo2, + foo3, + foo4, + foo5, + foo6, + }; + }); + + await this.runControlledDeploy( + moduleDefinition, + async (c: TestChainHelper) => { + // Process the first block, include foo1 and foo2 + await c.mineBlock(2); + + // Kill the deployment, with foo3 and foo4 submitted to mempool + await c.waitForPendingTxs(2); + c.exitDeploy(); + } + ); + + // NOTE: no blocks mined between previous run and this run + // there should two deploy contract transactions for foo3 and foo4 + // in the mempool + const result = await this.runControlledDeploy( + moduleDefinition, + async (c: TestChainHelper) => { + // this block should confirm foo3 and foo4 + await c.mineBlock(2); + + // this block shound include foo5 and foo6 + await c.mineBlock(2); + } + ); + + assert.isDefined(result); + + const x1 = await result.foo1.read.x(); + const x2 = await result.foo2.read.x(); + const x3 = await result.foo3.read.x(); + const x4 = await result.foo4.read.x(); + const x5 = await result.foo5.read.x(); + const x6 = await result.foo6.read.x(); + + assert.equal(x1, 1n); + assert.equal(x2, 1n); + assert.equal(x3, 1n); + assert.equal(x4, 1n); + assert.equal(x5, 1n); + assert.equal(x6, 1n); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/nonce-checks/rerun-with-replaced-confirmed-user-transaction.ts b/packages/hardhat-ignition/test/deploy/nonce-checks/rerun-with-replaced-confirmed-user-transaction.ts new file mode 100644 index 0000000000..5d5b00e8fd --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/nonce-checks/rerun-with-replaced-confirmed-user-transaction.ts @@ -0,0 +1,104 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; +import { createWalletClient, custom, parseEther } from "viem"; +import { hardhat } from "viem/chains"; + +import { mineBlock } from "../../test-helpers/mine-block"; +import { sleep } from "../../test-helpers/sleep"; +import { + TestChainHelper, + useFileIgnitionProject, +} from "../../test-helpers/use-ignition-project"; + +/** + * Run an initial deploy, that starts but does not finish several on-chain + * transactions via Ignition. The user then replaces a transaction by + * reusing a nonce with a higher gas value. The user submitted transaction + * confirms between runs. On the rerun we should we should resubmit + * the original transaction with a new nonce. + */ +describe("execution - rerun with replaced confirmed user transaction", () => { + useFileIgnitionProject( + "minimal", + "rerun-with-replaced-confirmed-user-transaction", + { + requiredConfirmations: 2, + } + ); + + it.skip("should deploy user interfered transaction on second run", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const account2 = m.getAccount(2); + + // batch 1 + const foo1 = m.contract("Foo", [], { id: "Foo1", from: account2 }); + const foo2 = m.contract("Foo", [], { id: "Foo2", from: account2 }); + const foo3 = m.contract("Foo", [], { id: "Foo3", from: account2 }); + + return { + foo1, + foo2, + foo3, + }; + }); + + // First run fo the deploy + await this.runControlledDeploy( + moduleDefinition, + async (c: TestChainHelper) => { + // Wait for the submission of foo1 foo2 and foo3 to mempool, + // then kill the deploy process + await c.waitForPendingTxs(3); + c.exitDeploy(); + } + ); + + const FooArtifact = this.hre.artifacts.readArtifactSync("Foo"); + + // Submit a user interfering deploy transaction + // to the mempool reusing nonce 2 + const [, , signer2] = (await this.hre.network.provider.request({ + method: "eth_accounts", + })) as string[]; + + const walletClient = createWalletClient({ + chain: hardhat, + transport: custom(this.hre.network.provider), + }); + + const deployPromise = walletClient.deployContract({ + abi: FooArtifact.abi, + bytecode: FooArtifact.bytecode as `0x${string}`, + args: [], + account: signer2 as `0x${string}`, + gasPrice: parseEther("500", "gwei"), + nonce: 2, + }); + + // mine a block confirming foo1, foo2, and the user provided transaction + // foo3 is no longer in the mempool + await sleep(300); + await mineBlock(this.hre); + + // Rerun the deployment with foo3 replaced, causing it to + // be resubmitted + const result = await this.runControlledDeploy( + moduleDefinition, + async (c: TestChainHelper) => { + // this block should confirm foo3 + await c.mineBlock(1); + } + ); + + assert.isDefined(result); + + assert.equal(await result.foo1.read.x(), 1n); + assert.equal(await result.foo2.read.x(), 1n); + assert.equal(await result.foo3.read.x(), 1n); + + // the user deployed contract is working as well + const userDeployed = await deployPromise; + assert(userDeployed); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/nonce-checks/revert-nonce-on-simulation-error.ts b/packages/hardhat-ignition/test/deploy/nonce-checks/revert-nonce-on-simulation-error.ts new file mode 100644 index 0000000000..3e9284efc3 --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/nonce-checks/revert-nonce-on-simulation-error.ts @@ -0,0 +1,36 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { useEphemeralIgnitionProject } from "../../test-helpers/use-ignition-project"; + +/** + * On running a deploy, if a transaction fails simulation, we should + * revert the allocated nonce and complete the rest of the batch. + * + * This test ensures that the nonce is reverted and the rest of the batch completes + * because the second transaction does not fail the nonce check. + */ +describe("execution - revert nonce on simulation error", () => { + useEphemeralIgnitionProject("minimal"); + + it("should raise the simulation error if there are multiple transactions in a batch and fails simulation", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + // batch 1 + const foo = m.contract("FailureCalls"); + + // batch 2 + m.call(foo, "fails"); + m.call(foo, "doesNotFail"); + + return { foo }; + }); + + // We check that it doesn't fail because of a nonce validation, + // but because of the actual simulation + await assert.isRejected( + this.hre.ignition.deploy(moduleDefinition), + /Simulating the transaction failed with error: Reverted with reason "fails"/ + ); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/rerun/rerun-a-deploy-that-timed-out.ts b/packages/hardhat-ignition/test/deploy/rerun/rerun-a-deploy-that-timed-out.ts new file mode 100644 index 0000000000..122c8dfb19 --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/rerun/rerun-a-deploy-that-timed-out.ts @@ -0,0 +1,127 @@ +/* eslint-disable import/no-unused-modules */ +import { setNextBlockBaseFeePerGas } from "@nomicfoundation/hardhat-network-helpers"; +import { buildModule, wipe } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { HardhatArtifactResolver } from "../../../src/hardhat-artifact-resolver"; +import { mineBlock } from "../../test-helpers/mine-block"; +import { + TestChainHelper, + useFileIgnitionProject, +} from "../../test-helpers/use-ignition-project"; + +/** + * A run that deploys a contract times out + * + * TODO: Needs to be updated to deal with fee bumps + */ +describe("execution - rerun a deploy that timed out", () => { + useFileIgnitionProject("minimal", "rerun-a-deploy-that-timed-out", { + blockPollingInterval: 50, + timeBeforeBumpingFees: 45, + maxFeeBumps: 2, + requiredConfirmations: 1, + }); + + it("shows an error indicating a wipe is required", async function () { + // Setup a module with a contract deploy on accounts[2] + const moduleDefinition = buildModule("FooModule", (m) => { + const account2 = m.getAccount(2); + + const foo = m.contract("Foo", [], { from: account2 }); + + return { + foo, + }; + }); + + // Deploying the module that uses accounts[2], but force timeout, + // by not processing any blocks + await assert.isRejected( + this.runControlledDeploy(moduleDefinition, async (c: TestChainHelper) => { + // wait for the deploy transaction to hit the memory pool, + // but then never mine the block that will complete it. + await c.waitForPendingTxs(1); + await setNextBlockBaseFeePerGas(10_000_000_000n); + await c.mineBlock(); + + await c.waitForPendingTxs(1); + await setNextBlockBaseFeePerGas(100_000_000_000n); + await c.mineBlock(); + + await c.waitForPendingTxs(1); + await setNextBlockBaseFeePerGas(1_000_000_000_000n); + await c.mineBlock(); + }) + ); + + await assert.isRejected( + this.runControlledDeploy(moduleDefinition, async (c: TestChainHelper) => { + // Mine the block, confirming foo + await c.mineBlock(1); + }), + `The deployment wasn\'t run because of the following errors in a previous run: + + * FooModule#Foo: The previous run of the future FooModule#Foo timed out, and will need wiped before running again` + ); + }); + + /** + * Perform a run that times out by manipulating the base fee. Reset the base fee + * and wipe the future, the run again. + * + * A new second transaction is submitted that succeeds. + */ + it("should successfully rerun after a timeout (and a wipe)", async function () { + // Setup a module with a contract deploy on accounts[2] + const moduleDefinition = buildModule("FooModule", (m) => { + const account2 = m.getAccount(2); + + const foo = m.contract("Foo", [], { from: account2 }); + + return { + foo, + }; + }); + + // Deploying the module that uses accounts[2], but force timeout, + // by not processing any blocks + await assert.isRejected( + this.runControlledDeploy(moduleDefinition, async (c: TestChainHelper) => { + // wait for the deploy transaction to hit the memory pool, + // but then never mine the block that will complete it. + await c.waitForPendingTxs(1); + await setNextBlockBaseFeePerGas(10_000_000_000n); + await c.mineBlock(); + + await c.waitForPendingTxs(1); + await setNextBlockBaseFeePerGas(100_000_000_000n); + await c.mineBlock(); + + await c.waitForPendingTxs(1); + await setNextBlockBaseFeePerGas(1_000_000_000_000n); + await c.mineBlock(); + }) + ); + + await setNextBlockBaseFeePerGas(1_000_000n); + await mineBlock(this.hre); + + await wipe( + this.deploymentDir!, + new HardhatArtifactResolver(this.hre), + "FooModule#Foo" + ); + + const result = await this.runControlledDeploy( + moduleDefinition, + async (c: TestChainHelper) => { + // Mine the block, confirming foo + await c.mineBlock(1); + } + ); + + assert.isDefined(result); + assert.equal(await result.foo.read.x(), 1n); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/rerun/rerun-after-kill.ts b/packages/hardhat-ignition/test/deploy/rerun/rerun-after-kill.ts new file mode 100644 index 0000000000..01c04dc57d --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/rerun/rerun-after-kill.ts @@ -0,0 +1,70 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { + TestChainHelper, + useFileIgnitionProject, +} from "../../test-helpers/use-ignition-project"; + +/** + * Run an initial deploy that deploys multiple contracts, one contract per batch. + * Kill the process on the first transaction being submitted. + * Restart the deployment and ensure that the deployment is completed with + * all contracts deployed. + * + * This covers a bug in the nonce mangement code: see #576 + */ +describe("execution - rerun after kill", function () { + this.timeout(60000); + + useFileIgnitionProject("minimal", "rerun-after-kill"); + + it("should pickup deployment and run contracts to completion", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const foo1 = m.contract("Foo", [], { id: "foo1" }); + const foo2 = m.contract("Foo", [], { id: "foo2" }); + const foo3 = m.contract("Foo", [], { id: "foo3" }); + const foo4 = m.contract("Foo", [], { id: "foo4" }); + const foo5 = m.contract("Foo", [], { id: "foo5" }); + + return { + foo1, + foo2, + foo3, + foo4, + foo5, + }; + }); + + // Start the deploy + await this.runControlledDeploy( + moduleDefinition, + async (c: TestChainHelper) => { + // this block shound include deployment of foo1 + await c.waitForPendingTxs(1); + + c.exitDeploy(); + } + ); + + // Rerun the deployment + const result = await this.runControlledDeploy( + moduleDefinition, + async (c: TestChainHelper) => { + // this block shound include deployment of foo2 + await c.mineBlock(1); + await c.mineBlock(1); + await c.mineBlock(1); + await c.mineBlock(1); + await c.mineBlock(1); + } + ); + + assert.equal(await result.foo1.read.x(), 1n); + assert.equal(await result.foo2.read.x(), 1n); + assert.equal(await result.foo3.read.x(), 1n); + assert.equal(await result.foo4.read.x(), 1n); + assert.equal(await result.foo5.read.x(), 1n); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/rerun/rerun-with-new-contract-deploy.ts b/packages/hardhat-ignition/test/deploy/rerun/rerun-with-new-contract-deploy.ts new file mode 100644 index 0000000000..323633f64a --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/rerun/rerun-with-new-contract-deploy.ts @@ -0,0 +1,73 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { mineBlock } from "../../test-helpers/mine-block"; +import { + TestChainHelper, + useFileIgnitionProject, +} from "../../test-helpers/use-ignition-project"; + +/** + * Run an initial deploy, that deploys a contract. The module is modified + * to add an additional dependent contract. On the second run only one contract + * is deployed. + */ +describe("execution - rerun with new contract deploy", () => { + useFileIgnitionProject("minimal", "rerun-with-new-contract-deploy"); + + it("should deploy only one contract on second run", async function () { + const moduleDefinition = buildModule("BarModule", (m) => { + const bar = m.contract("Bar"); + + return { + bar, + }; + }); + + // Start the deploy + const { bar: originalBar } = await this.runControlledDeploy( + moduleDefinition, + async (c: TestChainHelper) => { + // this block shound include deployment of foo1 + await c.mineBlock(1); + } + ); + + const firstRunBarAddress = originalBar.address.toLowerCase(); + + // Further blocks with no pending transactions + await mineBlock(this.hre); + await mineBlock(this.hre); + + const updatedModuleDefinition = buildModule("BarModule", (m) => { + const bar = m.contract("Bar"); + const usesContract = m.contract("UsesContract", [bar]); + + return { + bar, + usesContract, + }; + }); + + // Rerun the deployment + const result = await this.runControlledDeploy( + updatedModuleDefinition, + async (c: TestChainHelper) => { + // this block shound include deployment of foo2 + await c.mineBlock(1); + } + ); + + const usedAddress = ( + (await result.usesContract.read.contractAddress()) as string + ).toLowerCase(); + + const secondRunBarAddress = result.bar.address.toLowerCase(); + + // The BarModule#Bar contract has not been redeployed if + // it shares the same address. + assert.equal(firstRunBarAddress, secondRunBarAddress); + assert.equal(usedAddress, secondRunBarAddress); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/reset.ts b/packages/hardhat-ignition/test/deploy/reset.ts new file mode 100644 index 0000000000..2615060f12 --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/reset.ts @@ -0,0 +1,42 @@ +import { status } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { HardhatArtifactResolver } from "../../src/hardhat-artifact-resolver"; +import { useFileIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("reset flag", function () { + useFileIgnitionProject("reset-flag", "custom-reset-id"); + + it("should reset a deployment", async function () { + this.hre.network.name = "something-else"; + + await this.hre.run( + { scope: "ignition", task: "deploy" }, + { + modulePath: "./ignition/modules/FirstPass.js", + deploymentId: "custom-reset-id", + reset: true, + } + ); + + await this.hre.run( + { scope: "ignition", task: "deploy" }, + { + modulePath: "./ignition/modules/SecondPass.js", + deploymentId: "custom-reset-id", + reset: true, + } + ); + + const artifactResolver = new HardhatArtifactResolver(this.hre); + const result = await status(this.deploymentDir!, artifactResolver); + + // ResetModule#B will only be in the success list if the second + // run ran without any reconciliation errors - so the retry + // cleared the first pass + assert( + result.successful.includes("ResetModule#B"), + "Retry did not clear first pass, so second pass failed" + ); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/timeouts/deploy-run-times-out.ts b/packages/hardhat-ignition/test/deploy/timeouts/deploy-run-times-out.ts new file mode 100644 index 0000000000..86391e3898 --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/timeouts/deploy-run-times-out.ts @@ -0,0 +1,55 @@ +/* eslint-disable import/no-unused-modules */ +import { setNextBlockBaseFeePerGas } from "@nomicfoundation/hardhat-network-helpers"; +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { + TestChainHelper, + useFileIgnitionProject, +} from "../../test-helpers/use-ignition-project"; + +/** + * A run that deploys a contract times out + */ +describe("execution - deploy run times out", () => { + useFileIgnitionProject("minimal", "deploy-run-times-out", { + blockPollingInterval: 50, + timeBeforeBumpingFees: 45, + maxFeeBumps: 2, + requiredConfirmations: 1, + }); + + it("should error naming timed out transactions", async function () { + // Setup a module with a contract deploy on accounts[2] + const moduleDefinition = buildModule("FooModule", (m) => { + const account2 = m.getAccount(2); + + const foo = m.contract("Foo", [], { from: account2 }); + + return { + foo, + }; + }); + + // Deploying the module that uses accounts[2] throws with a warning + await assert.isRejected( + this.runControlledDeploy(moduleDefinition, async (c: TestChainHelper) => { + // wait for the deploy transaction to hit the memory pool, + // but then bump the base fee so that it doesn't get mined, + // with the next block + await c.waitForPendingTxs(1); + await setNextBlockBaseFeePerGas(10_000_000_000n); + await c.mineBlock(); + + await c.waitForPendingTxs(1); + await setNextBlockBaseFeePerGas(100_000_000_000n); + await c.mineBlock(); + + await c.waitForPendingTxs(1); + await setNextBlockBaseFeePerGas(1_000_000_000_000n); + await c.mineBlock(); + }), + "The deployment wasn't successful, there were timeouts:\n\nTimed out:\n\n * FooModule#Foo/1" + ); + }); +}); diff --git a/packages/hardhat-ignition/test/deploy/writeLocalhost.ts b/packages/hardhat-ignition/test/deploy/writeLocalhost.ts new file mode 100644 index 0000000000..1d64e03b56 --- /dev/null +++ b/packages/hardhat-ignition/test/deploy/writeLocalhost.ts @@ -0,0 +1,55 @@ +import { assert } from "chai"; +import { pathExists, removeSync } from "fs-extra"; +import path from "path"; + +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +const fixtureProjectName = "minimal"; +const deploymentDir = path.join( + path.resolve(__dirname, `../fixture-projects/${fixtureProjectName}/ignition`), + "deployments", + "chain-31337" +); + +describe("localhost deployment flag", function () { + useEphemeralIgnitionProject(fixtureProjectName); + + beforeEach("clean filesystem", async function () { + // make sure nothing is left over from a previous test + removeSync(deploymentDir); + }); + afterEach("clean filesystem", function () { + // cleanup + removeSync(deploymentDir); + }); + + it("true should write deployment to disk", async function () { + await this.hre.run( + { scope: "ignition", task: "deploy" }, + { + modulePath: "./ignition/modules/OwnModule.js", + writeLocalhostDeployment: true, + } + ); + + assert( + await pathExists(deploymentDir), + "Deployment was not written to disk" + ); + }); + + it("false should not write deployment to disk", async function () { + await this.hre.run( + { scope: "ignition", task: "deploy" }, + { + modulePath: "./ignition/modules/OwnModule.js", + writeLocalhostDeployment: false, + } + ); + + assert( + !(await pathExists(deploymentDir)), + "Deployment was not written to disk" + ); + }); +}); diff --git a/packages/hardhat-ignition/test/fixture-projects/.gitignore b/packages/hardhat-ignition/test/fixture-projects/.gitignore new file mode 100644 index 0000000000..f1462f7a56 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/.gitignore @@ -0,0 +1,3 @@ +artifacts/ +cache/ +deployments/ diff --git a/packages/hardhat-ignition/test/fixture-projects/create2-bad-config/contracts/Foo.sol b/packages/hardhat-ignition/test/fixture-projects/create2-bad-config/contracts/Foo.sol new file mode 100644 index 0000000000..33c8ffdf30 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/create2-bad-config/contracts/Foo.sol @@ -0,0 +1,7 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +contract Foo { + bool public isFoo = true; +} diff --git a/packages/hardhat-ignition/test/fixture-projects/create2-bad-config/hardhat.config.js b/packages/hardhat-ignition/test/fixture-projects/create2-bad-config/hardhat.config.js new file mode 100644 index 0000000000..bb4b83c260 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/create2-bad-config/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../src/index"); + +/** + * @type import('hardhat/config').HardhatUserConfig + */ +module.exports = { + solidity: "0.8.19", + ignition: { + strategyConfig: { + create2: { + salt: undefined, // Missing salt + }, + }, + }, +}; diff --git a/packages/hardhat-ignition/test/fixture-projects/create2-bad-config/ignition/modules/MyModule.js b/packages/hardhat-ignition/test/fixture-projects/create2-bad-config/ignition/modules/MyModule.js new file mode 100644 index 0000000000..88f3faf68d --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/create2-bad-config/ignition/modules/MyModule.js @@ -0,0 +1,7 @@ +const { buildModule } = require("@nomicfoundation/ignition-core"); + +module.exports = buildModule("MyModule", (m) => { + const foo = m.contract("Foo"); + + return { foo }; +}); diff --git a/packages/hardhat-ignition/test/fixture-projects/create2-exists-chain/contracts/Foo.sol b/packages/hardhat-ignition/test/fixture-projects/create2-exists-chain/contracts/Foo.sol new file mode 100644 index 0000000000..821ff9cd70 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/create2-exists-chain/contracts/Foo.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +contract Foo { + bool public isFoo = true; + uint256 public x = 1; + + constructor() payable {} + + function inc() public { + x++; + } + + function incByPositiveNumber(uint256 n) public { + require(n > 0, "n must be positive"); + x += n; + } + + function incTwoNumbers(uint256 first, uint256 second) public { + x += first; + x += second; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/create2-exists-chain/contracts/Unpayable.sol b/packages/hardhat-ignition/test/fixture-projects/create2-exists-chain/contracts/Unpayable.sol new file mode 100644 index 0000000000..d038ce117b --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/create2-exists-chain/contracts/Unpayable.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +contract Unpayable { + bool public isUnpayable = true; + + // intentionally not payable + constructor() {} +} diff --git a/packages/hardhat-ignition/test/fixture-projects/create2-exists-chain/hardhat.config.js b/packages/hardhat-ignition/test/fixture-projects/create2-exists-chain/hardhat.config.js new file mode 100644 index 0000000000..4b67cc0a66 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/create2-exists-chain/hardhat.config.js @@ -0,0 +1,16 @@ +require("../../../src/index"); + +/** + * @type import('hardhat/config').HardhatUserConfig + */ +module.exports = { + solidity: "0.8.19", + networks: { + hardhat: { + mining: { + auto: false, + }, + chainId: 1, + }, + }, +}; diff --git a/packages/hardhat-ignition/test/fixture-projects/create2-exists-chain/ignition/modules/MyModule.js b/packages/hardhat-ignition/test/fixture-projects/create2-exists-chain/ignition/modules/MyModule.js new file mode 100644 index 0000000000..11dd2c6589 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/create2-exists-chain/ignition/modules/MyModule.js @@ -0,0 +1,8 @@ +// eslint-disable-next-line import/no-unused-modules +const { buildModule } = require("@nomicfoundation/ignition-core"); + +module.exports = buildModule("MyModule", (m) => { + const foo = m.contract("Foo"); + + return { foo }; +}); diff --git a/packages/hardhat-ignition/test/fixture-projects/create2-not-exists-chain/contracts/Foo.sol b/packages/hardhat-ignition/test/fixture-projects/create2-not-exists-chain/contracts/Foo.sol new file mode 100644 index 0000000000..992dab4f1d --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/create2-not-exists-chain/contracts/Foo.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +contract Foo { + bool public isFoo = true; + uint256 public x = 1; + + function inc() public { + x++; + } + + function incByPositiveNumber(uint256 n) public { + require(n > 0, "n must be positive"); + x += n; + } + + function incTwoNumbers(uint256 first, uint256 second) public { + x += first; + x += second; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/create2-not-exists-chain/hardhat.config.js b/packages/hardhat-ignition/test/fixture-projects/create2-not-exists-chain/hardhat.config.js new file mode 100644 index 0000000000..186e6f152e --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/create2-not-exists-chain/hardhat.config.js @@ -0,0 +1,16 @@ +require("../../../src/index"); + +/** + * @type import('hardhat/config').HardhatUserConfig + */ +module.exports = { + solidity: "0.8.19", + networks: { + hardhat: { + mining: { + auto: false, + }, + chainId: 88888, + }, + }, +}; diff --git a/packages/hardhat-ignition/test/fixture-projects/create2-not-exists-chain/ignition/modules/MyModule.js b/packages/hardhat-ignition/test/fixture-projects/create2-not-exists-chain/ignition/modules/MyModule.js new file mode 100644 index 0000000000..11dd2c6589 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/create2-not-exists-chain/ignition/modules/MyModule.js @@ -0,0 +1,8 @@ +// eslint-disable-next-line import/no-unused-modules +const { buildModule } = require("@nomicfoundation/ignition-core"); + +module.exports = buildModule("MyModule", (m) => { + const foo = m.contract("Foo"); + + return { foo }; +}); diff --git a/packages/hardhat-ignition/test/fixture-projects/index-pattern-success/contracts/Test.sol b/packages/hardhat-ignition/test/fixture-projects/index-pattern-success/contracts/Test.sol new file mode 100644 index 0000000000..0e799e88d1 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/index-pattern-success/contracts/Test.sol @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.9; + +contract F1 { + bool public firstCalled; + bool public secondCalled; + bool public thirdCalled; + + address public caller1; + address public caller2; + + function first() public { + firstCalled = true; + } + + function second() public { + require(firstCalled, "first() was not called"); + require(!thirdCalled, "third() was called"); + + secondCalled = true; + } + + function third() public { + require(firstCalled, "first() was not called"); + require(secondCalled, "second() was not called"); + + thirdCalled = true; + } + + function mustBeCalledByTwoSeparateContracts() public { + if (caller1 == address(0)) { + caller1 = msg.sender; + } else { + caller2 = msg.sender; + } + } + + function throwsIfNotCalledTwice() public view { + require(caller1 != address(0) && caller2 != address(0) && caller1 != caller2, "was not called by two separate contracts"); + } +} + +contract F2 { + + F1 public f1; + + uint public counter; + + constructor(F1 _f1) { + f1 = _f1; + } + + function second() public { + f1.second(); + } + + function mustBeCalledByTwoSeparateContracts() public { + f1.mustBeCalledByTwoSeparateContracts(); + } + + function unrelatedFunc() public { + counter++; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/index-pattern-success/hardhat.config.js b/packages/hardhat-ignition/test/fixture-projects/index-pattern-success/hardhat.config.js new file mode 100644 index 0000000000..c76e2c9b8d --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/index-pattern-success/hardhat.config.js @@ -0,0 +1,14 @@ +require("@nomicfoundation/hardhat-ignition"); + +/** @type import('hardhat/config').HardhatUserConfig */ +module.exports = { + solidity: { + version: "0.8.19", + settings: { + metadata: { + // We disable the metadata to keep the fixtures more stables + appendCBOR: false, + }, + }, + }, +}; diff --git a/packages/hardhat-ignition/test/fixture-projects/index-pattern-success/ignition/modules/MyModule.js b/packages/hardhat-ignition/test/fixture-projects/index-pattern-success/ignition/modules/MyModule.js new file mode 100644 index 0000000000..11dd2c6589 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/index-pattern-success/ignition/modules/MyModule.js @@ -0,0 +1,8 @@ +// eslint-disable-next-line import/no-unused-modules +const { buildModule } = require("@nomicfoundation/ignition-core"); + +module.exports = buildModule("MyModule", (m) => { + const foo = m.contract("Foo"); + + return { foo }; +}); diff --git a/packages/hardhat-ignition/test/fixture-projects/lock/contracts/Lock.sol b/packages/hardhat-ignition/test/fixture-projects/lock/contracts/Lock.sol new file mode 100644 index 0000000000..122a274464 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/lock/contracts/Lock.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.9; + +// Uncomment this line to use console.log +// import "hardhat/console.sol"; + +contract Lock { + uint public unlockTime; + address payable public owner; + + event Withdrawal(uint amount, uint when); + + constructor(uint _unlockTime) payable { + require( + block.timestamp < _unlockTime, + "Unlock time should be in the future" + ); + + unlockTime = _unlockTime; + owner = payable(msg.sender); + } + + function test() public { + emit Withdrawal(address(this).balance, block.timestamp); + } + + function withdraw() public { + // Uncomment this line, and the import of "hardhat/console.sol", to print a log in your terminal + // console.log("Unlock time is %o and block timestamp is %o", unlockTime, block.timestamp); + + require(block.timestamp >= unlockTime, "You can't withdraw yet"); + require(msg.sender == owner, "You aren't the owner"); + + emit Withdrawal(address(this).balance, block.timestamp); + + owner.transfer(address(this).balance); + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/lock/hardhat.config.js b/packages/hardhat-ignition/test/fixture-projects/lock/hardhat.config.js new file mode 100644 index 0000000000..791b28f337 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/lock/hardhat.config.js @@ -0,0 +1,12 @@ +require("../../../src/index"); + +module.exports = { + solidity: "0.8.19", + networks: { + hardhat: { + mining: { + auto: false, + }, + }, + }, +}; diff --git a/packages/hardhat-ignition/test/fixture-projects/lock/ignition/modules/Lock.ts b/packages/hardhat-ignition/test/fixture-projects/lock/ignition/modules/Lock.ts new file mode 100644 index 0000000000..8b88fea646 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/lock/ignition/modules/Lock.ts @@ -0,0 +1,15 @@ +import { buildModule } from "@nomicfoundation/ignition-core"; + +const LockModule = buildModule("LockModule", (m) => { + const unlockTime = m.getParameter("unlockTime"); + const lockedAmount = m.getParameter("lockedAmount", 1_000_000_000n); + + const lock = m.contract("Lock", [unlockTime], { + value: lockedAmount, + }); + + return { lock }; +}); + +// eslint-disable-next-line import/no-default-export +export default LockModule; diff --git a/packages/hardhat-ignition/test/fixture-projects/lock/ignition/modules/parameters-bigints-as-strings.json b/packages/hardhat-ignition/test/fixture-projects/lock/ignition/modules/parameters-bigints-as-strings.json new file mode 100644 index 0000000000..f84de04388 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/lock/ignition/modules/parameters-bigints-as-strings.json @@ -0,0 +1,6 @@ +{ + "LockModule": { + "unlockTime": "1893499200000n", + "lockedAmount": "2000000000000n" + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/lock/ignition/modules/parameters-json5.json5 b/packages/hardhat-ignition/test/fixture-projects/lock/ignition/modules/parameters-json5.json5 new file mode 100644 index 0000000000..6a57f6c034 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/lock/ignition/modules/parameters-json5.json5 @@ -0,0 +1,16 @@ +/** + * comments allowed in json5 + */ + +{ + // no quotes around keys + LockModule: { + // weird multi-line but should pass + unlockTime: "1\ +893\ +499\ +200\ +000n", + lockedAmount: "2000000000000n", + }, +} diff --git a/packages/hardhat-ignition/test/fixture-projects/lock/ignition/modules/parameters-too-large.json b/packages/hardhat-ignition/test/fixture-projects/lock/ignition/modules/parameters-too-large.json new file mode 100644 index 0000000000..0fe07f2b2a --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/lock/ignition/modules/parameters-too-large.json @@ -0,0 +1,5 @@ +{ + "LockModule": { + "unlockTime": 1893499200000000000 + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/lock/ignition/modules/parameters.json b/packages/hardhat-ignition/test/fixture-projects/lock/ignition/modules/parameters.json new file mode 100644 index 0000000000..914e9c7c4e --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/lock/ignition/modules/parameters.json @@ -0,0 +1,5 @@ +{ + "LockModule": { + "unlockTime": 1893499200000 + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Bar.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Bar.sol new file mode 100644 index 0000000000..1ee84c4f40 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Bar.sol @@ -0,0 +1,6 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract Bar { + bool public isBar = true; +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/CaptureArraysContract.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/CaptureArraysContract.sol new file mode 100644 index 0000000000..7cc2e4871f --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/CaptureArraysContract.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +contract CaptureArraysContract { + bool public arraysCaptured; + + constructor() { + arraysCaptured = false; + } + + function recordArrays( + uint256[] memory first, + string[] memory second, + bool[] memory third + ) public returns (uint256 output) { + arraysCaptured = true; + + require(first.length == 3, "Wrong number of args on first arg"); + require(first[0] == 1, "First value is wrong"); + require(first[1] == 2, "Second value is wrong"); + require(first[2] == 3, "Third value is wrong"); + + require(second.length == 3, "Wrong number of args on second arg"); + require( + keccak256(abi.encodePacked(second[0])) == + keccak256(abi.encodePacked("a")), + "First value is wrong" + ); + require( + keccak256(abi.encodePacked(second[1])) == + keccak256(abi.encodePacked("b")), + "Second value is wrong" + ); + require( + keccak256(abi.encodePacked(second[2])) == + keccak256(abi.encodePacked("c")), + "Third value is wrong" + ); + + require(third.length == 3, "Wrong number of args on third arg"); + require(third[0] == true, "First value is wrong"); + require(third[1] == false, "Second value is wrong"); + require(third[2] == true, "Third value is wrong"); + + return 1; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/CaptureComplexObjectContract.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/CaptureComplexObjectContract.sol new file mode 100644 index 0000000000..698c71207f --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/CaptureComplexObjectContract.sol @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +contract CaptureComplexObjectContract { + bool public complexArgCaptured; + + constructor() { + complexArgCaptured = false; + } + + struct SubComplex { + string sub; + } + + struct Complex { + bool firstBool; + uint256[] secondArray; + SubComplex thirdSubcomplex; + } + + function testComplexObject( + Complex memory complexArg + ) public returns (uint256 output) { + complexArgCaptured = true; + + require(complexArg.firstBool, "bad first bool"); + + require(complexArg.secondArray.length == 3, "bad second array"); + require(complexArg.secondArray[0] == 1, "First value is wrong"); + require(complexArg.secondArray[1] == 2, "Second value is wrong"); + require(complexArg.secondArray[2] == 3, "Third value is wrong"); + + require( + keccak256(abi.encodePacked(complexArg.thirdSubcomplex.sub)) == + keccak256(abi.encodePacked("sub")), + "The complex sub object property is wrong" + ); + + return 1; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/EventArgValue.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/EventArgValue.sol new file mode 100644 index 0000000000..11bdb0a6ce --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/EventArgValue.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract EventArgValue { + event EventValue(uint256 value); + + bool public argWasValidated; + + constructor() { + emit EventValue(42); + } + + function validateEmitted(uint256 arg) public { + argWasValidated = true; + + require(arg == 42, "arg is wrong"); + } +} + +contract PassingValue { + constructor() payable {} + + function deposit() public payable {} +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Factory.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Factory.sol new file mode 100644 index 0000000000..c5d27b1d5b --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Factory.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +import "./Foo.sol"; + +contract FooFactory { + event Deployed(address indexed fooAddress); + + address public deployed; + address[] public allDeployed; + + bool public nonAddressResult; + + function create() public { + Foo foo = new Foo(); + + deployed = address(foo); + allDeployed.push(address(foo)); + + emit Deployed(address(foo)); + } + + function isDeployed() public pure returns (bool output) { + return true; + } + + function getDeployed() public view returns (address output) { + return allDeployed[0]; + } + + function getDeployed(uint256 value) public view returns (address output) { + return allDeployed[value]; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Fails.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Fails.sol new file mode 100644 index 0000000000..60f8354fdc --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Fails.sol @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; +pragma experimental ABIEncoderV2; + +contract Fails { + constructor() { + revert("Constructor failed"); + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/FailureCalls.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/FailureCalls.sol new file mode 100644 index 0000000000..9db5e14ac0 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/FailureCalls.sol @@ -0,0 +1,16 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract FailureCalls { + bool public success; + + function fails() public { + success = false; + revert("fails"); + } + + function doesNotFail() public { + // modify the state so the function isn't pure/view + success = true; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Foo.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Foo.sol new file mode 100644 index 0000000000..197a16b176 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Foo.sol @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract Foo { + bool public isFoo = true; + uint256 public x = 1; + + function inc() public { + x++; + } + + function incByPositiveNumber(uint256 n) public { + require(n > 0, "n must be positive"); + x += n; + } + + function incTwoNumbers(uint256 first, uint256 second) public { + x += first; + x += second; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Greeter.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Greeter.sol new file mode 100644 index 0000000000..ac1942abe4 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Greeter.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract Greeter { + string private _greeting; + + constructor(string memory greeting) { + _greeting = greeting; + } + + function getGreeting() public view returns (string memory) { + return _greeting; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Ownable.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Ownable.sol new file mode 100644 index 0000000000..7c4c829625 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Ownable.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract Ownable { + address public owner; + + constructor() { + owner = msg.sender; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Owner.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Owner.sol new file mode 100644 index 0000000000..67f06f801c --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Owner.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +contract Owner { + address public owner; + + constructor() { + owner = msg.sender; + } + + function setOwner(address _owner) public { + owner = _owner; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/SendDataEmitter.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/SendDataEmitter.sol new file mode 100644 index 0000000000..bf78a7361b --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/SendDataEmitter.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +contract SendDataEmitter { + event SendDataEvent(uint256 arg); + + bool public wasEmitted; + + receive() external payable { + emit SendDataEvent(42); + } + + function emitEvent() public { + emit SendDataEvent(42); + } + + function validateEmitted(uint256 arg) public { + wasEmitted = true; + + require(arg == 42, "arg is wrong"); + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/StaticCallValue.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/StaticCallValue.sol new file mode 100644 index 0000000000..11b5f3b1d0 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/StaticCallValue.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract StaticCallValue { + function getValue() public pure returns (uint256) { + return 42; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Trace.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Trace.sol new file mode 100644 index 0000000000..1687a1d485 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/Trace.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract Trace { + string[] public entries; + + constructor(string memory firstEntry) { + entries = [firstEntry]; + } + + function addEntry(string memory entry) public { + entries.push(entry); + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/TupleEmitter.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/TupleEmitter.sol new file mode 100644 index 0000000000..b9f98c5cb7 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/TupleEmitter.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +contract TupleEmitter { + bool public arg1Captured; + bool public arg2Captured; + + event TupleEvent(bool arg1, uint256 arg2); + + function emitTuple() public { + emit TupleEvent(true, 1234); + } + + function verifyArg1(bool arg) public returns (uint256 output) { + arg1Captured = true; + + require(arg == true, "arg1 is wrong"); + + return 1; + } + + function verifyArg2(uint256 arg) public returns (uint256 output) { + arg2Captured = true; + + require(arg == 1234, "arg2 is wrong"); + + return 1; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/TupleReturn.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/TupleReturn.sol new file mode 100644 index 0000000000..c7e224e6fc --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/TupleReturn.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +contract TupleReturn { + bool public arg1Captured; + bool public arg2Captured; + + function getTuple() public pure returns (bool arg1, uint256 arg2) { + return (true, 1234); + } + + function verifyArg1(bool arg) public returns (uint256 output) { + arg1Captured = true; + + require(arg == true, "arg1 is wrong"); + + return 1; + } + + function verifyArg2(uint256 arg) public returns (uint256 output) { + arg2Captured = true; + + require(arg == 1234, "arg2 is wrong"); + + return 1; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/UsesContract.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/UsesContract.sol new file mode 100644 index 0000000000..a1b14aabe2 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/UsesContract.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract UsesContract { + address public contractAddress; + + constructor(address _contract) { + contractAddress = _contract; + } + + function setAddress(address _contract) public { + contractAddress = _contract; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/WithLibrary.sol b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/WithLibrary.sol new file mode 100644 index 0000000000..3a1f0acd2a --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/contracts/WithLibrary.sol @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +library RubbishMath { + function add(uint16 left, uint16 right) public pure returns (uint16) { + return left + right; + } +} + +contract DependsOnLib { + function addThreeNumbers( + uint16 first, + uint16 second, + uint16 third + ) public pure returns (uint16) { + return RubbishMath.add(first, RubbishMath.add(second, third)); + } +} + +library LibDependsOnLib { + function add(uint16 left, uint16 right) public pure returns (uint16) { + return RubbishMath.add(left, right); + } +} + +contract DependsOnLibThatDependsOnLib { + function addThreeNumbers( + uint16 first, + uint16 second, + uint16 third + ) public pure returns (uint16) { + return LibDependsOnLib.add(first, LibDependsOnLib.add(second, third)); + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/hardhat.config.js b/packages/hardhat-ignition/test/fixture-projects/minimal/hardhat.config.js new file mode 100644 index 0000000000..791b28f337 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/hardhat.config.js @@ -0,0 +1,12 @@ +require("../../../src/index"); + +module.exports = { + solidity: "0.8.19", + networks: { + hardhat: { + mining: { + auto: false, + }, + }, + }, +}; diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/ignition/modules/MyModule.js b/packages/hardhat-ignition/test/fixture-projects/minimal/ignition/modules/MyModule.js new file mode 100644 index 0000000000..f00a750bde --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/ignition/modules/MyModule.js @@ -0,0 +1,13 @@ +// eslint-disable-next-line import/no-unused-modules +const { buildModule } = require("@nomicfoundation/ignition-core"); + +module.exports = buildModule("MyModule", (m) => { + const bar = m.contract("Bar"); + const usesContract = m.contract("UsesContract", [ + "0x0000000000000000000000000000000000000000", + ]); + + m.call(usesContract, "setAddress", [bar]); + + return { bar, usesContract }; +}); diff --git a/packages/hardhat-ignition/test/fixture-projects/minimal/ignition/modules/OwnModule.js b/packages/hardhat-ignition/test/fixture-projects/minimal/ignition/modules/OwnModule.js new file mode 100644 index 0000000000..b124b9d11f --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/minimal/ignition/modules/OwnModule.js @@ -0,0 +1,8 @@ +// eslint-disable-next-line import/no-unused-modules +const { buildModule } = require("@nomicfoundation/ignition-core"); + +module.exports = buildModule("OwnModule", (m) => { + const ownable = m.contract("Ownable"); + + return { ownable }; +}); diff --git a/packages/hardhat-ignition/test/fixture-projects/multiple-contracts-with-same-name/contracts/Rocket1.sol b/packages/hardhat-ignition/test/fixture-projects/multiple-contracts-with-same-name/contracts/Rocket1.sol new file mode 100644 index 0000000000..8b11e5648a --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/multiple-contracts-with-same-name/contracts/Rocket1.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +// This contract name is the same as in `./Rocket2.sol` +contract Rocket { + string public name; + + constructor(string memory _name) { + name = _name; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/multiple-contracts-with-same-name/contracts/Rocket2.sol b/packages/hardhat-ignition/test/fixture-projects/multiple-contracts-with-same-name/contracts/Rocket2.sol new file mode 100644 index 0000000000..e13358a6bc --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/multiple-contracts-with-same-name/contracts/Rocket2.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.0; + +// This contract name is the same as in `./Rocket1.sol` +contract Rocket { + string public name; + + constructor(string memory _name) { + name = _name; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/multiple-contracts-with-same-name/hardhat.config.js b/packages/hardhat-ignition/test/fixture-projects/multiple-contracts-with-same-name/hardhat.config.js new file mode 100644 index 0000000000..a59d1ed4d8 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/multiple-contracts-with-same-name/hardhat.config.js @@ -0,0 +1,5 @@ +require("../../../src/index"); + +module.exports = { + solidity: "0.8.19", +}; diff --git a/packages/hardhat-ignition/test/fixture-projects/reset-flag/contracts/Contracts.sol b/packages/hardhat-ignition/test/fixture-projects/reset-flag/contracts/Contracts.sol new file mode 100644 index 0000000000..c821b2d0d9 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/reset-flag/contracts/Contracts.sol @@ -0,0 +1,20 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.9; + +contract Foo { + function isFoo() public pure returns (bool) { + return true; + } +} + +contract Bar { + function isBar() public pure returns (bool) { + return true; + } +} + +contract Baz { + function isBaz() public pure returns (bool) { + return true; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/reset-flag/hardhat.config.js b/packages/hardhat-ignition/test/fixture-projects/reset-flag/hardhat.config.js new file mode 100644 index 0000000000..c76e2c9b8d --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/reset-flag/hardhat.config.js @@ -0,0 +1,14 @@ +require("@nomicfoundation/hardhat-ignition"); + +/** @type import('hardhat/config').HardhatUserConfig */ +module.exports = { + solidity: { + version: "0.8.19", + settings: { + metadata: { + // We disable the metadata to keep the fixtures more stables + appendCBOR: false, + }, + }, + }, +}; diff --git a/packages/hardhat-ignition/test/fixture-projects/reset-flag/ignition/modules/FirstPass.js b/packages/hardhat-ignition/test/fixture-projects/reset-flag/ignition/modules/FirstPass.js new file mode 100644 index 0000000000..e69d05696f --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/reset-flag/ignition/modules/FirstPass.js @@ -0,0 +1,9 @@ +const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); + +module.exports = buildModule("ResetModule", (m) => { + const a = m.contract("Foo", [], { + id: "A", + }); + + return { a }; +}); diff --git a/packages/hardhat-ignition/test/fixture-projects/reset-flag/ignition/modules/SecondPass.js b/packages/hardhat-ignition/test/fixture-projects/reset-flag/ignition/modules/SecondPass.js new file mode 100644 index 0000000000..fdf765ce38 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/reset-flag/ignition/modules/SecondPass.js @@ -0,0 +1,14 @@ +const { buildModule } = require("@nomicfoundation/hardhat-ignition/modules"); + +module.exports = buildModule("ResetModule", (m) => { + // Same id as first pass but a different contract + const a = m.contract("Bar", [], { + id: "A", + }); + + const b = m.contract("Baz", [], { + id: "B", + }); + + return { a, b }; +}); diff --git a/packages/hardhat-ignition/test/fixture-projects/reset-flag/journal.jsonl b/packages/hardhat-ignition/test/fixture-projects/reset-flag/journal.jsonl new file mode 100644 index 0000000000..9598589a9b --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/reset-flag/journal.jsonl @@ -0,0 +1,7 @@ + +{"chainId":31337,"type":"DEPLOYMENT_INITIALIZE"} +{"artifactId":"LockModule#resetFutureId","constructorArgs":[1987909200],"contractName":"Lock","dependencies":[],"from":"0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266","futureId":"LockModule#resetFutureId","futureType":"NAMED_ARTIFACT_CONTRACT_DEPLOYMENT","libraries":{},"strategy":"basic","type":"DEPLOYMENT_EXECUTION_STATE_INITIALIZE","value":{"_kind":"bigint","value":"1000000000"}} +{"futureId":"LockModule#resetFutureId","networkInteraction":{"data":"0x60806040526040516105d83803806105d8833981810160405281019061002591906100f0565b804210610067576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161005e906101a0565b60405180910390fd5b8060008190555033600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550506101c0565b600080fd5b6000819050919050565b6100cd816100ba565b81146100d857600080fd5b50565b6000815190506100ea816100c4565b92915050565b600060208284031215610106576101056100b5565b5b6000610114848285016100db565b91505092915050565b600082825260208201905092915050565b7f556e6c6f636b2074696d652073686f756c6420626520696e207468652066757460008201527f7572650000000000000000000000000000000000000000000000000000000000602082015250565b600061018a60238361011d565b91506101958261012e565b604082019050919050565b600060208201905081810360008301526101b98161017d565b9050919050565b610409806101cf6000396000f3fe608060405234801561001057600080fd5b50600436106100415760003560e01c8063251c1aa3146100465780633ccfd60b146100645780638da5cb5b1461006e575b600080fd5b61004e61008c565b60405161005b919061024a565b60405180910390f35b61006c610092565b005b61007661020b565b60405161008391906102a6565b60405180910390f35b60005481565b6000544210156100d7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100ce9061031e565b60405180910390fd5b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610167576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161015e9061038a565b60405180910390fd5b7fbf2ed60bd5b5965d685680c01195c9514e4382e28e3a5a2d2d5244bf59411b9347426040516101989291906103aa565b60405180910390a1600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f19350505050158015610208573d6000803e3d6000fd5b50565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000819050919050565b61024481610231565b82525050565b600060208201905061025f600083018461023b565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600061029082610265565b9050919050565b6102a081610285565b82525050565b60006020820190506102bb6000830184610297565b92915050565b600082825260208201905092915050565b7f596f752063616e27742077697468647261772079657400000000000000000000600082015250565b60006103086016836102c1565b9150610313826102d2565b602082019050919050565b60006020820190508181036000830152610337816102fb565b9050919050565b7f596f75206172656e277420746865206f776e6572000000000000000000000000600082015250565b60006103746014836102c1565b915061037f8261033e565b602082019050919050565b600060208201905081810360008301526103a381610367565b9050919050565b60006040820190506103bf600083018561023b565b6103cc602083018461023b565b939250505056fea2646970667358221220f92f73d2a3284a3c1cca55a0fe6ec1a91b13bec884aecdbcf644cebf2774f32f64736f6c6343000813003300000000000000000000000000000000000000000000000000000000767d1650","id":1,"type":"ONCHAIN_INTERACTION","value":{"_kind":"bigint","value":"1000000000"}},"type":"NETWORK_INTERACTION_REQUEST"} +{"futureId":"LockModule#resetFutureId","networkInteractionId":1,"nonce":1,"transaction":{"fees":{"maxFeePerGas":{"_kind":"bigint","value":"2750000000"},"maxPriorityFeePerGas":{"_kind":"bigint","value":"1000000000"}},"hash":"0x1a3eb512e21fc849f8e8733b250ce49b61178c9c4a670063f969db59eda4a59f"},"type":"TRANSACTION_SEND"} +{"futureId":"LockModule#resetFutureId","hash":"0x1a3eb512e21fc849f8e8733b250ce49b61178c9c4a670063f969db59eda4a59f","networkInteractionId":1,"receipt":{"blockHash":"0xd742dbff894385ce6cbe737508ce91c181d0b65c7faaa5a7078fde68070c16e5","blockNumber":2,"contractAddress":"0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512","logs":[],"status":"SUCCESS"},"type":"TRANSACTION_CONFIRM"} +{"futureId":"LockModule#resetFutureId","result":{"address":"0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512","type":"SUCCESS"},"type":"DEPLOYMENT_EXECUTION_STATE_COMPLETE"} \ No newline at end of file diff --git a/packages/hardhat-ignition/test/fixture-projects/user-modules/contracts/Contracts.sol b/packages/hardhat-ignition/test/fixture-projects/user-modules/contracts/Contracts.sol new file mode 100644 index 0000000000..f975a1abdc --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/user-modules/contracts/Contracts.sol @@ -0,0 +1,31 @@ +contract Foo { + bool public isFoo = true; + uint public x = 1; + + function inc() public { + x++; + } + + function incByPositiveNumber(uint n) public { + require(n > 0, "n must be positive"); + x += n; + } + + function incTwoNumbers(uint n, uint y) public { + require(n > 0, "n must be positive"); + x += n; + x += y; + } +} + +contract Bar { + bool public isBar = true; +} + +contract UsesContract { + address public contractAddress; + + constructor (address _contract) { + contractAddress = _contract; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/user-modules/contracts/WithLibrary.sol b/packages/hardhat-ignition/test/fixture-projects/user-modules/contracts/WithLibrary.sol new file mode 100644 index 0000000000..903f589c6c --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/user-modules/contracts/WithLibrary.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +library RubbishMath { + function add(uint16 left, uint16 right) public pure returns (uint16) { + return left + right; + } +} + +contract DependsOnLib { + function addThreeNumbers( + uint16 first, + uint16 second, + uint16 third + ) public pure returns (uint16) { + return RubbishMath.add(first, RubbishMath.add(second, third)); + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/user-modules/hardhat.config.js b/packages/hardhat-ignition/test/fixture-projects/user-modules/hardhat.config.js new file mode 100644 index 0000000000..39a079daef --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/user-modules/hardhat.config.js @@ -0,0 +1,11 @@ +require("../../../src/index"); + +module.exports = { + networks: { + hardhat: { + mining: { + auto: false, + }, + }, + }, +}; diff --git a/packages/hardhat-ignition/test/fixture-projects/user-modules/ignition/.testignore b/packages/hardhat-ignition/test/fixture-projects/user-modules/ignition/.testignore new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/hardhat-ignition/test/fixture-projects/user-modules/ignition/modules/TestModule.js b/packages/hardhat-ignition/test/fixture-projects/user-modules/ignition/modules/TestModule.js new file mode 100644 index 0000000000..5e46fcd608 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/user-modules/ignition/modules/TestModule.js @@ -0,0 +1,4 @@ +module.exports = { + id: "testing123", + moduleDefintionFunction: () => {}, +}; diff --git a/packages/hardhat-ignition/test/fixture-projects/verify-no-api-key/hardhat.config.js b/packages/hardhat-ignition/test/fixture-projects/verify-no-api-key/hardhat.config.js new file mode 100644 index 0000000000..8eb8897a69 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/verify-no-api-key/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../src/index"); + +module.exports = { + solidity: "0.8.19", + networks: { + hardhat: { + mining: { + auto: false, + }, + }, + }, + etherscan: { + apiKey: "", + }, +}; diff --git a/packages/hardhat-ignition/test/fixture-projects/with-config/contracts/Contracts.sol b/packages/hardhat-ignition/test/fixture-projects/with-config/contracts/Contracts.sol new file mode 100644 index 0000000000..7b168b2d7d --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/with-config/contracts/Contracts.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract Foo { + bool public isFoo = true; + uint256 public x = 1; + + function inc() public { + x++; + } + + function incByPositiveNumber(uint256 n) public { + require(n > 0, "n must be positive"); + x += n; + } + + function incTwoNumbers(uint256 first, uint256 second) public { + x += first; + x += second; + } +} + +contract Bar { + bool public isBar = true; +} + +contract UsesContract { + address public contractAddress; + + constructor(address _contract) { + contractAddress = _contract; + } + + function setAddress(address _contract) public { + contractAddress = _contract; + } +} + +contract Greeter { + string private _greeting; + + constructor(string memory greeting) { + _greeting = greeting; + } + + function getGreeting() public view returns (string memory) { + return _greeting; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/with-config/contracts/Trace.sol b/packages/hardhat-ignition/test/fixture-projects/with-config/contracts/Trace.sol new file mode 100644 index 0000000000..1687a1d485 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/with-config/contracts/Trace.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract Trace { + string[] public entries; + + constructor(string memory firstEntry) { + entries = [firstEntry]; + } + + function addEntry(string memory entry) public { + entries.push(entry); + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/with-config/contracts/WithLibrary.sol b/packages/hardhat-ignition/test/fixture-projects/with-config/contracts/WithLibrary.sol new file mode 100644 index 0000000000..903f589c6c --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/with-config/contracts/WithLibrary.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +library RubbishMath { + function add(uint16 left, uint16 right) public pure returns (uint16) { + return left + right; + } +} + +contract DependsOnLib { + function addThreeNumbers( + uint16 first, + uint16 second, + uint16 third + ) public pure returns (uint16) { + return RubbishMath.add(first, RubbishMath.add(second, third)); + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/with-config/hardhat.config.js b/packages/hardhat-ignition/test/fixture-projects/with-config/hardhat.config.js new file mode 100644 index 0000000000..1a2ca9a967 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/with-config/hardhat.config.js @@ -0,0 +1,29 @@ +require("../../../src/index"); + +module.exports = { + networks: { + hardhat: { + mining: { + auto: false, + }, + ignition: { + maxFeePerGasLimit: 2n, + maxPriorityFeePerGas: 3n, + gasPrice: 1n, + disableFeeBumping: false, + }, + }, + }, + ignition: { + requiredConfirmations: 10, + blockPollingInterval: 100, + timeBeforeBumpingFees: 60 * 1000, + maxFeeBumps: 2, + strategyConfig: { + create2: { + salt: "custom-salt", + }, + }, + disableFeeBumping: true, + }, +}; diff --git a/packages/hardhat-ignition/test/fixture-projects/with-config/ignition/modules/MyModule.js b/packages/hardhat-ignition/test/fixture-projects/with-config/ignition/modules/MyModule.js new file mode 100644 index 0000000000..49cddf0034 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/with-config/ignition/modules/MyModule.js @@ -0,0 +1,14 @@ +const { buildModule } = require("@nomicfoundation/ignition-core"); + +module.exports = buildModule("MyModule", (m) => { + const bar = m.contract("Bar"); + const usesContract = m.contract("UsesContract", { + args: ["0x0000000000000000000000000000000000000000"], + }); + + m.call(usesContract, "setAddress", { + args: [bar], + }); + + return { bar, usesContract }; +}); diff --git a/packages/hardhat-ignition/test/fixture-projects/with-invalid-config/contracts/Contracts.sol b/packages/hardhat-ignition/test/fixture-projects/with-invalid-config/contracts/Contracts.sol new file mode 100644 index 0000000000..7b168b2d7d --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/with-invalid-config/contracts/Contracts.sol @@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract Foo { + bool public isFoo = true; + uint256 public x = 1; + + function inc() public { + x++; + } + + function incByPositiveNumber(uint256 n) public { + require(n > 0, "n must be positive"); + x += n; + } + + function incTwoNumbers(uint256 first, uint256 second) public { + x += first; + x += second; + } +} + +contract Bar { + bool public isBar = true; +} + +contract UsesContract { + address public contractAddress; + + constructor(address _contract) { + contractAddress = _contract; + } + + function setAddress(address _contract) public { + contractAddress = _contract; + } +} + +contract Greeter { + string private _greeting; + + constructor(string memory greeting) { + _greeting = greeting; + } + + function getGreeting() public view returns (string memory) { + return _greeting; + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/with-invalid-config/contracts/Trace.sol b/packages/hardhat-ignition/test/fixture-projects/with-invalid-config/contracts/Trace.sol new file mode 100644 index 0000000000..1687a1d485 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/with-invalid-config/contracts/Trace.sol @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract Trace { + string[] public entries; + + constructor(string memory firstEntry) { + entries = [firstEntry]; + } + + function addEntry(string memory entry) public { + entries.push(entry); + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/with-invalid-config/contracts/WithLibrary.sol b/packages/hardhat-ignition/test/fixture-projects/with-invalid-config/contracts/WithLibrary.sol new file mode 100644 index 0000000000..903f589c6c --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/with-invalid-config/contracts/WithLibrary.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +library RubbishMath { + function add(uint16 left, uint16 right) public pure returns (uint16) { + return left + right; + } +} + +contract DependsOnLib { + function addThreeNumbers( + uint16 first, + uint16 second, + uint16 third + ) public pure returns (uint16) { + return RubbishMath.add(first, RubbishMath.add(second, third)); + } +} diff --git a/packages/hardhat-ignition/test/fixture-projects/with-invalid-config/hardhat.config.js b/packages/hardhat-ignition/test/fixture-projects/with-invalid-config/hardhat.config.js new file mode 100644 index 0000000000..26fea701e4 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/with-invalid-config/hardhat.config.js @@ -0,0 +1,17 @@ +require("../../../src/index"); + +module.exports = { + networks: { + hardhat: { + mining: { + auto: false, + }, + }, + }, + ignition: { + requiredConfirmations: 0, + blockPollingInterval: 100, + timeBeforeBumpingFees: 60 * 1000, + maxFeeBumps: 2, + }, +}; diff --git a/packages/hardhat-ignition/test/fixture-projects/with-invalid-config/ignition/modules/MyModule.js b/packages/hardhat-ignition/test/fixture-projects/with-invalid-config/ignition/modules/MyModule.js new file mode 100644 index 0000000000..49cddf0034 --- /dev/null +++ b/packages/hardhat-ignition/test/fixture-projects/with-invalid-config/ignition/modules/MyModule.js @@ -0,0 +1,14 @@ +const { buildModule } = require("@nomicfoundation/ignition-core"); + +module.exports = buildModule("MyModule", (m) => { + const bar = m.contract("Bar"); + const usesContract = m.contract("UsesContract", { + args: ["0x0000000000000000000000000000000000000000"], + }); + + m.call(usesContract, "setAddress", { + args: [bar], + }); + + return { bar, usesContract }; +}); diff --git a/packages/hardhat-ignition/test/ignition-helper-guard.ts b/packages/hardhat-ignition/test/ignition-helper-guard.ts new file mode 100644 index 0000000000..fb7359bbf2 --- /dev/null +++ b/packages/hardhat-ignition/test/ignition-helper-guard.ts @@ -0,0 +1,21 @@ +/* eslint-disable import/no-unused-modules */ +import { assert } from "chai"; + +import { useEphemeralIgnitionProject } from "./test-helpers/use-ignition-project"; + +/** + * A project that only imports `@nomicfoundation/hardhat-ignition` will not add + * a `hre.ignition` property to the Hardhat Runtime Environment. + * We warn that you need to install either the viem or ethers plugin to get + * Ignition support in tests or scripts. + */ +describe("ignition helper guard", () => { + useEphemeralIgnitionProject("minimal"); + + it("should error on attempting to use `hre.ignition` without viem/ethers plugins installed", function () { + assert.throws( + () => (this.hre as any).originalIgnition.deploy(), + /Please install either `@nomicfoundation\/hardhat-ignition-viem` or `@nomicfoundation\/hardhat-ignition-ethers` to use Ignition in your Hardhat tests/ + ); + }); +}); diff --git a/packages/hardhat-ignition/test/module-api/calls.ts b/packages/hardhat-ignition/test/module-api/calls.ts new file mode 100644 index 0000000000..e18ce6e181 --- /dev/null +++ b/packages/hardhat-ignition/test/module-api/calls.ts @@ -0,0 +1,173 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { getBalanceFor } from "../test-helpers/get-balance-for"; +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("calls", () => { + useEphemeralIgnitionProject("minimal"); + + it("should be able to call contracts", async function () { + const moduleDefinition = buildModule("SetAddressModule", (m) => { + const bar = m.contract("Bar"); + const usesContract = m.contract("UsesContract", [ + "0x0000000000000000000000000000000000000000", + ]); + + m.call(usesContract, "setAddress", [bar]); + + return { bar, usesContract }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.isDefined(result.bar); + assert.isDefined(result.usesContract); + + const usedAddress = + (await result.usesContract.read.contractAddress()) as string; + + assert.equal(usedAddress.toLowerCase(), result.bar.address.toLowerCase()); + }); + + it("should be able to call contracts with array args", async function () { + const moduleDefinition = buildModule("ArrayArgModule", (m) => { + const captureArraysContract = m.contract("CaptureArraysContract"); + + m.call(captureArraysContract, "recordArrays", [ + [1, 2, 3], + ["a", "b", "c"], + [true, false, true], + ]); + + return { captureArraysContract }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.isDefined(result.captureArraysContract); + + const captureSuceeded = + await result.captureArraysContract.read.arraysCaptured(); + + assert(captureSuceeded); + }); + + it("should be able to call contracts with arrays nested in objects args", async function () { + const moduleDefinition = buildModule("ArrayNestedModule", (m) => { + const captureComplexObjectContract = m.contract( + "CaptureComplexObjectContract" + ); + + m.call(captureComplexObjectContract, "testComplexObject", [ + { + firstBool: true, + secondArray: [1, 2, 3], + thirdSubcomplex: { sub: "sub" }, + }, + ]); + + return { captureComplexObjectContract }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.isDefined(result.captureComplexObjectContract); + + const captureSuceeded = + await result.captureComplexObjectContract.read.complexArgCaptured(); + + assert(captureSuceeded); + }); + + it("should be able to make calls in order", async function () { + const moduleDefinition = buildModule("OrderedModule", (m) => { + const trace = m.contract("Trace", ["first"]); + + const second = m.call(trace, "addEntry", ["second"], { id: "AddEntry1" }); + + m.call(trace, "addEntry", ["third"], { + id: "AddEntry2", + after: [second], + }); + + return { trace }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.isDefined(result.trace); + + const entry1 = await result.trace.read.entries([0n]); + const entry2 = await result.trace.read.entries([1n]); + const entry3 = await result.trace.read.entries([2n]); + + assert.deepStrictEqual( + [entry1, entry2, entry3], + ["first", "second", "third"] + ); + }); + + describe("passing value", () => { + it("should be able to call a contract passing a value", async function () { + const moduleDefinition = buildModule("PassingValue", (m) => { + const passingValue = m.contract("PassingValue"); + + m.call(passingValue, "deposit", [], { + value: 1_000_000_000n, + }); + + return { passingValue }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.isDefined(result.passingValue); + + const actualInstanceBalance = await getBalanceFor( + this.hre, + result.passingValue.address + ); + + assert.equal(actualInstanceBalance, 1_000_000_000n); + }); + + it("should be able to call a contract passing a value via a parameter", async function () { + const submoduleDefinition = buildModule("Submodule", (m) => { + const depositValue = m.getParameter("depositValue", 1000n); + + const passingValue = m.contract("PassingValue"); + + m.call(passingValue, "deposit", [], { + value: depositValue, + }); + + return { passingValue }; + }); + + const moduleDefinition = buildModule("Module", (m) => { + const { passingValue } = m.useModule(submoduleDefinition); + + return { passingValue }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition, { + parameters: { + Submodule: { + depositValue: 1_000_000_000n, + }, + }, + }); + + assert.isDefined(result.passingValue); + + const actualInstanceBalance = await getBalanceFor( + this.hre, + result.passingValue.address + ); + + assert.equal(actualInstanceBalance, 1_000_000_000n); + }); + }); +}); diff --git a/packages/hardhat-ignition/test/module-api/contracts.ts b/packages/hardhat-ignition/test/module-api/contracts.ts new file mode 100644 index 0000000000..01dcb3fc3c --- /dev/null +++ b/packages/hardhat-ignition/test/module-api/contracts.ts @@ -0,0 +1,206 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { getBalanceFor } from "../test-helpers/get-balance-for"; +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("contract deploys", () => { + useEphemeralIgnitionProject("minimal"); + + it("should be able to deploy a contract", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const foo = m.contract("Foo"); + + return { foo }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.equal(await result.foo.read.x(), 1n); + }); + + it("should be able to deploy a contract with arguments", async function () { + const moduleDefinition = buildModule("GreeterModule", (m) => { + const greeter = m.contract("Greeter", ["Hello World"]); + + return { greeter }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + const greeting = await result.greeter.read.getGreeting(); + assert.equal(greeting, "Hello World"); + }); + + it("should be able to deploy contracts with dependencies", async function () { + const moduleDefinition = buildModule("DependentModule", (m) => { + const bar = m.contract("Bar"); + const usesContract = m.contract("UsesContract", [bar]); + + return { bar, usesContract }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.isDefined(result.bar); + assert.isDefined(result.usesContract); + + const usedAddress = + (await result.usesContract.read.contractAddress()) as string; + + assert.equal(usedAddress.toLowerCase(), result.bar.address.toLowerCase()); + }); + + it("should be able to deploy contracts without dependencies", async function () { + const moduleDefinition = buildModule("WithoutDepModule", (m) => { + const foo = m.contract("Foo"); + const bar = m.contract("Bar"); + + return { foo, bar }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + const x = await result.foo.read.x(); + const isBar = await result.bar.read.isBar(); + + assert.equal(x, 1n); + assert.equal(isBar, true); + }); + + it("should be able to use an artifact to deploy a contract", async function () { + await this.hre.run("compile", { quiet: true }); + + const artifact = await this.hre.artifacts.readArtifact("Greeter"); + + const moduleDefinition = buildModule("ArtifactModule", (m) => { + const greeter = m.contract("Greeter", artifact, ["Hello World"]); + + return { greeter }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + const greeting = await result.greeter.read.getGreeting(); + assert.equal(greeting, "Hello World"); + }); + + describe("with endowment", () => { + it("should be able to deploy a contract with an endowment", async function () { + const moduleDefinition = buildModule("EndowmentModule", (m) => { + const passingValue = m.contract("PassingValue", [], { + value: 1_000_000_000n, + }); + + return { passingValue }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.isDefined(result.passingValue); + + const actualInstanceBalance = await getBalanceFor( + this.hre, + result.passingValue.address + ); + + assert.equal(actualInstanceBalance, 1_000_000_000n); + }); + + it("should be able to deploy a contract with an endowment via a parameter", async function () { + const submoduleDefinition = buildModule("submodule", (m) => { + const endowment = m.getParameter("endowment", 2_000_000_000n); + + const passingValue = m.contract("PassingValue", [], { + value: endowment, + }); + + return { passingValue }; + }); + + const moduleDefinition = buildModule("Module", (m) => { + const { passingValue } = m.useModule(submoduleDefinition); + + return { passingValue }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.isDefined(result.passingValue); + + const actualInstanceBalance = await getBalanceFor( + this.hre, + result.passingValue.address + ); + + assert.equal(actualInstanceBalance, 2_000_000_000n); + }); + + it("should be able to deploy a contract with an endowment via a static call", async function () { + const submoduleDefinition = buildModule("submodule", (m) => { + const valueContract = m.contract("StaticCallValue"); + + const valueResult = m.staticCall(valueContract, "getValue"); + + const passingValue = m.contract("PassingValue", [], { + value: valueResult, + }); + + return { passingValue }; + }); + + const moduleDefinition = buildModule("Module", (m) => { + const { passingValue } = m.useModule(submoduleDefinition); + + return { passingValue }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.isDefined(result.passingValue); + + const actualInstanceBalance = await getBalanceFor( + this.hre, + result.passingValue.address + ); + + assert.equal(actualInstanceBalance.toString(), "42"); + }); + + it("should be able to deploy a contract with an endowment via an event argument", async function () { + const submoduleDefinition = buildModule("submodule", (m) => { + const valueContract = m.contract("EventArgValue"); + + const valueResult = m.readEventArgument( + valueContract, + "EventValue", + "value" + ); + + const passingValue = m.contract("PassingValue", [], { + value: valueResult, + }); + + return { passingValue }; + }); + + const moduleDefinition = buildModule("Module", (m) => { + const { passingValue } = m.useModule(submoduleDefinition); + + return { passingValue }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.isDefined(result.passingValue); + + const actualInstanceBalance = await getBalanceFor( + this.hre, + result.passingValue.address + ); + + assert.equal(actualInstanceBalance.toString(), "42"); + }); + }); +}); diff --git a/packages/hardhat-ignition/test/module-api/events.ts b/packages/hardhat-ignition/test/module-api/events.ts new file mode 100644 index 0000000000..291d0b4383 --- /dev/null +++ b/packages/hardhat-ignition/test/module-api/events.ts @@ -0,0 +1,106 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("events", () => { + useEphemeralIgnitionProject("minimal"); + + it("should be able to use the output of a readEvent in a contract at", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const account1 = m.getAccount(1); + + const fooFactory = m.contract("FooFactory", [], { from: account1 }); + + const createCall = m.call(fooFactory, "create", []); + + const newAddress = m.readEventArgument( + createCall, + "Deployed", + "fooAddress" + ); + + const foo = m.contractAt("Foo", newAddress); + + return { fooFactory, foo }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.equal(await result.fooFactory.read.isDeployed(), true); + assert.equal(await result.foo.read.x(), 1n); + }); + + it("should be able to use the output of a readEvent in an artifact contract at", async function () { + const artifact = await this.hre.artifacts.readArtifact("Foo"); + + const moduleDefinition = buildModule("FooModule", (m) => { + const account1 = m.getAccount(1); + + const fooFactory = m.contract("FooFactory", [], { from: account1 }); + + const createCall = m.call(fooFactory, "create", []); + + const newAddress = m.readEventArgument( + createCall, + "Deployed", + "fooAddress" + ); + + const foo = m.contractAt("Foo", artifact, newAddress); + + return { fooFactory, foo }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.equal(await result.fooFactory.read.isDeployed(), true); + assert.equal(await result.foo.read.x(), 1n); + }); + + it("should be able to read an event from a SendDataFuture", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const sendEmitter = m.contract("SendDataEmitter"); + + const send = m.send("send_data_event", sendEmitter); + + const output = m.readEventArgument(send, "SendDataEvent", "arg", { + emitter: sendEmitter, + }); + + m.call(sendEmitter, "validateEmitted", [output]); + + return { sendEmitter }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.equal(await result.sendEmitter.read.wasEmitted(), true); + }); + + it("should be able to use the output of a readEvent with an indexed tuple result", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const tupleContract = m.contract("TupleEmitter"); + + const tupleCall = m.call(tupleContract, "emitTuple"); + + const arg1 = m.readEventArgument(tupleCall, "TupleEvent", "arg1", { + id: "arg1", + }); + const arg2 = m.readEventArgument(tupleCall, "TupleEvent", 1, { + id: "arg2", + }); + + m.call(tupleContract, "verifyArg1", [arg1], { id: "call1" }); + m.call(tupleContract, "verifyArg2", [arg2], { id: "call2" }); + + return { tupleContract }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.equal(await result.tupleContract.read.arg1Captured(), true); + assert.equal(await result.tupleContract.read.arg2Captured(), true); + }); +}); diff --git a/packages/hardhat-ignition/test/module-api/existing-contract.ts b/packages/hardhat-ignition/test/module-api/existing-contract.ts new file mode 100644 index 0000000000..2b50dbb73a --- /dev/null +++ b/packages/hardhat-ignition/test/module-api/existing-contract.ts @@ -0,0 +1,55 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("existing contract", () => { + useEphemeralIgnitionProject("minimal"); + + it("should be able to use an existing contract", async function () { + await this.hre.run("compile", { quiet: true }); + + const barArtifact = await this.hre.artifacts.readArtifact("Bar"); + const usesContractArtifact = await this.hre.artifacts.readArtifact( + "UsesContract" + ); + + const firstModuleDefinition = buildModule("FirstModule", (m) => { + const bar = m.contract("Bar"); + const usesContract = m.contract("UsesContract", [ + "0x0000000000000000000000000000000000000000", + ]); + + return { bar, usesContract }; + }); + + const firstResult = await this.hre.ignition.deploy(firstModuleDefinition); + + const barAddress: string = firstResult.bar.address; + const usesContractAddress: string = firstResult.usesContract.address; + + const secondModuleDefinition = buildModule("SecondModule", (m) => { + const bar = m.contractAt("Bar", barArtifact, barAddress); + const usesContract = m.contractAt( + "UsesContract", + usesContractArtifact, + usesContractAddress + ); + + m.call(usesContract, "setAddress", [bar]); + + return { bar, usesContract }; + }); + + const result = await this.hre.ignition.deploy(secondModuleDefinition); + + assert.isDefined(result.bar); + assert.isDefined(result.usesContract); + + const usedAddress = + (await result.usesContract.read.contractAddress()) as string; + + assert.equal(usedAddress.toLowerCase(), result.bar.address.toLowerCase()); + }); +}); diff --git a/packages/hardhat-ignition/test/module-api/fully-qualified-names.ts b/packages/hardhat-ignition/test/module-api/fully-qualified-names.ts new file mode 100644 index 0000000000..9a3c911809 --- /dev/null +++ b/packages/hardhat-ignition/test/module-api/fully-qualified-names.ts @@ -0,0 +1,39 @@ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { useFileIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("fully qualified names", () => { + describe("where there are multiple contracts with the same name in the project", () => { + useFileIgnitionProject( + "multiple-contracts-with-same-name", + "contract-deploy" + ); + + it("should deploy contracts by referring using fully qualified names", async function () { + const LaunchModule = buildModule("Apollo", (m) => { + const rocket1 = m.contract( + "contracts/Rocket1.sol:Rocket", + ["Rocket 1"], + { + id: "Rocket1", + } + ); + const rocket2 = m.contract( + "contracts/Rocket2.sol:Rocket", + ["Rocket 2"], + { + id: "Rocket2", + } + ); + + return { rocket1, rocket2 }; + }); + + const result = await this.hre.ignition.deploy(LaunchModule); + + assert.equal(await result.rocket1.read.name(), "Rocket 1"); + assert.equal(await result.rocket2.read.name(), "Rocket 2"); + }); + }); +}); diff --git a/packages/hardhat-ignition/test/module-api/libraries.ts b/packages/hardhat-ignition/test/module-api/libraries.ts new file mode 100644 index 0000000000..5ccefc9c78 --- /dev/null +++ b/packages/hardhat-ignition/test/module-api/libraries.ts @@ -0,0 +1,128 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("libraries", () => { + useEphemeralIgnitionProject("minimal"); + + it("should be able to deploy a contract that depends on a hardhat library", async function () { + const moduleDefinition = buildModule("WithLibModule", (m) => { + const rubbishMath = m.library("RubbishMath"); + const dependsOnLib = m.contract("DependsOnLib", [], { + libraries: { + RubbishMath: rubbishMath, + }, + }); + + return { rubbishMath, dependsOnLib }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.isDefined(result); + const contractThatDependsOnLib = result.dependsOnLib; + + const libBasedAddtion = await contractThatDependsOnLib.read.addThreeNumbers( + [1, 2, 3] + ); + + assert.equal(libBasedAddtion, 6); + }); + + it("should be able to deploy a contract that depends on an artifact library", async function () { + await this.hre.run("compile", { quiet: true }); + + const libraryArtifact = await this.hre.artifacts.readArtifact( + "RubbishMath" + ); + + const moduleDefinition = buildModule("ArtifactLibraryModule", (m) => { + const rubbishMath = m.library("RubbishMath", libraryArtifact); + const dependsOnLib = m.contract("DependsOnLib", [], { + libraries: { + RubbishMath: rubbishMath, + }, + }); + + return { rubbishMath, dependsOnLib }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.isDefined(result); + const contractThatDependsOnLib = result.dependsOnLib; + + const libBasedAddtion = await contractThatDependsOnLib.read.addThreeNumbers( + [1, 2, 3] + ); + + assert.equal(libBasedAddtion, 6); + }); + + it("should deploy a contract with an existing library", async function () { + const libraryModuleDefinition = buildModule("LibraryModule", (m) => { + const rubbishMath = m.library("RubbishMath"); + + return { rubbishMath }; + }); + + const libDeployResult = await this.hre.ignition.deploy( + libraryModuleDefinition + ); + + const libAddress = libDeployResult.rubbishMath.address; + + const moduleDefinition = buildModule("ConsumingLibModule", (m) => { + const rubbishMath = m.contractAt("RubbishMath", libAddress); + + const dependsOnLib = m.contract("DependsOnLib", [], { + libraries: { + RubbishMath: rubbishMath, + }, + }); + + return { dependsOnLib }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.equal(await libDeployResult.rubbishMath.read.add([1, 2]), 3); + assert.equal(await result.dependsOnLib.read.addThreeNumbers([1, 2, 3]), 6); + }); + + it("should be able to deploy a library that depends on a library", async function () { + const moduleDefinition = buildModule("ArtifactLibraryModule", (m) => { + const rubbishMath = m.library("RubbishMath"); + + const libDependsOnLib = m.library("LibDependsOnLib", { + libraries: { + RubbishMath: rubbishMath, + }, + }); + + const dependsOnLibThatDependsOnLib = m.contract( + "DependsOnLibThatDependsOnLib", + [], + { + libraries: { + LibDependsOnLib: libDependsOnLib, + }, + } + ); + + return { rubbishMath, libDependsOnLib, dependsOnLibThatDependsOnLib }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.isDefined(result); + const contractThatDependsOnLibOnLib = result.dependsOnLibThatDependsOnLib; + + const libBasedAddtion = + await contractThatDependsOnLibOnLib.read.addThreeNumbers([1, 2, 3]); + + assert.equal(libBasedAddtion, 6); + }); +}); diff --git a/packages/hardhat-ignition/test/module-api/params.ts b/packages/hardhat-ignition/test/module-api/params.ts new file mode 100644 index 0000000000..d76c90bb16 --- /dev/null +++ b/packages/hardhat-ignition/test/module-api/params.ts @@ -0,0 +1,183 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("module parameters", () => { + useEphemeralIgnitionProject("minimal"); + + it("should be able to retrieve a default number", async function () { + const moduleDefinition = buildModule("WithDefaultModule", (m) => { + const myNumber = m.getParameter("MyNumber", 42); + + const foo = m.contract("Foo"); + + m.call(foo, "incByPositiveNumber", [myNumber]); + + return { foo }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + const v = await result.foo.read.x(); + + assert.equal(v, 43n); + }); + + it("should be able to override a default number", async function () { + const moduleDefinition = buildModule("WithDefaultModule", (m) => { + const myNumber = m.getParameter("MyNumber", 10); + + const foo = m.contract("Foo"); + + m.call(foo, "incByPositiveNumber", [myNumber]); + + return { foo }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition, { + parameters: { + WithDefaultModule: { + MyNumber: 20, + }, + }, + }); + + assert.equal(await result.foo.read.x(), 21n); + }); + + it("should be able to retrieve a default string", async function () { + const moduleDefinition = buildModule("WithDefaultStringModule", (m) => { + const myString = m.getParameter("MyString", "Example"); + + const greeter = m.contract("Greeter", [myString]); + + return { greeter }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + const v = await result.greeter.read.getGreeting(); + + assert.equal(v, "Example"); + }); + + it("should be able to override a default string", async function () { + const moduleDefinition = buildModule("WithDefaultStringModule", (m) => { + const myString = m.getParameter("MyString", "Example"); + + const greeter = m.contract("Greeter", [myString]); + + return { greeter }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition, { + parameters: { + WithDefaultStringModule: { + MyString: "NotExample", + }, + }, + }); + + assert.equal(await result.greeter.read.getGreeting(), "NotExample"); + }); + + it("should be able to retrieve a default AccountRuntimeValue", async function () { + const moduleDefinition = buildModule("WithDefaultAccountModule", (m) => { + const newOwner = m.getParameter("newOwner", m.getAccount(1)); + + const ownerContract = m.contract("Owner", [], { from: m.getAccount(0) }); + + m.call(ownerContract, "setOwner", [newOwner]); + + return { ownerContract }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + const v = (await result.ownerContract.read.owner()) as string; + + const accounts = await this.hre.network.provider.send("eth_accounts"); + + assert.equal(v.toLowerCase(), accounts[1]); + }); + + it("should be able to override a default AccountRuntimeValue", async function () { + const moduleDefinition = buildModule("WithDefaultAccountModule", (m) => { + const newOwner = m.getParameter("newOwner", m.getAccount(1)); + + const ownerContract = m.contract("Owner", [], { from: m.getAccount(0) }); + + m.call(ownerContract, "setOwner", [newOwner]); + + return { ownerContract }; + }); + + const accounts = await this.hre.network.provider.send("eth_accounts"); + + const result = await this.hre.ignition.deploy(moduleDefinition, { + parameters: { + WithDefaultAccountModule: { + newOwner: accounts[2], + }, + }, + }); + + const v = (await result.ownerContract.read.owner()) as string; + + assert.equal(v.toLowerCase(), accounts[2]); + }); +}); + +describe("params validation", () => { + useEphemeralIgnitionProject("minimal"); + + it("should throw if no parameters object provided", async function () { + await this.hre.run("compile", { quiet: true }); + + const userModule = buildModule("UserModule", (m) => { + const myNumber = m.getParameter("MyNumber"); + + const foo = m.contract("Foo"); + + m.call(foo, "incByPositiveNumber", [myNumber]); + + return { foo }; + }); + + const deployPromise = this.hre.ignition.deploy(userModule); + + await assert.isRejected( + deployPromise, + "Module parameter 'MyNumber' requires a value but was given none" + ); + }); + + it("should throw if parameter missing from parameters", async function () { + await this.hre.run("compile", { quiet: true }); + + const userModule = buildModule("UserModule", (m) => { + const myNumber = m.getParameter("MyNumber"); + + const foo = m.contract("Foo"); + + m.call(foo, "incByPositiveNumber", [myNumber]); + + return { foo }; + }); + + const deployPromise = this.hre.ignition.deploy(userModule, { + parameters: { + UserModule: { + NotMyNumber: 11, + }, + }, + }); + + await assert.isRejected( + deployPromise, + "Module parameter 'MyNumber' requires a value but was given none" + ); + }); +}); diff --git a/packages/hardhat-ignition/test/module-api/static-calls.ts b/packages/hardhat-ignition/test/module-api/static-calls.ts new file mode 100644 index 0000000000..fd603e5f73 --- /dev/null +++ b/packages/hardhat-ignition/test/module-api/static-calls.ts @@ -0,0 +1,180 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("static calls", () => { + useEphemeralIgnitionProject("minimal"); + + it("should be able to use the output of a static call in a contract at", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const account1 = m.getAccount(1); + + const fooFactory = m.contract("FooFactory", [], { from: account1 }); + + const createCall = m.call(fooFactory, "create", []); + + const newAddress = m.staticCall(fooFactory, "deployed", [], 0, { + after: [createCall], + }); + + const foo = m.contractAt("Foo", newAddress); + + return { fooFactory, foo }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.equal(await result.fooFactory.read.isDeployed(), true); + assert.equal(await result.foo.read.x(), 1n); + }); + + it("should be able to use the output of a static call in an artifact contract at", async function () { + const artifact = await this.hre.artifacts.readArtifact("Foo"); + + const moduleDefinition = buildModule("FooModule", (m) => { + const account1 = m.getAccount(1); + + const fooFactory = m.contract("FooFactory", [], { from: account1 }); + + const createCall = m.call(fooFactory, "create", []); + + const newAddress = m.staticCall(fooFactory, "deployed", [], 0, { + after: [createCall], + }); + + const foo = m.contractAt("Foo", artifact, newAddress); + + return { fooFactory, foo }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.equal(await result.fooFactory.read.isDeployed(), true); + assert.equal(await result.foo.read.x(), 1n); + }); + + it("should be able to use the output of a static call function in a contract at (with arg)", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const account1 = m.getAccount(1); + + const fooFactory = m.contract("FooFactory", [], { from: account1 }); + + const createCall = m.call(fooFactory, "create", []); + + const newAddress = m.staticCall(fooFactory, "allDeployed", [0], 0, { + after: [createCall], + }); + + const foo = m.contractAt("Foo", newAddress); + + return { fooFactory, foo }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.equal(await result.fooFactory.read.isDeployed(), true); + assert.equal(await result.foo.read.x(), 1n); + }); + + it("should be able to use the output of a static call function in a contract at (with function signature)", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const account1 = m.getAccount(1); + + const fooFactory = m.contract("FooFactory", [], { from: account1 }); + + const createCall = m.call(fooFactory, "create", []); + + const newAddress = m.staticCall( + fooFactory, + "getDeployed(uint256)", + [0], + 0, + { + after: [createCall], + } + ); + + const foo = m.contractAt("Foo", newAddress); + + return { fooFactory, foo }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.equal(await result.fooFactory.read.isDeployed(), true); + assert.equal(await result.foo.read.x(), 1n); + }); + + it("should be able to use the output of a static call with an indexed tuple result", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const tupleContract = m.contract("TupleReturn"); + + const arg1 = m.staticCall(tupleContract, "getTuple", [], "arg1", { + id: "arg1", + }); + const arg2 = m.staticCall(tupleContract, "getTuple", [], "arg2", { + id: "arg2", + }); + + m.call(tupleContract, "verifyArg1", [arg1], { id: "call1" }); + m.call(tupleContract, "verifyArg2", [arg2], { id: "call2" }); + + return { tupleContract }; + }); + + const result = await this.hre.ignition.deploy(moduleDefinition); + + assert.equal(await result.tupleContract.read.arg1Captured(), true); + assert.equal(await result.tupleContract.read.arg2Captured(), true); + }); + + it("should not be able to use the output of a non-address static call in a contract at", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const account1 = m.getAccount(1); + + const fooFactory = m.contract("FooFactory", [], { from: account1 }); + + const createCall = m.call(fooFactory, "create", []); + + const nonAddress = m.staticCall(fooFactory, "nonAddressResult", [], 0, { + after: [createCall], + }); + + const foo = m.contractAt("Foo", nonAddress); + + return { fooFactory, foo }; + }); + + await assert.isRejected( + this.hre.ignition.deploy(moduleDefinition), + /Future 'FooModule#FooFactory.nonAddressResult' must be a valid address/ + ); + }); + + it("should not be able to use the output of a non-address static call in an artifact contract at", async function () { + const artifact = await this.hre.artifacts.readArtifact("Foo"); + + const moduleDefinition = buildModule("FooModule", (m) => { + const account1 = m.getAccount(1); + + const fooFactory = m.contract("FooFactory", [], { from: account1 }); + + const createCall = m.call(fooFactory, "create", []); + + const nonAddress = m.staticCall(fooFactory, "nonAddressResult", [], 0, { + after: [createCall], + }); + + const foo = m.contractAt("Foo", artifact, nonAddress); + + return { fooFactory, foo }; + }); + + await assert.isRejected( + this.hre.ignition.deploy(moduleDefinition), + /Future 'FooModule#FooFactory.nonAddressResult' must be a valid address/ + ); + }); +}); diff --git a/packages/hardhat-ignition/test/module-api/use-module.ts b/packages/hardhat-ignition/test/module-api/use-module.ts new file mode 100644 index 0000000000..27a4894586 --- /dev/null +++ b/packages/hardhat-ignition/test/module-api/use-module.ts @@ -0,0 +1,77 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("useModule", function () { + useEphemeralIgnitionProject("minimal"); + + describe("returning futures from module usage", () => { + it("using useModule", async function () { + const thirdPartyModule = buildModule("ThirdPartySubmodule", (m) => { + const foo = m.contract("Foo"); + + return { foo }; + }); + + const userModule = buildModule("UserModule", (m) => { + const { foo } = m.useModule(thirdPartyModule); + + m.call(foo, "inc"); + + return { foo }; + }); + + const result = await this.hre.ignition.deploy(userModule); + + assert.equal(await result.foo.read.x(), 2n); + }); + }); + + describe("modules depending on other modules contracts", () => { + it("should execute all in a module before any that depends on a contract within the module", async function () { + const firstSecondAndThirdModule = buildModule( + "SecondAndThirdCallModule", + (m) => { + const trace = m.contract("Trace", ["first"]); + + const secondCall = m.call(trace, "addEntry", ["second"]); + + m.call(trace, "addEntry", ["third"], { + id: "third_add_entry", + after: [secondCall], + }); + + return { trace }; + } + ); + + const fourthCallModule = buildModule("FourthCallModule", (m) => { + const { trace } = m.useModule(firstSecondAndThirdModule); + + m.call(trace, "addEntry", ["fourth"]); + + return { trace }; + }); + + const userModule = buildModule("UserModule", (m) => { + const { trace } = m.useModule(fourthCallModule); + + return { trace }; + }); + + const result = await this.hre.ignition.deploy(userModule); + + const entry1 = await result.trace.read.entries([0n]); + const entry2 = await result.trace.read.entries([1n]); + const entry3 = await result.trace.read.entries([2n]); + const entry4 = await result.trace.read.entries([3n]); + + assert.deepStrictEqual( + [entry1, entry2, entry3, entry4], + ["first", "second", "third", "fourth"] + ); + }); + }); +}); diff --git a/packages/hardhat-ignition/test/module-parameters.ts b/packages/hardhat-ignition/test/module-parameters.ts new file mode 100644 index 0000000000..5e476c4bd0 --- /dev/null +++ b/packages/hardhat-ignition/test/module-parameters.ts @@ -0,0 +1,190 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { useEphemeralIgnitionProject } from "./test-helpers/use-ignition-project"; + +describe("module parameters", () => { + describe("a standard hardhat project", () => { + useEphemeralIgnitionProject("lock"); + + it("should run if provided with a valid module parameters file", async function () { + await this.hre.run( + { + scope: "ignition", + task: "deploy", + }, + { + modulePath: "./ignition/modules/Lock.ts", + parameters: "./ignition/modules/parameters.json", + } + ); + }); + + it("should run if provided with a valid module parameters file in JSON5 format", async function () { + await this.hre.run( + { + scope: "ignition", + task: "deploy", + }, + { + modulePath: "./ignition/modules/Lock.ts", + parameters: "./ignition/modules/parameters-json5.json5", + } + ); + }); + + it("should run if provided with a valid module parameters file encoding a bigint as a string", async function () { + await this.hre.run( + { + scope: "ignition", + task: "deploy", + }, + { + modulePath: "./ignition/modules/Lock.ts", + parameters: "./ignition/modules/parameters-bigints-as-strings.json", + } + ); + }); + + it("should fail if the module path is invalid", async function () { + await assert.isRejected( + this.hre.run( + { + scope: "ignition", + task: "deploy", + }, + { + modulePath: "./ignition/modules/nonexistant.ts", + } + ), + /Could not find a module file at the path: .\/ignition\/modules\/nonexistant.ts/ + ); + }); + + it("should fail if the module parameters path is invalid", async function () { + await assert.isRejected( + this.hre.run( + { + scope: "ignition", + task: "deploy", + }, + { + modulePath: "./ignition/modules/nonexistant.ts", + parameters: "./ignition/modules/nonexistant.json", + } + ), + /Could not find a module file at the path: .\/ignition\/modules\/nonexistant.ts/ + ); + }); + + it("should fail if parameters file number is larger than allowed", async function () { + await assert.isRejected( + this.hre.run( + { + scope: "ignition", + task: "deploy", + }, + { + modulePath: "./ignition/modules/Lock.ts", + parameters: "./ignition/modules/parameters-too-large.json", + } + ), + /Parameter "unlockTime" exceeds maximum safe integer size. Encode the value as a string using bigint notation: `\${value}n`/ + ); + }); + + it("should use a global parameter if no module parameter is available", async function () { + const ignitionModule = buildModule("Test", (m) => { + const unlockTime = m.getParameter("unlockTime"); + + const lock = m.contract("Lock", [unlockTime]); + + return { lock }; + }); + + const result = await this.hre.ignition.deploy(ignitionModule, { + parameters: { $global: { unlockTime: 1893499200000 } }, + }); + + assert.equal(await result.lock.read.unlockTime(), 1893499200000); + }); + + it("should use a global parameter instead of the default value", async function () { + const ignitionModule = buildModule("Test", (m) => { + const unlockTime = m.getParameter("unlockTime", 100); + + const lock = m.contract("Lock", [unlockTime]); + + return { lock }; + }); + + const result = await this.hre.ignition.deploy(ignitionModule, { + parameters: { $global: { unlockTime: 1893499200000 } }, + }); + + assert.equal(await result.lock.read.unlockTime(), 1893499200000); + }); + + it("should use the module parameter even if global parameters exist but not that specific parameter", async function () { + const ignitionModule = buildModule("Test", (m) => { + const unlockTime = m.getParameter("moduleLevelParam"); + + const lock = m.contract("Lock", [unlockTime]); + + return { lock }; + }); + + const result = await this.hre.ignition.deploy(ignitionModule, { + parameters: { + $global: { globalLevelParam: "should-not-be-read" }, + Test: { + moduleLevelParam: 1893499200000, + }, + }, + }); + + assert.equal(await result.lock.read.unlockTime(), 1893499200000); + }); + + it("should use the global parameter even if module parameters exist but not that specific parameter", async function () { + const ignitionModule = buildModule("Test", (m) => { + const unlockTime = m.getParameter("globalLevelParam"); + + const lock = m.contract("Lock", [unlockTime]); + + return { lock }; + }); + + const result = await this.hre.ignition.deploy(ignitionModule, { + parameters: { + $global: { globalLevelParam: 1893499200000 }, + Test: { + moduleLevelParam: "should-not-be-read", + }, + }, + }); + + assert.equal(await result.lock.read.unlockTime(), 1893499200000); + }); + + it("should use a module parameter instead of a global parameter if both are present", async function () { + const ignitionModule = buildModule("Test", (m) => { + const unlockTime = m.getParameter("unlockTime", 100); + + const lock = m.contract("Lock", [unlockTime]); + + return { lock }; + }); + + const result = await this.hre.ignition.deploy(ignitionModule, { + parameters: { + $global: { unlockTime: 1893499200000 }, + Test: { unlockTime: 9876543210000 }, + }, + }); + + assert.equal(await result.lock.read.unlockTime(), 9876543210000); + }); + }); +}); diff --git a/packages/hardhat-ignition/test/plan/index.ts b/packages/hardhat-ignition/test/plan/index.ts new file mode 100644 index 0000000000..af4af6dc63 --- /dev/null +++ b/packages/hardhat-ignition/test/plan/index.ts @@ -0,0 +1,31 @@ +/* eslint-disable import/no-unused-modules */ +import { assert } from "chai"; +import { emptyDirSync, readdir } from "fs-extra"; +import path from "path"; + +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("visualize", () => { + useEphemeralIgnitionProject("minimal"); + + it("should create a visualization", async function () { + const visualizationPath = path.resolve("../minimal/cache/visualization"); + emptyDirSync(visualizationPath); + + await this.hre.run("compile", { quiet: true }); + await this.hre.run( + { + scope: "ignition", + task: "visualize", + }, + { + noOpen: true, + modulePath: "./ignition/modules/MyModule.js", + } + ); + + const files = await readdir(visualizationPath); + + assert(files.includes("index.html")); + }); +}); diff --git a/packages/hardhat-ignition/test/setup.ts b/packages/hardhat-ignition/test/setup.ts new file mode 100644 index 0000000000..83ca4a5922 --- /dev/null +++ b/packages/hardhat-ignition/test/setup.ts @@ -0,0 +1,11 @@ +/* eslint-disable import/no-unused-modules */ +import chai from "chai"; +import chaiAsPromised from "chai-as-promised"; +import sinon from "sinon"; + +chai.use(chaiAsPromised); +chai.config.truncateThreshold = 1000; + +afterEach(() => { + sinon.restore(); +}); diff --git a/packages/hardhat-ignition/test/strategies/create2.ts b/packages/hardhat-ignition/test/strategies/create2.ts new file mode 100644 index 0000000000..193aa01b68 --- /dev/null +++ b/packages/hardhat-ignition/test/strategies/create2.ts @@ -0,0 +1,254 @@ +/* eslint-disable import/no-unused-modules */ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; + +import { presignedTx } from "../test-helpers/createX-tx"; +import { externallyLoadedContractArtifact } from "../test-helpers/externally-loaded-contract"; +import { mineBlock } from "../test-helpers/mine-block"; +import { + useEphemeralIgnitionProject, + useFileIgnitionProject, +} from "../test-helpers/use-ignition-project"; +import { waitForPendingTxs } from "../test-helpers/wait-for-pending-txs"; + +describe("create2", function () { + const example32ByteSalt = + "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"; + const anotherExample32ByteSalt = + "0xabcde67890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"; + + const EXPECTED_FOO_CREATE2_ADDRESS = + "0xA901a97D596320CC5b4E61f6B315F6128fAfF10B"; + const EXPECTED_BAR_CREATE2_ADDRESS = + "0x5985C19bc6ba6f9b3f9350Ba6c8156c8A9876E1a"; + const EXPECTED_CUSTOM_SALT_FOO_CREATE2_ADDRESS = + "0x2FbECc7173383C5878FF8EC336da0775CbF77fF7"; + + const moduleDefinition = buildModule("FooModule", (m) => { + // Use a known bytecode to ensure the same address is generated + // via create2 + const foo = m.contract("Foo", externallyLoadedContractArtifact); + + return { foo }; + }); + + describe("non-hardhat network", function () { + describe("preexisting createX contract", function () { + useEphemeralIgnitionProject("create2-exists-chain"); + + beforeEach(async function () { + await deployCreateXFactory(this.hre); + }); + + [ + "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", + "0x3C44CdDdB6a900fa2b585dd299e03d12FA4293BC", + "0x90F79bf6EB2c4f870365E785982E1f101E93b906", + ].forEach((accountAddress) => { + it(`should deploy a contract from account <${accountAddress}> using the createX factory to the expected address`, async function () { + const deployPromise = this.hre.ignition.deploy(moduleDefinition, { + strategy: "create2", + defaultSender: accountAddress, + strategyConfig: { + salt: example32ByteSalt, + }, + }); + + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + + const result = await deployPromise; + + assert.equal(result.foo.address, EXPECTED_FOO_CREATE2_ADDRESS); + + assert.equal(this.hre.network.config.chainId, 1); + assert.equal(await result.foo.read.x(), Number(1)); + }); + }); + + it(`should support endowing eth to the deployed contract`, async function () { + const deployPromise = this.hre.ignition.deploy( + buildModule("ValueModule", (m) => { + const foo = m.contract("Foo", [], { + value: 1_000_000_000n, + }); + + return { foo }; + }), + { + strategy: "create2", + strategyConfig: { + salt: example32ByteSalt, + }, + } + ); + + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + + const result = await deployPromise; + + const balance = await this.hre.network.provider.request({ + method: "eth_getBalance", + params: [result.foo.address, "latest"], + }); + + assert.equal(balance, 1_000_000_000n); + }); + + it(`should throw if you attempt to endow when the constructor isn't payable`, async function () { + await assert.isRejected( + this.hre.ignition.deploy( + buildModule("ValueModule", (m) => { + const foo = m.contract("Unpayable", [], { + value: 1_000_000_000n, + }); + + return { foo }; + }), + { + strategy: "create2", + strategyConfig: { + salt: example32ByteSalt, + }, + } + ), + /Simulating the transaction failed with error: Reverted with custom error FailedContractCreation/ + ); + }); + + it("should deploy with a custom salt", async function () { + const deployPromise = this.hre.ignition.deploy(moduleDefinition, { + strategy: "create2", + strategyConfig: { + salt: anotherExample32ByteSalt, + }, + }); + + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + + const result = await deployPromise; + + assert.equal( + result.foo.address, + EXPECTED_CUSTOM_SALT_FOO_CREATE2_ADDRESS + ); + + assert.equal(this.hre.network.config.chainId, 1); + assert.equal(await result.foo.read.x(), Number(1)); + }); + }); + + describe("no preexisting createX contract", function () { + useEphemeralIgnitionProject("create2-not-exists-chain"); + + it("should throw when no createX contract exists on the network", async function () { + assert.equal(this.hre.network.config.chainId, 88888); + await assert.isRejected( + this.hre.ignition.deploy(moduleDefinition, { + strategy: "create2", + strategyConfig: { + salt: example32ByteSalt, + }, + }), + /CreateX not deployed on current network 88888/ + ); + }); + }); + }); + + describe("hardhat network", function () { + useEphemeralIgnitionProject("minimal"); + + it("should deploy a createX factory then use it to deploy the given contract", async function () { + const deployPromise = this.hre.ignition.deploy(moduleDefinition, { + strategy: "create2", + strategyConfig: { + salt: example32ByteSalt, + }, + }); + + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + + const result = await deployPromise; + + assert.equal(result.foo.address, EXPECTED_FOO_CREATE2_ADDRESS); + + assert.equal(this.hre.network.config.chainId, 31337); + assert.equal(await result.foo.read.x(), Number(1)); + }); + + it("should use an existing createX factory to deploy the given contract", async function () { + // Run create2 once deploying the factory + const firstDeployPromise = this.hre.ignition.deploy(moduleDefinition, { + strategy: "create2", + strategyConfig: { + salt: example32ByteSalt, + }, + }); + + await waitForPendingTxs(this.hre, 1, firstDeployPromise); + await mineBlock(this.hre); + + await firstDeployPromise; + + // Run a second deploy, this time leveraging the existing create2 factory + const secondDeployPromise = this.hre.ignition.deploy( + buildModule("Second", (m) => { + const bar = m.contract("Bar"); + + return { bar }; + }), + { + strategy: "create2", + strategyConfig: { + salt: example32ByteSalt, + }, + } + ); + + await waitForPendingTxs(this.hre, 1, secondDeployPromise); + await mineBlock(this.hre); + + const secondDeployResult = await secondDeployPromise; + + assert.equal( + secondDeployResult.bar.address, + EXPECTED_BAR_CREATE2_ADDRESS + ); + assert(await secondDeployResult.bar.read.isBar()); + }); + }); + + describe("config", function () { + useFileIgnitionProject("create2-bad-config", "attempt-bad-config"); + + it("should throw if salt is not defined in Hardhat config", async function () { + await assert.isRejected( + this.hre.run( + { scope: "ignition", task: "deploy" }, + { + modulePath: "./ignition/modules/MyModule.js", + strategy: "create2", + } + ), + /IGN1102: Missing required strategy configuration parameter 'salt' for the strategy 'create2'/ + ); + }); + }); +}); + +async function deployCreateXFactory(hre: HardhatRuntimeEnvironment) { + await hre.network.provider.request({ + method: "hardhat_setBalance", + params: ["0xeD456e05CaAb11d66C4c797dD6c1D6f9A7F352b5", "0x58D15E176280000"], + }); + + await hre.network.provider.request({ + method: "eth_sendRawTransaction", + params: [presignedTx], + }); +} diff --git a/packages/hardhat-ignition/test/strategies/generic-strategy-constraints.ts b/packages/hardhat-ignition/test/strategies/generic-strategy-constraints.ts new file mode 100644 index 0000000000..e74f0b7101 --- /dev/null +++ b/packages/hardhat-ignition/test/strategies/generic-strategy-constraints.ts @@ -0,0 +1,241 @@ +import { buildModule } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { mineBlock } from "../test-helpers/mine-block"; +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; +import { waitForPendingTxs } from "../test-helpers/wait-for-pending-txs"; + +const strategies = ["basic", "create2"] as const; + +const exampleConfig = { + basic: {}, + create2: { + salt: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef", + }, +} as const; + +describe("strategies - generic constraints", function () { + strategies.forEach((strategy) => { + describe(strategy, function () { + useEphemeralIgnitionProject("minimal"); + + it("should deploy a contract", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const foo = m.contract("Foo"); + + return { foo }; + }); + + const deployPromise = this.hre.ignition.deploy(moduleDefinition, { + strategy, + strategyConfig: exampleConfig[strategy], + }); + + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + + const result = await deployPromise; + + assert.isDefined(result.foo.address); + + assert.equal(await result.foo.read.x(), Number(1)); + }); + + it("should deploy multiple contracts", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const foo = m.contract("Foo"); + const bar = m.contract("Bar"); + + return { foo, bar }; + }); + + const deployPromise = this.hre.ignition.deploy(moduleDefinition, { + strategy, + strategyConfig: exampleConfig[strategy], + }); + + await waitForPendingTxs(this.hre, 2, deployPromise); + await mineBlock(this.hre); + + const result = await deployPromise; + + assert.isDefined(result.foo.address); + assert.isDefined(result.bar.address); + + assert.equal(await result.foo.read.x(), Number(1)); + assert.equal(await result.bar.read.isBar(), true); + }); + + it("should call a contract function", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const foo = m.contract("Foo"); + + m.call(foo, "inc"); + + return { foo }; + }); + + const deployPromise = this.hre.ignition.deploy(moduleDefinition, { + strategy, + strategyConfig: exampleConfig[strategy], + }); + + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + + const result = await deployPromise; + + assert.isDefined(result.foo.address); + + assert.equal(await result.foo.read.x(), Number(2)); + }); + + it("should static call a contract function", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const foo = m.contract("Foo"); + + const firstInc = m.call(foo, "inc", [], { id: "inc1" }); + const secondInc = m.call(foo, "inc", [], { + id: "inc2", + after: [firstInc], + }); + + const counter = m.staticCall(foo, "x", [], 0, { + id: "inc3", + after: [secondInc], + }); + + m.call(foo, "incByPositiveNumber", [counter]); + + return { foo }; + }); + + const deployPromise = this.hre.ignition.deploy(moduleDefinition, { + strategy, + strategyConfig: exampleConfig[strategy], + }); + + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + + const result = await deployPromise; + + assert.isDefined(result.foo.address); + + assert.equal(await result.foo.read.x(), Number(6)); + }); + + it("should support using existing contracts", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const foo = m.contract("Foo"); + + return { foo }; + }); + + const deployPromise = this.hre.ignition.deploy(moduleDefinition); + + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + + const result = await deployPromise; + + const fooAddress = result.foo.address; + + const contractAtDefinition = buildModule("ContractAtModule", (m) => { + const contractAtFoo = m.contractAt("Foo", fooAddress); + + m.call(contractAtFoo, "inc"); + + return { contractAtFoo }; + }); + + const contractAtPromise = this.hre.ignition.deploy( + contractAtDefinition, + { + strategy, + strategyConfig: exampleConfig[strategy], + } + ); + + await waitForPendingTxs(this.hre, 1, contractAtPromise); + await mineBlock(this.hre); + + const contractAtResult = await contractAtPromise; + + assert.equal(await contractAtResult.contractAtFoo.read.x(), Number(2)); + }); + + it("should read an event emitted from a constructor", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const foo = m.contract("EventArgValue"); + + const arg = m.readEventArgument(foo, "EventValue", "value"); + + // will revert if the event argument is not equal to 42 + m.call(foo, "validateEmitted", [arg]); + + return { foo }; + }); + + const deployPromise = this.hre.ignition.deploy(moduleDefinition, { + strategy, + strategyConfig: exampleConfig[strategy], + }); + + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + + const result = await deployPromise; + + assert.isDefined(result.foo.address); + + assert.equal(await result.foo.read.argWasValidated(), true); + }); + + it("should read an event emitted from a function", async function () { + const moduleDefinition = buildModule("FooModule", (m) => { + const foo = m.contract("SendDataEmitter"); + + const eventCall = m.call(foo, "emitEvent"); + + const arg = m.readEventArgument(eventCall, "SendDataEvent", "arg", { + emitter: foo, + }); + + // will revert if the event argument is not equal to 42 + m.call(foo, "validateEmitted", [arg]); + + return { foo }; + }); + + const deployPromise = this.hre.ignition.deploy(moduleDefinition, { + strategy, + strategyConfig: exampleConfig[strategy], + }); + + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + await waitForPendingTxs(this.hre, 1, deployPromise); + await mineBlock(this.hre); + + const result = await deployPromise; + + assert.isDefined(result.foo.address); + + assert.equal(await result.foo.read.wasEmitted(), true); + }); + }); + }); +}); diff --git a/packages/hardhat-ignition/test/strategies/only-built-in-strategies.ts b/packages/hardhat-ignition/test/strategies/only-built-in-strategies.ts new file mode 100644 index 0000000000..0c0ce70461 --- /dev/null +++ b/packages/hardhat-ignition/test/strategies/only-built-in-strategies.ts @@ -0,0 +1,20 @@ +import { assert } from "chai"; + +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("strategies - only built in strategies", function () { + useEphemeralIgnitionProject("minimal"); + + it("should throw if a non-recognized strategy is specified", async function () { + await assert.isRejected( + this.hre.run( + { scope: "ignition", task: "deploy" }, + { + modulePath: "./ignition/modules/MyModule.js", + strategy: "non-recognized-strategy", + } + ), + /Invalid strategy name, must be either 'basic' or 'create2'/ + ); + }); +}); diff --git a/packages/hardhat-ignition/test/test-helpers/clear-pending-transactions-from-memory-pool.ts b/packages/hardhat-ignition/test/test-helpers/clear-pending-transactions-from-memory-pool.ts new file mode 100644 index 0000000000..04044b50a0 --- /dev/null +++ b/packages/hardhat-ignition/test/test-helpers/clear-pending-transactions-from-memory-pool.ts @@ -0,0 +1,33 @@ +import { assert } from "chai"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; + +export async function clearPendingTransactionsFromMemoryPool( + hre: HardhatRuntimeEnvironment +): Promise { + const pendingBlockBefore = await hre.network.provider.send( + "eth_getBlockByNumber", + ["pending", false] + ); + + assert( + pendingBlockBefore.transactions.length > 0, + "Clearing an empty mempool" + ); + + for (const hash of pendingBlockBefore.transactions) { + await hre.network.provider.request({ + method: "hardhat_dropTransaction", + params: [hash], + }); + } + + const pendingBlockAfter = await hre.network.provider.send( + "eth_getBlockByNumber", + ["pending", false] + ); + + assert( + pendingBlockAfter.transactions.length === 0, + "All blocks should be cleared" + ); +} diff --git a/packages/hardhat-ignition/test/test-helpers/createX-tx.ts b/packages/hardhat-ignition/test/test-helpers/createX-tx.ts new file mode 100644 index 0000000000..2df94f2a7a --- /dev/null +++ b/packages/hardhat-ignition/test/test-helpers/createX-tx.ts @@ -0,0 +1,2 @@ +export const presignedTx = + "0xf92f698085174876e800832dc6c08080b92f1660a06040523060805234801561001457600080fd5b50608051612e3e6100d860003960008181610603015281816107050152818161082b015281816108d50152818161127f01528181611375015281816113e00152818161141f015281816114a7015281816115b3015281816117d20152818161183d0152818161187c0152818161190401528181611ac501528181611c7801528181611ce301528181611d2201528181611daa01528181611fe901528181612206015281816122f20152818161244d015281816124a601526125820152612e3e6000f3fe60806040526004361061018a5760003560e01c806381503da1116100d6578063d323826a1161007f578063e96deee411610059578063e96deee414610395578063f5745aba146103a8578063f9664498146103bb57600080fd5b8063d323826a1461034f578063ddda0acb1461036f578063e437252a1461038257600080fd5b80639c36a286116100b05780639c36a28614610316578063a7db93f214610329578063c3fe107b1461033c57600080fd5b806381503da1146102d0578063890c283b146102e357806398e810771461030357600080fd5b80632f990e3f116101385780636cec2536116101125780636cec25361461027d57806374637a7a1461029d5780637f565360146102bd57600080fd5b80632f990e3f1461023757806331a7c8c81461024a57806342d654fc1461025d57600080fd5b806327fe18221161016957806327fe1822146101f15780632852527a1461020457806328ddd0461461021757600080fd5b8062d84acb1461018f57806326307668146101cb57806326a32fc7146101de575b600080fd5b6101a261019d366004612915565b6103ce565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6101a26101d9366004612994565b6103e6565b6101a26101ec3660046129db565b610452565b6101a26101ff3660046129db565b6104de565b6101a2610212366004612a39565b610539565b34801561022357600080fd5b506101a2610232366004612a90565b6106fe565b6101a2610245366004612aa9565b61072a565b6101a2610258366004612aa9565b6107bb565b34801561026957600080fd5b506101a2610278366004612b1e565b6107c9565b34801561028957600080fd5b506101a2610298366004612a90565b610823565b3480156102a957600080fd5b506101a26102b8366004612b4a565b61084f565b6101a26102cb3660046129db565b611162565b6101a26102de366004612b74565b6111e8565b3480156102ef57600080fd5b506101a26102fe366004612bac565b611276565b6101a2610311366004612bce565b6112a3565b6101a2610324366004612994565b611505565b6101a2610337366004612c49565b6116f1565b6101a261034a366004612aa9565b611964565b34801561035b57600080fd5b506101a261036a366004612cd9565b6119ed565b6101a261037d366004612c49565b611a17565b6101a2610390366004612bce565b611e0c565b6101a26103a3366004612915565b611e95565b6101a26103b6366004612bce565b611ea4565b6101a26103c9366004612b74565b611f2d565b60006103dd8585858533611a17565b95945050505050565b6000806103f2846120db565b90508083516020850134f59150610408826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a35092915050565b60006104d86104d260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b836103e6565b92915050565b600081516020830134f090506104f3816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a2919050565b600080610545856120db565b905060008460601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf300000000000000000000000000000000006028820152826037826000f593505073ffffffffffffffffffffffffffffffffffffffff8316610635576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001660048201526024015b60405180910390fd5b604051829073ffffffffffffffffffffffffffffffffffffffff8516907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808473ffffffffffffffffffffffffffffffffffffffff1634876040516106a19190612d29565b60006040518083038185875af1925050503d80600081146106de576040519150601f19603f3d011682016040523d82523d6000602084013e6106e3565b606091505b50915091506106f382828961247d565b505050509392505050565b60006104d87f00000000000000000000000000000000000000000000000000000000000000008361084f565b60006107b36107aa60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b85858533611a17565b949350505050565b60006107b3848484336112a3565b60006040518260005260ff600b53836020527f21c35dbe1b344a2488cf3321d6ce542f8e9f305544ff09e4993a62319a497c1f6040526055600b20601452806040525061d694600052600160345350506017601e20919050565b60006104d8827f00000000000000000000000000000000000000000000000000000000000000006107c9565b600060607f9400000000000000000000000000000000000000000000000000000000000000610887600167ffffffffffffffff612d45565b67ffffffffffffffff16841115610902576040517f3c55ab3b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b836000036109c7576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f800000000000000000000000000000000000000000000000000000000000000060368201526037015b6040516020818303038152906040529150611152565b607f8411610a60576040517fd60000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b16602283015260f886901b1660368201526037016109b1565b60ff8411610b1f576040517fd70000000000000000000000000000000000000000000000000000000000000060208201527fff0000000000000000000000000000000000000000000000000000000000000080831660218301527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606088901b1660228301527f8100000000000000000000000000000000000000000000000000000000000000603683015260f886901b1660378201526038016109b1565b61ffff8411610bff576040517fd80000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f820000000000000000000000000000000000000000000000000000000000000060368201527fffff00000000000000000000000000000000000000000000000000000000000060f086901b1660378201526039016109b1565b62ffffff8411610ce0576040517fd90000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f830000000000000000000000000000000000000000000000000000000000000060368201527fffffff000000000000000000000000000000000000000000000000000000000060e886901b166037820152603a016109b1565b63ffffffff8411610dc2576040517fda0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f840000000000000000000000000000000000000000000000000000000000000060368201527fffffffff0000000000000000000000000000000000000000000000000000000060e086901b166037820152603b016109b1565b64ffffffffff8411610ea5576040517fdb0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f850000000000000000000000000000000000000000000000000000000000000060368201527fffffffffff00000000000000000000000000000000000000000000000000000060d886901b166037820152603c016109b1565b65ffffffffffff8411610f89576040517fdc0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f860000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffff000000000000000000000000000000000000000000000000000060d086901b166037820152603d016109b1565b66ffffffffffffff841161106e576040517fdd0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f870000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffff0000000000000000000000000000000000000000000000000060c886901b166037820152603e016109b1565b6040517fde0000000000000000000000000000000000000000000000000000000000000060208201527fff00000000000000000000000000000000000000000000000000000000000000821660218201527fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606087901b1660228201527f880000000000000000000000000000000000000000000000000000000000000060368201527fffffffffffffffff00000000000000000000000000000000000000000000000060c086901b166037820152603f0160405160208183030381529060405291505b5080516020909101209392505050565b60006104d86111e260408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b83611505565b600061126f61126860408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b8484610539565b9392505050565b600061126f83837f00000000000000000000000000000000000000000000000000000000000000006119ed565b60008451602086018451f090506112b9816123d3565b60405173ffffffffffffffffffffffffffffffffffffffff8216907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808273ffffffffffffffffffffffffffffffffffffffff168560200151876040516113279190612d29565b60006040518083038185875af1925050503d8060008114611364576040519150601f19603f3d011682016040523d82523d6000602084013e611369565b606091505b5091509150816113c9577f0000000000000000000000000000000000000000000000000000000000000000816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001631156114fb578373ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611495576040519150601f19603f3d011682016040523d82523d6000602084013e61149a565b606091505b509092509050816114fb577f0000000000000000000000000000000000000000000000000000000000000000816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b5050949350505050565b600080611511846120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff81166115e0576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a361162c83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1634876040516116569190612d29565b60006040518083038185875af1925050503d8060008114611693576040519150601f19603f3d011682016040523d82523d6000602084013e611698565b606091505b505090506116a681866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a25050505092915050565b6000806116fd876120db565b9050808651602088018651f59150611714826123d3565b604051819073ffffffffffffffffffffffffffffffffffffffff8416907fb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f790600090a36000808373ffffffffffffffffffffffffffffffffffffffff168660200151886040516117849190612d29565b60006040518083038185875af1925050503d80600081146117c1576040519150601f19603f3d011682016040523d82523d6000602084013e6117c6565b606091505b509150915081611826577f0000000000000000000000000000000000000000000000000000000000000000816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163115611958578473ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d80600081146118f2576040519150601f19603f3d011682016040523d82523d6000602084013e6118f7565b606091505b50909250905081611958577f0000000000000000000000000000000000000000000000000000000000000000816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b50505095945050505050565b60006107b36119e460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b858585336116f1565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b600080611a23876120db565b905060006040518060400160405280601081526020017f67363d3d37363d34f03d5260086018f30000000000000000000000000000000081525090506000828251602084016000f5905073ffffffffffffffffffffffffffffffffffffffff8116611af2576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b604051839073ffffffffffffffffffffffffffffffffffffffff8316907f2feea65dd4e9f9cbd86b74b7734210c59a1b2981b5b137bd0ee3e208200c906790600090a3611b3e83610823565b935060008173ffffffffffffffffffffffffffffffffffffffff1687600001518a604051611b6c9190612d29565b60006040518083038185875af1925050503d8060008114611ba9576040519150601f19603f3d011682016040523d82523d6000602084013e611bae565b606091505b50509050611bbc81866124ff565b60405173ffffffffffffffffffffffffffffffffffffffff8616907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a260608573ffffffffffffffffffffffffffffffffffffffff1688602001518a604051611c299190612d29565b60006040518083038185875af1925050503d8060008114611c66576040519150601f19603f3d011682016040523d82523d6000602084013e611c6b565b606091505b50909250905081611ccc577f0000000000000000000000000000000000000000000000000000000000000000816040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163115611dfe578673ffffffffffffffffffffffffffffffffffffffff167f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163160405160006040518083038185875af1925050503d8060008114611d98576040519150601f19603f3d011682016040523d82523d6000602084013e611d9d565b606091505b50909250905081611dfe577f0000000000000000000000000000000000000000000000000000000000000000816040517fc2b3f44500000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050505095945050505050565b60006103dd611e8c60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b868686866116f1565b60006103dd85858585336116f1565b60006103dd611f2460408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b86868686611a17565b6000808360601b90506040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528160148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f092505073ffffffffffffffffffffffffffffffffffffffff8216612016576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b60405173ffffffffffffffffffffffffffffffffffffffff8316907f4db17dd5e4732fb6da34a148104a592783ca119a1e7bb8829eba6cbadef0b51190600090a26000808373ffffffffffffffffffffffffffffffffffffffff1634866040516120809190612d29565b60006040518083038185875af1925050503d80600081146120bd576040519150601f19603f3d011682016040523d82523d6000602084013e6120c2565b606091505b50915091506120d282828861247d565b50505092915050565b60008060006120e9846125b3565b9092509050600082600281111561210257612102612e02565b1480156121205750600081600281111561211e5761211e612e02565b145b1561215e57604080513360208201524691810191909152606081018590526080016040516020818303038152906040528051906020012092506123cc565b600082600281111561217257612172612e02565b1480156121905750600181600281111561218e5761218e612e02565b145b156121b0576121a9338560009182526020526040902090565b92506123cc565b60008260028111156121c4576121c4612e02565b03612233576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b600182600281111561224757612247612e02565b1480156122655750600081600281111561226357612263612e02565b145b1561227e576121a9468560009182526020526040902090565b600182600281111561229257612292612e02565b1480156122b0575060028160028111156122ae576122ae612e02565b145b1561231f576040517f13b3a2a100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b61239a60408051437fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101406020830152419282019290925260608101919091524260808201524460a08201524660c08201523360e08201526000906101000160405160208183030381529060405280519060200120905090565b84036123a657836123c9565b604080516020810186905201604051602081830303815290604052805190602001205b92505b5050919050565b73ffffffffffffffffffffffffffffffffffffffff8116158061240b575073ffffffffffffffffffffffffffffffffffffffff81163b155b1561247a576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b50565b82158061249f575073ffffffffffffffffffffffffffffffffffffffff81163b155b156124fa577f0000000000000000000000000000000000000000000000000000000000000000826040517fa57ca23900000000000000000000000000000000000000000000000000000000815260040161062c929190612d94565b505050565b811580612520575073ffffffffffffffffffffffffffffffffffffffff8116155b80612540575073ffffffffffffffffffffffffffffffffffffffff81163b155b156125af576040517fc05cee7a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016600482015260240161062c565b5050565b600080606083901c3314801561261057508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b1561262057506000905080915091565b606083901c3314801561265a57507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561266b5750600090506001915091565b33606084901c036126825750600090506002915091565b606083901c1580156126db57508260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000145b156126ec5750600190506000915091565b606083901c15801561272557507fff00000000000000000000000000000000000000000000000000000000000000601484901a60f81b16155b1561273557506001905080915091565b606083901c61274a5750600190506002915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167f0100000000000000000000000000000000000000000000000000000000000000036127a55750600290506000915091565b8260141a60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166000036127e15750600290506001915091565b506002905080915091565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261282c57600080fd5b813567ffffffffffffffff80821115612847576128476127ec565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561288d5761288d6127ec565b816040528381528660208588010111156128a657600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000604082840312156128d857600080fd5b6040516040810181811067ffffffffffffffff821117156128fb576128fb6127ec565b604052823581526020928301359281019290925250919050565b60008060008060a0858703121561292b57600080fd5b84359350602085013567ffffffffffffffff8082111561294a57600080fd5b6129568883890161281b565b9450604087013591508082111561296c57600080fd5b506129798782880161281b565b92505061298986606087016128c6565b905092959194509250565b600080604083850312156129a757600080fd5b82359150602083013567ffffffffffffffff8111156129c557600080fd5b6129d18582860161281b565b9150509250929050565b6000602082840312156129ed57600080fd5b813567ffffffffffffffff811115612a0457600080fd5b6107b38482850161281b565b803573ffffffffffffffffffffffffffffffffffffffff81168114612a3457600080fd5b919050565b600080600060608486031215612a4e57600080fd5b83359250612a5e60208501612a10565b9150604084013567ffffffffffffffff811115612a7a57600080fd5b612a868682870161281b565b9150509250925092565b600060208284031215612aa257600080fd5b5035919050565b600080600060808486031215612abe57600080fd5b833567ffffffffffffffff80821115612ad657600080fd5b612ae28783880161281b565b94506020860135915080821115612af857600080fd5b50612b058682870161281b565b925050612b1585604086016128c6565b90509250925092565b60008060408385031215612b3157600080fd5b82359150612b4160208401612a10565b90509250929050565b60008060408385031215612b5d57600080fd5b612b6683612a10565b946020939093013593505050565b60008060408385031215612b8757600080fd5b612b9083612a10565b9150602083013567ffffffffffffffff8111156129c557600080fd5b60008060408385031215612bbf57600080fd5b50508035926020909101359150565b60008060008060a08587031215612be457600080fd5b843567ffffffffffffffff80821115612bfc57600080fd5b612c088883890161281b565b95506020870135915080821115612c1e57600080fd5b50612c2b8782880161281b565b935050612c3b86604087016128c6565b915061298960808601612a10565b600080600080600060c08688031215612c6157600080fd5b85359450602086013567ffffffffffffffff80821115612c8057600080fd5b612c8c89838a0161281b565b95506040880135915080821115612ca257600080fd5b50612caf8882890161281b565b935050612cbf87606088016128c6565b9150612ccd60a08701612a10565b90509295509295909350565b600080600060608486031215612cee57600080fd5b8335925060208401359150612b1560408501612a10565b60005b83811015612d20578181015183820152602001612d08565b50506000910152565b60008251612d3b818460208701612d05565b9190910192915050565b67ffffffffffffffff828116828216039080821115612d8d577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b5092915050565b73ffffffffffffffffffffffffffffffffffffffff831681526040602082015260008251806040840152612dcf816060850160208701612d05565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016060019392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fdfea164736f6c6343000817000a1ca005f70bf8a1493291468f36ef23b05eb3a4f1807f6b4022942a4104b7537bfc36a029528c0c29546c81e7d78b0277ef87031541bdc96427b246ecedb6d74cd3ed62"; diff --git a/packages/hardhat-ignition/test/test-helpers/externally-loaded-contract.ts b/packages/hardhat-ignition/test/test-helpers/externally-loaded-contract.ts new file mode 100644 index 0000000000..cd8f2a6172 --- /dev/null +++ b/packages/hardhat-ignition/test/test-helpers/externally-loaded-contract.ts @@ -0,0 +1,94 @@ +/** + * This is the artifact of a contract that is not part of the compilation output. + * + * Based on the following Solidity: + * + * ``` + contract ExternallyLoadedContract { + bool public isExternallyLoaded = true; + uint256 public x = 1; + + function buildMessage( + string memory message + ) public pure returns (string memory) { + return string.concat("A message: ", message); + } + + function inc() public returns (uint256) { + x++; + return x; + } + } + * ``` + */ +export const externallyLoadedContractArtifact = { + _format: "hh-sol-artifact-1", + contractName: "ExternallyLoadedContract", + sourceName: "contracts/Foo.sol", + abi: [ + { + inputs: [ + { + internalType: "string", + name: "message", + type: "string", + }, + ], + name: "buildMessage", + outputs: [ + { + internalType: "string", + name: "", + type: "string", + }, + ], + stateMutability: "pure", + type: "function", + }, + { + inputs: [], + name: "inc", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "nonpayable", + type: "function", + }, + { + inputs: [], + name: "isExternallyLoaded", + outputs: [ + { + internalType: "bool", + name: "", + type: "bool", + }, + ], + stateMutability: "view", + type: "function", + }, + { + inputs: [], + name: "x", + outputs: [ + { + internalType: "uint256", + name: "", + type: "uint256", + }, + ], + stateMutability: "view", + type: "function", + }, + ], + bytecode: + "0x608060405260016000806101000a81548160ff0219169083151502179055506001805534801561002e57600080fd5b506105208061003e6000396000f3fe608060405234801561001057600080fd5b506004361061004c5760003560e01c80630c55699c14610051578063371303c01461006f578063ae78e06b1461008d578063c4a5693d146100ab575b600080fd5b6100596100db565b6040516100669190610156565b60405180910390f35b6100776100e1565b6040516100849190610156565b60405180910390f35b610095610103565b6040516100a2919061018c565b60405180910390f35b6100c560048036038101906100c09190610301565b610114565b6040516100d291906103c9565b60405180910390f35b60015481565b6000600160008154809291906100f69061041a565b9190505550600154905090565b60008054906101000a900460ff1681565b60608160405160200161012791906104c4565b6040516020818303038152906040529050919050565b6000819050919050565b6101508161013d565b82525050565b600060208201905061016b6000830184610147565b92915050565b60008115159050919050565b61018681610171565b82525050565b60006020820190506101a1600083018461017d565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61020e826101c5565b810181811067ffffffffffffffff8211171561022d5761022c6101d6565b5b80604052505050565b60006102406101a7565b905061024c8282610205565b919050565b600067ffffffffffffffff82111561026c5761026b6101d6565b5b610275826101c5565b9050602081019050919050565b82818337600083830152505050565b60006102a461029f84610251565b610236565b9050828152602081018484840111156102c0576102bf6101c0565b5b6102cb848285610282565b509392505050565b600082601f8301126102e8576102e76101bb565b5b81356102f8848260208601610291565b91505092915050565b600060208284031215610317576103166101b1565b5b600082013567ffffffffffffffff811115610335576103346101b6565b5b610341848285016102d3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610384578082015181840152602081019050610369565b60008484015250505050565b600061039b8261034a565b6103a58185610355565b93506103b5818560208601610366565b6103be816101c5565b840191505092915050565b600060208201905081810360008301526103e38184610390565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006104258261013d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610457576104566103eb565b5b600182019050919050565b7f41206d6573736167653a20000000000000000000000000000000000000000000815250565b600081905092915050565b600061049e8261034a565b6104a88185610488565b93506104b8818560208601610366565b80840191505092915050565b60006104cf82610462565b600b820191506104df8284610493565b91508190509291505056fea2646970667358221220d6f949c606fe2cf1b3274ef889cd952363a9558f9f5027ee18f03fe4c4cbaee864736f6c63430008130033", + deployedBytecode: + "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c80630c55699c14610051578063371303c01461006f578063ae78e06b1461008d578063c4a5693d146100ab575b600080fd5b6100596100db565b6040516100669190610156565b60405180910390f35b6100776100e1565b6040516100849190610156565b60405180910390f35b610095610103565b6040516100a2919061018c565b60405180910390f35b6100c560048036038101906100c09190610301565b610114565b6040516100d291906103c9565b60405180910390f35b60015481565b6000600160008154809291906100f69061041a565b9190505550600154905090565b60008054906101000a900460ff1681565b60608160405160200161012791906104c4565b6040516020818303038152906040529050919050565b6000819050919050565b6101508161013d565b82525050565b600060208201905061016b6000830184610147565b92915050565b60008115159050919050565b61018681610171565b82525050565b60006020820190506101a1600083018461017d565b92915050565b6000604051905090565b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61020e826101c5565b810181811067ffffffffffffffff8211171561022d5761022c6101d6565b5b80604052505050565b60006102406101a7565b905061024c8282610205565b919050565b600067ffffffffffffffff82111561026c5761026b6101d6565b5b610275826101c5565b9050602081019050919050565b82818337600083830152505050565b60006102a461029f84610251565b610236565b9050828152602081018484840111156102c0576102bf6101c0565b5b6102cb848285610282565b509392505050565b600082601f8301126102e8576102e76101bb565b5b81356102f8848260208601610291565b91505092915050565b600060208284031215610317576103166101b1565b5b600082013567ffffffffffffffff811115610335576103346101b6565b5b610341848285016102d3565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015610384578082015181840152602081019050610369565b60008484015250505050565b600061039b8261034a565b6103a58185610355565b93506103b5818560208601610366565b6103be816101c5565b840191505092915050565b600060208201905081810360008301526103e38184610390565b905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60006104258261013d565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203610457576104566103eb565b5b600182019050919050565b7f41206d6573736167653a20000000000000000000000000000000000000000000815250565b600081905092915050565b600061049e8261034a565b6104a88185610488565b93506104b8818560208601610366565b80840191505092915050565b60006104cf82610462565b600b820191506104df8284610493565b91508190509291505056fea2646970667358221220d6f949c606fe2cf1b3274ef889cd952363a9558f9f5027ee18f03fe4c4cbaee864736f6c63430008130033", + linkReferences: {}, + deployedLinkReferences: {}, +} as const; diff --git a/packages/hardhat-ignition/test/test-helpers/get-balance-for.ts b/packages/hardhat-ignition/test/test-helpers/get-balance-for.ts new file mode 100644 index 0000000000..8b0caba349 --- /dev/null +++ b/packages/hardhat-ignition/test/test-helpers/get-balance-for.ts @@ -0,0 +1,16 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; + +/** + * Get latest balance for an address. + */ +export async function getBalanceFor( + hre: HardhatRuntimeEnvironment, + address: string +): Promise { + const balance = await hre.network.provider.send("eth_getBalance", [ + address, + "latest", + ]); + + return BigInt(balance); +} diff --git a/packages/hardhat-ignition/test/test-helpers/mine-block.ts b/packages/hardhat-ignition/test/test-helpers/mine-block.ts new file mode 100644 index 0000000000..24092427d0 --- /dev/null +++ b/packages/hardhat-ignition/test/test-helpers/mine-block.ts @@ -0,0 +1,5 @@ +import { HardhatRuntimeEnvironment } from "hardhat/types"; + +export function mineBlock(hre: HardhatRuntimeEnvironment): Promise { + return hre.network.provider.send("evm_mine"); +} diff --git a/packages/hardhat-ignition/test/test-helpers/sleep.ts b/packages/hardhat-ignition/test/test-helpers/sleep.ts new file mode 100644 index 0000000000..d95e4b68e4 --- /dev/null +++ b/packages/hardhat-ignition/test/test-helpers/sleep.ts @@ -0,0 +1,2 @@ +export const sleep = (timeout: number) => + new Promise((res) => setTimeout(res, timeout)); diff --git a/packages/hardhat-ignition/test/test-helpers/test-ignition-helper.ts b/packages/hardhat-ignition/test/test-helpers/test-ignition-helper.ts new file mode 100644 index 0000000000..36d4498e9e --- /dev/null +++ b/packages/hardhat-ignition/test/test-helpers/test-ignition-helper.ts @@ -0,0 +1,212 @@ +import { + deploy, + DeployConfig, + DeploymentParameters, + DeploymentResultType, + EIP1193Provider, + Future, + IgnitionModule, + IgnitionModuleResult, + isContractFuture, + StrategyConfig, + SuccessfulDeploymentResult, +} from "@nomicfoundation/ignition-core"; +import { HardhatPluginError } from "hardhat/plugins"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { + createPublicClient, + custom, + getContract, + GetContractReturnType, +} from "viem"; +import { hardhat } from "viem/chains"; + +import { HardhatArtifactResolver } from "../../src/hardhat-artifact-resolver"; +import { errorDeploymentResultToExceptionMessage } from "../../src/utils/error-deployment-result-to-exception-message"; + +export type IgnitionModuleResultsTToViemContracts< + ContractNameT extends string, + IgnitionModuleResultsT extends IgnitionModuleResult +> = { + [contract in keyof IgnitionModuleResultsT]: TypeChainViemContractByName; +}; + +// TODO: This is a very permissive type to maintain the existing tests. +// We should work it up to the equivalent of the Viem Ignition helper. +// That implies solving how we get post compile type information for contracts. +export interface TypeChainViemContractByName { + address: string; + read: any; + write: any; +} + +export class TestIgnitionHelper { + public type = "test"; + + private _provider: EIP1193Provider; + private _deploymentDir: string | undefined; + + constructor( + private _hre: HardhatRuntimeEnvironment, + private _config?: Partial, + provider?: EIP1193Provider, + deploymentDir?: string + ) { + this._provider = provider ?? this._hre.network.provider; + this._deploymentDir = deploymentDir; + } + + public async deploy< + ModuleIdT extends string, + ContractNameT extends string, + IgnitionModuleResultsT extends IgnitionModuleResult, + StrategyT extends keyof StrategyConfig = "basic" + >( + ignitionModule: IgnitionModule< + ModuleIdT, + ContractNameT, + IgnitionModuleResultsT + >, + { + parameters = {}, + config: perDeployConfig = {}, + strategy: strategyName, + strategyConfig, + defaultSender = undefined, + }: { + parameters?: DeploymentParameters; + config?: Partial; + strategy?: StrategyT; + strategyConfig?: StrategyConfig[StrategyT]; + defaultSender?: string; + } = { + parameters: {}, + config: {}, + } + ): Promise< + IgnitionModuleResultsTToViemContracts + > { + const accounts = (await this._hre.network.provider.request({ + method: "eth_accounts", + })) as string[]; + + const artifactResolver = new HardhatArtifactResolver(this._hre); + + const resolvedConfig: Partial = { + ...this._config, + ...perDeployConfig, + }; + + const result = await deploy({ + config: resolvedConfig, + provider: this._provider, + deploymentDir: this._deploymentDir, + artifactResolver, + ignitionModule, + deploymentParameters: parameters, + accounts, + defaultSender, + strategy: strategyName, + strategyConfig, + }); + + if (result.type !== DeploymentResultType.SUCCESSFUL_DEPLOYMENT) { + const message = errorDeploymentResultToExceptionMessage(result); + + throw new HardhatPluginError("hardhat-ignition-test", message); + } + + const publicClient = createPublicClient({ + chain: hardhat, + transport: custom(this._hre.network.provider), + }); + + return this._toViemContracts( + this._hre, + ignitionModule, + result, + publicClient + ); + } + + private async _toViemContracts< + ModuleIdT extends string, + ContractNameT extends string, + IgnitionModuleResultsT extends IgnitionModuleResult + >( + hre: HardhatRuntimeEnvironment, + ignitionModule: IgnitionModule< + ModuleIdT, + ContractNameT, + IgnitionModuleResultsT + >, + result: SuccessfulDeploymentResult, + publicClient: any + ): Promise< + IgnitionModuleResultsTToViemContracts + > { + return Object.fromEntries( + await Promise.all( + Object.entries(ignitionModule.results).map( + async ([name, contractFuture]) => [ + name, + await this._getContract( + hre, + contractFuture, + result.contracts[contractFuture.id], + publicClient + ), + ] + ) + ) + ); + } + + private async _getContract( + hre: HardhatRuntimeEnvironment, + future: Future, + deployedContract: { address: string; contractName: string }, + publicClient: any + ): Promise { + if (!isContractFuture(future)) { + throw new HardhatPluginError( + "hardhat-ignition-viem", + `Expected contract future but got ${future.id} with type ${future.type} instead` + ); + } + + const contract: any = getContract({ + address: this._ensureAddressFormat(deployedContract.address), + abi: await this._loadAbiFromHHArtifactFolder( + hre, + deployedContract.contractName + ), + client: { public: publicClient }, + }); + + return contract; + } + + private _ensureAddressFormat(address: string): `0x${string}` { + if (!address.startsWith("0x")) { + return `0x${address}`; + } + + return `0x${address.slice(2)}`; + } + + private async _loadAbiFromHHArtifactFolder( + hre: HardhatRuntimeEnvironment, + contractName: string + ): Promise { + const artifact = await hre.artifacts.readArtifact(contractName); + + if (artifact === undefined) { + throw new Error( + `Test error: no hardcoded abi for contract ${contractName}` + ); + } + + return artifact.abi; + } +} diff --git a/packages/hardhat-ignition/test/test-helpers/type-helper.ts b/packages/hardhat-ignition/test/test-helpers/type-helper.ts new file mode 100644 index 0000000000..4d85892546 --- /dev/null +++ b/packages/hardhat-ignition/test/test-helpers/type-helper.ts @@ -0,0 +1,29 @@ +/** + * Given an object generate the type that is an array of the strings + * of the objects properties. + * + * @example + * type ExpectedConfigOptions = keyListOf + * Where ExpectedConfigOptions is the type level tuple: + * ``` + * [ + * "blockPollingInterval", + * "maxFeeBumps", + * "requiredConfirmations", + * "timeBeforeBumpingFees" + * ] + * ``` + */ +export type KeyListOf = ConvertObjectToTypeArray< + ConvertUnionToObject> +>; + +type ConvertUnionToObject = { + [key in U]: ConvertUnionToObject>; +}; + +type ConvertObjectToTypeArray = {} extends O + ? [] + : { + [key in keyof O]: [key, ...ConvertObjectToTypeArray]; + }[keyof O]; diff --git a/packages/hardhat-ignition/test/test-helpers/use-ignition-project.ts b/packages/hardhat-ignition/test/test-helpers/use-ignition-project.ts new file mode 100644 index 0000000000..7f2bbceb96 --- /dev/null +++ b/packages/hardhat-ignition/test/test-helpers/use-ignition-project.ts @@ -0,0 +1,224 @@ +import { DeployConfig, IgnitionModule } from "@nomicfoundation/ignition-core"; +import { ensureDirSync, removeSync } from "fs-extra"; +import { resetHardhatContext } from "hardhat/plugins-testing"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import path from "path"; + +import { clearPendingTransactionsFromMemoryPool } from "./clear-pending-transactions-from-memory-pool"; +import { TestIgnitionHelper } from "./test-ignition-helper"; +import { waitForPendingTxs } from "./wait-for-pending-txs"; + +declare module "mocha" { + interface Context { + hre: HardhatRuntimeEnvironment & { ignition: TestIgnitionHelper }; + deploymentDir: string | undefined; + runControlledDeploy: ( + ignitionModule: IgnitionModule, + chainUpdates: (c: TestChainHelper) => Promise + ) => ReturnType; + config: Partial; + } +} + +const defaultTestConfig: DeployConfig = { + maxFeeBumps: 5, + timeBeforeBumpingFees: 3 * 60 * 1000, + blockPollingInterval: 200, + requiredConfirmations: 1, + disableFeeBumping: false, +}; + +export function useEphemeralIgnitionProject(fixtureProjectName: string) { + beforeEach("Load environment", async function () { + process.chdir( + path.join(__dirname, "../fixture-projects", fixtureProjectName) + ); + + const hre = require("hardhat"); + + await hre.network.provider.send("evm_setAutomine", [true]); + await hre.run("compile", { quiet: true }); + + this.hre = hre; + (this.hre as any).originalIgnition = this.hre.ignition; + this.hre.ignition = new TestIgnitionHelper(hre); + this.deploymentDir = undefined; + }); + + afterEach("reset hardhat context", function () { + resetHardhatContext(); + }); +} + +export function useFileIgnitionProject( + fixtureProjectName: string, + deploymentId: string, + config?: Partial +) { + beforeEach("Load environment", async function () { + process.chdir( + path.join(__dirname, "../fixture-projects", fixtureProjectName) + ); + + const hre = require("hardhat"); + + const deploymentDir = path.join( + path.resolve( + __dirname, + `../fixture-projects/${fixtureProjectName}/ignition` + ), + "deployments", + deploymentId + ); + + this.hre = hre; + this.hre.ignition = new TestIgnitionHelper(hre); + this.deploymentDir = deploymentDir; + + await hre.run("compile", { quiet: true }); + + const testConfig: Partial = { + ...defaultTestConfig, + ...config, + }; + + this.config = testConfig; + + ensureDirSync(deploymentDir); + + this.runControlledDeploy = ( + ignitionModule: IgnitionModule, + chainUpdates: (c: TestChainHelper) => Promise = async () => {} + ) => { + return runDeploy( + deploymentDir, + ignitionModule, + { hre, config: testConfig }, + chainUpdates + ); + }; + }); + + afterEach("reset hardhat context", function () { + resetHardhatContext(); + + if (this.deploymentDir === undefined) { + throw new Error( + "Deployment dir not set during cleanup of file based project" + ); + } + + removeSync(this.deploymentDir); + }); +} + +async function runDeploy( + deploymentDir: string, + ignitionModule: IgnitionModule, + { + hre, + config = {}, + }: { hre: HardhatRuntimeEnvironment; config?: Partial }, + chainUpdates: (c: TestChainHelper) => Promise = async () => {} +): Promise> { + const { ignitionHelper: ignitionHelper, kill: killFn } = + setupIgnitionHelperRiggedToThrow(hre, deploymentDir, config); + + try { + const deployPromise = ignitionHelper.deploy(ignitionModule, { + config, + }); + + const chainHelper = new TestChainHelper(hre, deployPromise, killFn); + + const [result] = await Promise.all([ + deployPromise, + chainUpdates(chainHelper), + ]); + + return result; + } catch (error) { + if (error instanceof Error && error.message === "Killing deploy process") { + return {}; + } + + throw error; + } +} + +function setupIgnitionHelperRiggedToThrow( + hre: HardhatRuntimeEnvironment, + deploymentDir: string, + config: Partial = {} +): { + ignitionHelper: TestIgnitionHelper; + kill: () => void; +} { + let trigger: boolean = false; + + const kill = () => { + trigger = true; + }; + + const proxiedProvider = new Proxy(hre.network.provider, { + get(target: any, key) { + if (trigger) { + trigger = false; + throw new Error("Killing deploy process"); + } + + return target[key]; + }, + }); + + const ignitionHelper = new TestIgnitionHelper( + hre, + config, + proxiedProvider, + deploymentDir + ); + + return { ignitionHelper, kill }; +} + +export class TestChainHelper { + constructor( + private _hre: HardhatRuntimeEnvironment, + private _deployPromise: Promise, + private _exitFn: () => void + ) {} + + public async waitForPendingTxs(expectedCount: number) { + await waitForPendingTxs(this._hre, expectedCount, this._deployPromise); + } + + /** + * Mine the next block, optionally waiting for pending transactions to + * build up before mining. + * + * @param pendingTxToAwait - the number of pending tx that should be in + * the block before mining + */ + public async mineBlock(pendingTxToAwait: number = 0) { + if (pendingTxToAwait > 0) { + await waitForPendingTxs(this._hre, pendingTxToAwait, this._deployPromise); + } + + return this._hre.network.provider.send("evm_mine"); + } + + public async clearMempool(pendingTxToAwait: number = 0) { + if (pendingTxToAwait > 0) { + await waitForPendingTxs(this._hre, pendingTxToAwait, this._deployPromise); + } + + return clearPendingTransactionsFromMemoryPool(this._hre); + } + + /** + * Exit from the deploy on the next block tick. + */ + public exitDeploy() { + this._exitFn(); + } +} diff --git a/packages/hardhat-ignition/test/test-helpers/wait-for-pending-txs.ts b/packages/hardhat-ignition/test/test-helpers/wait-for-pending-txs.ts new file mode 100644 index 0000000000..eb3f91ffc3 --- /dev/null +++ b/packages/hardhat-ignition/test/test-helpers/wait-for-pending-txs.ts @@ -0,0 +1,32 @@ +const sleep = (timeout: number) => + new Promise((res) => setTimeout(res, timeout)); + +/** + * Wait until there are at least `expectedCount` transactions in the mempool + */ +export async function waitForPendingTxs( + hre: any, + expectedCount: number, + finished: Promise +) { + let stopWaiting = false; + finished.finally(() => { + stopWaiting = true; + }); + + while (true) { + if (stopWaiting) { + return; + } + const pendingBlock = await hre.network.provider.send( + "eth_getBlockByNumber", + ["pending", false] + ); + + if (pendingBlock.transactions.length >= expectedCount) { + return; + } + + await sleep(50); + } +} diff --git a/packages/hardhat-ignition/test/ui/helpers/calculate-batch-display.ts b/packages/hardhat-ignition/test/ui/helpers/calculate-batch-display.ts new file mode 100644 index 0000000000..64559c3242 --- /dev/null +++ b/packages/hardhat-ignition/test/ui/helpers/calculate-batch-display.ts @@ -0,0 +1,228 @@ +import { assert } from "chai"; + +import { calculateBatchDisplay } from "../../../src/ui/helpers/calculate-batch-display"; +import { + UiFuture, + UiFutureStatusType, + UiState, + UiStateDeploymentStatus, +} from "../../../src/ui/types"; + +import { testFormat } from "./test-format"; + +const exampleState: UiState = { + status: UiStateDeploymentStatus.DEPLOYING, + chainId: 31337, + moduleName: "ExampleModule", + deploymentDir: "/users/example", + batches: [], + currentBatch: 1, + result: null, + warnings: [], + isResumed: false, + maxFeeBumps: 0, + disableFeeBumping: false, + gasBumps: {}, + strategy: null, + ledger: false, + ledgerMessage: "", + ledgerMessageIsDisplayed: false, +}; + +describe("ui - calculate batch display", () => { + it("should render a batch with a single running future", () => { + const expectedText = testFormat(` + Batch #1 + Executing ExampleModule#Token... + `); + + assertBatchText( + [ + { + status: { + type: UiFutureStatusType.UNSTARTED, + }, + futureId: "ExampleModule#Token", + }, + ], + 3, + expectedText + ); + }); + + it("should render a batch with a single completed future", () => { + const expectedText = testFormat(` + Batch #1 + Executed ExampleModule#Token + `); + + assertBatchText( + [ + { + status: { + type: UiFutureStatusType.SUCCESS, + }, + futureId: "ExampleModule#Token", + }, + ], + 3, + expectedText + ); + }); + + it("should render a batch with a single failed future", () => { + const expectedText = testFormat(` + Batch #1 + Failed ExampleModule#Token + `); + + assertBatchText( + [ + { + status: { + type: UiFutureStatusType.ERRORED, + message: "The transaction reverted", + }, + futureId: "ExampleModule#Token", + }, + ], + 3, + expectedText + ); + }); + + it("should render a batch with a single timed out future", () => { + const expectedText = testFormat(` + Batch #1 + Timed out ExampleModule#Token + `); + + assertBatchText( + [ + { + status: { + type: UiFutureStatusType.TIMEDOUT, + }, + futureId: "ExampleModule#Token", + }, + ], + 3, + expectedText + ); + }); + + it("should render a batch with a single held future", () => { + const expectedText = testFormat(` + Batch #1 + Held ExampleModule#Token + `); + + assertBatchText( + [ + { + status: { + type: UiFutureStatusType.HELD, + heldId: 1, + reason: "Waiting for multisig signoff", + }, + futureId: "ExampleModule#Token", + }, + ], + 3, + expectedText + ); + }); + + it("should render a complex batch in multiple states", () => { + const expectedText = testFormat(` + Batch #1 + Failed ExampleModule#Dex + Held ExampleModule#ENS + Timed out ExampleModule#Registry + Executed ExampleModule#Router + Executing ExampleModule#Token... + `); + + assertBatchText( + [ + { + status: { + type: UiFutureStatusType.UNSTARTED, + }, + futureId: "ExampleModule#Token", + }, + { + status: { + type: UiFutureStatusType.ERRORED, + message: "The transaction reverted", + }, + futureId: "ExampleModule#Dex", + }, + { + status: { + type: UiFutureStatusType.SUCCESS, + }, + futureId: "ExampleModule#Router", + }, + { + status: { + type: UiFutureStatusType.TIMEDOUT, + }, + futureId: "ExampleModule#Registry", + }, + { + status: { + type: UiFutureStatusType.HELD, + heldId: 1, + reason: "Waiting for multisig signoff", + }, + futureId: "ExampleModule#ENS", + }, + ], + 7, + expectedText + ); + }); + + it("should render a batch when using a ledger device", () => { + const expectedText = testFormat(` + Batch #1 + Executing ExampleModule#Token... + + Ledger: Waiting for confirmation on device + `); + + assertBatchText( + [ + { + status: { + type: UiFutureStatusType.UNSTARTED, + }, + futureId: "ExampleModule#Token", + }, + ], + 3, + expectedText, + { + ledger: true, + ledgerMessage: "Waiting for confirmation on device", + } + ); + }); +}); + +function assertBatchText( + batch: UiFuture[], + expectedHeight: number, + expectedText: string, + extraState?: Partial +) { + const { text: actualText, height } = calculateBatchDisplay({ + ...exampleState, + batches: [batch], + ...extraState, + }); + + assert.equal(height, expectedHeight); + assert.equal(actualText, expectedText); +} diff --git a/packages/hardhat-ignition/test/ui/helpers/calculate-deploying-module-panel-display.ts b/packages/hardhat-ignition/test/ui/helpers/calculate-deploying-module-panel-display.ts new file mode 100644 index 0000000000..3fbbc7adbb --- /dev/null +++ b/packages/hardhat-ignition/test/ui/helpers/calculate-deploying-module-panel-display.ts @@ -0,0 +1,119 @@ +import { assert } from "chai"; +import chalk from "chalk"; +import path from "path"; + +import { calculateDeployingModulePanel } from "../../../src/ui/helpers/calculate-deploying-module-panel"; +import { UiState, UiStateDeploymentStatus } from "../../../src/ui/types"; + +import { testFormat } from "./test-format"; + +describe("ui - calculate starting message display", () => { + const exampleState: UiState = { + status: UiStateDeploymentStatus.UNSTARTED, + chainId: 31337, + moduleName: "ExampleModule", + deploymentDir: "/users/example", + batches: [], + currentBatch: 0, + result: null, + warnings: [], + isResumed: null, + maxFeeBumps: 0, + disableFeeBumping: false, + gasBumps: {}, + strategy: "basic", + ledger: false, + ledgerMessage: "", + ledgerMessageIsDisplayed: false, + }; + + it("should display the deploying module message", () => { + const expectedText = testFormat(` + Hardhat Ignition 🚀 + + ${chalk.bold(`Deploying [ ExampleModule ]`)} + `); + + const actualText = calculateDeployingModulePanel(exampleState); + + assert.equal(actualText, expectedText); + }); + + it("should include the strategy if it is something other than basic", () => { + const expectedText = testFormat(` + Hardhat Ignition 🚀 + + ${chalk.bold(`Deploying [ ExampleModule ] with strategy create2`)} + `); + + const actualText = calculateDeployingModulePanel({ + ...exampleState, + strategy: "create2", + }); + + assert.equal(actualText, expectedText); + }); + + it("should display reconciliation warnings", () => { + const expectedText = testFormat(` + Hardhat Ignition 🚀 + + ${chalk.bold(`Deploying [ ExampleModule ]`)} + + ${chalk.yellow( + "Warning - previously executed futures are not in the module:" + )} + ${chalk.yellow(" - MyModule#Contract1")} + ${chalk.yellow(" - MyModule#Contract1.call1")} + ${chalk.yellow(" - MyModule#Contract2")} + `); + + const actualText = calculateDeployingModulePanel({ + ...exampleState, + warnings: [ + "MyModule#Contract1", + "MyModule#Contract1.call1", + "MyModule#Contract2", + ], + }); + + assert.equal(actualText, expectedText); + }); + + it("should display a message when the deployment is being resumed and the path is not in the CWD", () => { + const expectedText = testFormat(` + Hardhat Ignition 🚀 + + ${chalk.bold(`Resuming existing deployment from /users/example`)} + + ${chalk.bold(`Deploying [ ExampleModule ]`)} + `); + + const actualText = calculateDeployingModulePanel({ + ...exampleState, + isResumed: true, + }); + + assert.equal(actualText, expectedText); + }); + + it("should display a message when the deployment is being resumed and the path is not in the CWD", () => { + const expectedText = testFormat(` + Hardhat Ignition 🚀 + + ${chalk.bold( + `Resuming existing deployment from .${path.sep}ignition${path.sep}deployments${path.sep}foo` + )} + + ${chalk.bold(`Deploying [ ExampleModule ]`)} + `); + + const actualText = calculateDeployingModulePanel({ + ...exampleState, + isResumed: true, + deploymentDir: `${process.cwd()}/ignition/deployments/foo`, + }); + + assert.equal(actualText, expectedText); + }); +}); diff --git a/packages/hardhat-ignition/test/ui/helpers/calculate-deployment-complete-display.ts b/packages/hardhat-ignition/test/ui/helpers/calculate-deployment-complete-display.ts new file mode 100644 index 0000000000..5e59cc92a5 --- /dev/null +++ b/packages/hardhat-ignition/test/ui/helpers/calculate-deployment-complete-display.ts @@ -0,0 +1,317 @@ +import { + DeploymentCompleteEvent, + DeploymentResultType, + ExecutionErrorDeploymentResult, + ExecutionEventType, + PreviousRunErrorDeploymentResult, + ReconciliationErrorDeploymentResult, + ValidationErrorDeploymentResult, +} from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; +import chalk from "chalk"; + +import { calculateDeploymentCompleteDisplay } from "../../../src/ui/helpers/calculate-deployment-complete-display"; +import { UiBatches, UiFutureStatusType } from "../../../src/ui/types"; + +import { testFormat } from "./test-format"; + +describe("ui - calculate deployment complete display", () => { + const exampleAddress = "0x1F98431c8aD98523631AE4a59f267346ea31F984"; + const differentAddress = "0x0011223344556677889900112233445566778899"; + + const exampleMultipleBatches: UiBatches = [ + [ + { + status: { + type: UiFutureStatusType.SUCCESS, + result: "0x0", + }, + futureId: "MyModule#MyContract1", + }, + ], + ]; + + const exampleNoBatches: UiBatches = []; + + describe("successful deployment", () => { + it("should render a sucessful deployment", () => { + const expectedText = testFormat(` + [ MyModule ] successfully deployed 🚀 + + ${chalk.bold("Deployed Addresses")} + + MyModule#Token - 0x1F98431c8aD98523631AE4a59f267346ea31F984 + MyModule#AnotherToken - 0x0011223344556677889900112233445566778899`); + + const event: DeploymentCompleteEvent = { + type: ExecutionEventType.DEPLOYMENT_COMPLETE, + result: { + type: DeploymentResultType.SUCCESSFUL_DEPLOYMENT, + contracts: { + "MyModule#Token": { + id: "MyModule#Token", + address: exampleAddress, + contractName: "Token", + }, + "MyModule#AnotherToken": { + id: "MyModule#AnotherToken", + address: differentAddress, + contractName: "AnotherToken", + }, + }, + }, + }; + + const actualText = calculateDeploymentCompleteDisplay(event, { + moduleName: "MyModule", + isResumed: false, + batches: exampleMultipleBatches, + deploymentDir: "", + }); + + assert.equal(actualText, expectedText); + }); + + it("should render a sucessful deployment with no contracts", () => { + const expectedText = testFormat(` + [ MyModule ] successfully deployed 🚀 + + ${chalk.bold("Deployed Addresses")} + + ${chalk.italic("No contracts were deployed")}`); + + const event: DeploymentCompleteEvent = { + type: ExecutionEventType.DEPLOYMENT_COMPLETE, + result: { + type: DeploymentResultType.SUCCESSFUL_DEPLOYMENT, + contracts: {}, + }, + }; + + const actualText = calculateDeploymentCompleteDisplay(event, { + moduleName: "MyModule", + isResumed: false, + batches: exampleMultipleBatches, + deploymentDir: "", + }); + + assert.equal(actualText, expectedText); + }); + + it("should render a resumed deployment with no new deployments", () => { + const expectedText = testFormat(` + [ MyModule ] Nothing new to deploy based on previous execution stored in test + + ${chalk.bold("Deployed Addresses")} + + ${chalk.italic("No contracts were deployed")}`); + + const event: DeploymentCompleteEvent = { + type: ExecutionEventType.DEPLOYMENT_COMPLETE, + result: { + type: DeploymentResultType.SUCCESSFUL_DEPLOYMENT, + contracts: {}, + }, + }; + + const actualText = calculateDeploymentCompleteDisplay(event, { + moduleName: "MyModule", + isResumed: true, + batches: exampleNoBatches, + deploymentDir: "test", + }); + + assert.equal(actualText, expectedText); + }); + }); + + describe("validation failures", () => { + it("should render multiple validation errors on multiple futures", () => { + const expectedText = testFormat(` + [ MyModule ] validation failed ⛔ + + The module contains futures that would fail to execute: + + MyModule#MyContract: + - The number of params does not match the constructor + - The name of the contract is invalid + + MyModule#AnotherContract: + - No library provided + + Update the invalid futures and rerun the deployment.`); + + const result: ValidationErrorDeploymentResult = { + type: DeploymentResultType.VALIDATION_ERROR, + errors: { + "MyModule#MyContract": [ + "The number of params does not match the constructor", + "The name of the contract is invalid", + ], + "MyModule#AnotherContract": ["No library provided"], + }, + }; + + const event: DeploymentCompleteEvent = { + type: ExecutionEventType.DEPLOYMENT_COMPLETE, + result, + }; + + const actualText = calculateDeploymentCompleteDisplay(event, { + moduleName: "MyModule", + isResumed: false, + batches: exampleMultipleBatches, + deploymentDir: "", + }); + + assert.equal(actualText, expectedText); + }); + }); + + describe("reconciliation errors", () => { + it("should render a multiple reconciliation errors on multiple futures", () => { + const expectedText = testFormat(` + [ MyModule ] reconciliation failed ⛔ + + The module contains changes to executed futures: + + MyModule#MyContract: + - The params don't match + - The value doesn't match + + MyModule#AnotherContract: + - The artifact bytecode has changed + + Consider modifying your module to remove the inconsistencies with deployed futures.`); + + const result: ReconciliationErrorDeploymentResult = { + type: DeploymentResultType.RECONCILIATION_ERROR, + errors: { + "MyModule#MyContract": [ + "The params don't match", + "The value doesn't match", + ], + "MyModule#AnotherContract": ["The artifact bytecode has changed"], + }, + }; + + const event: DeploymentCompleteEvent = { + type: ExecutionEventType.DEPLOYMENT_COMPLETE, + result, + }; + + const actualText = calculateDeploymentCompleteDisplay(event, { + moduleName: "MyModule", + isResumed: false, + batches: exampleMultipleBatches, + deploymentDir: "", + }); + + assert.equal(actualText, expectedText); + }); + }); + + describe("previous run errors", () => { + it("should render a multiple previous run errors on multiple futures", () => { + const expectedText = testFormat(` + [ MyModule ] deployment cancelled ⛔ + + These futures failed or timed out on a previous run: + - MyModule#MyContract + - MyModule#AnotherContract + + Use the ${chalk.italic("wipe")} task to reset them.`); + + const result: PreviousRunErrorDeploymentResult = { + type: DeploymentResultType.PREVIOUS_RUN_ERROR, + errors: { + "MyModule#MyContract": ["The previous run failed"], + "MyModule#AnotherContract": ["The previous run timed out"], + }, + }; + + const event: DeploymentCompleteEvent = { + type: ExecutionEventType.DEPLOYMENT_COMPLETE, + result, + }; + + const actualText = calculateDeploymentCompleteDisplay(event, { + moduleName: "MyModule", + isResumed: false, + batches: exampleMultipleBatches, + deploymentDir: "", + }); + + assert.equal(actualText, expectedText); + }); + }); + + describe("execution errors", () => { + it("should render an execution failure with multiple of each problem type", () => { + const expectedText = testFormat(` + [ MyModule ] failed ⛔ + + Futures timed out with transactions unconfirmed after maximum fee bumps: + - MyModule#MyContract1 + - MyModule#AnotherContract1 + + Futures failed during execution: + - MyModule#MyContract3: Reverted with reason x + - MyModule#AnotherContract3: Reverted with reason y + + To learn how to handle these errors: https://hardhat.org/ignition-errors + + Held: + - MyModule#MyContract2: Vote is not complete + - MyModule#AnotherContract2: Server timed out`); + + const result: ExecutionErrorDeploymentResult = { + type: DeploymentResultType.EXECUTION_ERROR, + started: [], + timedOut: [ + { futureId: "MyModule#MyContract1", networkInteractionId: 1 }, + { futureId: "MyModule#AnotherContract1", networkInteractionId: 3 }, + ], + held: [ + { + futureId: "MyModule#MyContract2", + heldId: 1, + reason: "Vote is not complete", + }, + { + futureId: "MyModule#AnotherContract2", + heldId: 3, + reason: "Server timed out", + }, + ], + failed: [ + { + futureId: "MyModule#MyContract3", + networkInteractionId: 1, + error: "Reverted with reason x", + }, + { + futureId: "MyModule#AnotherContract3", + networkInteractionId: 3, + error: "Reverted with reason y", + }, + ], + successful: [], + }; + + const event: DeploymentCompleteEvent = { + type: ExecutionEventType.DEPLOYMENT_COMPLETE, + result, + }; + + const actualText = calculateDeploymentCompleteDisplay(event, { + moduleName: "MyModule", + isResumed: false, + batches: exampleMultipleBatches, + deploymentDir: "", + }); + + assert.equal(actualText, expectedText); + }); + }); +}); diff --git a/packages/hardhat-ignition/test/ui/helpers/calculate-deployment-status-display.ts b/packages/hardhat-ignition/test/ui/helpers/calculate-deployment-status-display.ts new file mode 100644 index 0000000000..b4f5e3dae1 --- /dev/null +++ b/packages/hardhat-ignition/test/ui/helpers/calculate-deployment-status-display.ts @@ -0,0 +1,184 @@ +import { StatusResult } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; +import chalk from "chalk"; + +import { calculateDeploymentStatusDisplay } from "../../../src/ui/helpers/calculate-deployment-status-display"; + +import { testFormat } from "./test-format"; + +describe("ui - calculate deployment status display", () => { + const exampleAddress = "0x1F98431c8aD98523631AE4a59f267346ea31F984"; + const differentAddress = "0x0011223344556677889900112233445566778899"; + + const exampleStatusResult = { + chainId: 1, + started: [], + timedOut: [], + held: [], + failed: [], + successful: [], + contracts: {}, + }; + + describe("successful deployment", () => { + it("should render a sucessful deployment", () => { + const expectedText = testFormat(` + Deployment deployment-01 (chainId: 1) was successful + + ${chalk.bold("Deployed Addresses")} + + MyModule#Token - 0x1F98431c8aD98523631AE4a59f267346ea31F984 + MyModule#AnotherToken - 0x0011223344556677889900112233445566778899`); + + const statusResult: StatusResult = { + ...exampleStatusResult, + successful: ["MyModule#Token", "MyModule#AnotherToken"], + contracts: { + "MyModule#Token": { + id: "MyModule#Token", + address: exampleAddress, + contractName: "Token", + sourceName: "contracts/Token.sol", + abi: [], + }, + "MyModule#AnotherToken": { + id: "MyModule#AnotherToken", + address: differentAddress, + contractName: "AnotherToken", + sourceName: "contracts/AnotherToken.sol", + abi: [], + }, + }, + }; + + const actualText = calculateDeploymentStatusDisplay( + "deployment-01", + statusResult + ); + + assert.equal(actualText, expectedText); + }); + + it("should render a sucessful deployment with no deploys", () => { + const expectedText = testFormat(` + Deployment deployment-01 (chainId: 1) was successful + + ${chalk.italic("No contracts were deployed")}`); + + const statusResult: StatusResult = { + ...exampleStatusResult, + successful: ["MyModule#a_call"], + contracts: {}, + }; + + const actualText = calculateDeploymentStatusDisplay( + "deployment-01", + statusResult + ); + + assert.equal(actualText, expectedText); + }); + }); + + describe("failed deployment", () => { + it("should render an execution failure with multiple of each problem type", () => { + const expectedText = testFormat(` + Deployment deployment-01 (chainId: 1) failed + + Futures timed out with transactions unconfirmed after maximum fee bumps: + - MyModule:MyContract1 + - MyModule:AnotherContract1 + + Futures failed during execution: + - MyModule:MyContract3: Reverted with reason x + - MyModule:AnotherContract3: Reverted with reason y + + To learn how to handle these errors: https://hardhat.org/ignition-errors + + Futures where held by the strategy: + - MyModule:MyContract2: Vote is not complete + - MyModule:AnotherContract2: Server timed out`); + + const statusResult: StatusResult = { + chainId: 1, + started: [], + timedOut: [ + { futureId: "MyModule:MyContract1", networkInteractionId: 1 }, + { futureId: "MyModule:AnotherContract1", networkInteractionId: 3 }, + ], + held: [ + { + futureId: "MyModule:MyContract2", + heldId: 1, + reason: "Vote is not complete", + }, + { + futureId: "MyModule:AnotherContract2", + heldId: 3, + reason: "Server timed out", + }, + ], + failed: [ + { + futureId: "MyModule:MyContract3", + networkInteractionId: 1, + error: "Reverted with reason x", + }, + { + futureId: "MyModule:AnotherContract3", + networkInteractionId: 3, + error: "Reverted with reason y", + }, + ], + successful: ["MyModule#Token", "MyModule#AnotherToken"], + contracts: { + "MyModule#Token": { + id: "MyModule#Token", + address: exampleAddress, + contractName: "Token", + sourceName: "contracts/Token.sol", + abi: [], + }, + "MyModule#AnotherToken": { + id: "MyModule#AnotherToken", + address: differentAddress, + contractName: "AnotherToken", + sourceName: "contracts/AnotherToken.sol", + abi: [], + }, + }, + }; + + const actualText = calculateDeploymentStatusDisplay( + "deployment-01", + statusResult + ); + + assert.equal(actualText, expectedText); + }); + }); + + describe("deployment with started but unfinished futures (e.g. simulation errors)", () => { + it("should render a sucessful deployment", () => { + const expectedText = testFormat(` + Deployment deployment-01 (chainId: 1) has futures that have started but not completed + + - MyModule#Token + - MyModule#AnotherToken + + Please rerun your deployment.`); + + const statusResult: StatusResult = { + ...exampleStatusResult, + started: ["MyModule#Token", "MyModule#AnotherToken"], + }; + + const actualText = calculateDeploymentStatusDisplay( + "deployment-01", + statusResult + ); + + assert.equal(actualText, expectedText); + }); + }); +}); diff --git a/packages/hardhat-ignition/test/ui/helpers/calculate-list-transactions-display.ts b/packages/hardhat-ignition/test/ui/helpers/calculate-list-transactions-display.ts new file mode 100644 index 0000000000..d1c950e954 --- /dev/null +++ b/packages/hardhat-ignition/test/ui/helpers/calculate-list-transactions-display.ts @@ -0,0 +1,77 @@ +import { TransactionStatus } from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { calculateListTransactionsDisplay } from "../../../src/ui/helpers/calculate-list-transactions-display"; + +describe("calculateListTransactionsDisplay", function () { + it("should serialize a bigint in transaction params", () => { + const result = calculateListTransactionsDisplay("1", [ + { + status: TransactionStatus.SUCCESS, + type: "DEPLOYMENT_EXECUTION_STATE", + txHash: + "0x65c7c0850d014fe44aced2249b3b3523c3a29e5e40b6388b6d84b28c0345b9e1", + from: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + name: "BasicContract", + address: "0x74e720c9B362ae3A65fF356ad62866511486BBBc", + params: [BigInt(42)], + value: BigInt(10), + }, + ]); + + const expected = `Logging transactions for deployment 1 + +Transaction 1: + - Type: Contract Deployment + - Status: SUCCESS + - TxHash: 0x65c7c0850d014fe44aced2249b3b3523c3a29e5e40b6388b6d84b28c0345b9e1 + - From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 + - Name: BasicContract + - Address: 0x74e720c9B362ae3A65fF356ad62866511486BBBc + - Params: ['42n'] + - Value: '10n' + +`; + + assert.equal(result, expected); + }); + + it("should serialize bigints in nested transaction params", () => { + const result = calculateListTransactionsDisplay("1", [ + { + status: TransactionStatus.SUCCESS, + type: "DEPLOYMENT_EXECUTION_STATE", + txHash: + "0x65c7c0850d014fe44aced2249b3b3523c3a29e5e40b6388b6d84b28c0345b9e1", + from: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", + name: "BasicContract", + address: "0x74e720c9B362ae3A65fF356ad62866511486BBBc", + params: [ + 1, + 2, + "A", + "B", + [BigInt(42), BigInt(43)], + { sub: { a: BigInt(44) } }, + ], + value: BigInt(10), + }, + ]); + + const expected = `Logging transactions for deployment 1 + +Transaction 1: + - Type: Contract Deployment + - Status: SUCCESS + - TxHash: 0x65c7c0850d014fe44aced2249b3b3523c3a29e5e40b6388b6d84b28c0345b9e1 + - From: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 + - Name: BasicContract + - Address: 0x74e720c9B362ae3A65fF356ad62866511486BBBc + - Params: [1,2,'A','B',['42n','43n'],{sub:{a:'44n'}}] + - Value: '10n' + +`; + + assert.equal(result, expected); + }); +}); diff --git a/packages/hardhat-ignition/test/ui/helpers/calculate-starting-message.ts b/packages/hardhat-ignition/test/ui/helpers/calculate-starting-message.ts new file mode 100644 index 0000000000..1eb12ba144 --- /dev/null +++ b/packages/hardhat-ignition/test/ui/helpers/calculate-starting-message.ts @@ -0,0 +1,34 @@ +import { assert } from "chai"; +import chalk from "chalk"; + +import { calculateStartingMessage } from "../../../src/ui/helpers/calculate-starting-message"; + +describe("ui - calculate starting message display", () => { + it("should display the starting message", () => { + const expectedText = `Hardhat Ignition starting for [ MyModule ]...`; + + const actualText = calculateStartingMessage({ + moduleName: "MyModule", + deploymentDir: "/users/example", + }); + + assert.equal(actualText, expectedText); + }); + + it("should display the warning for an ephemeral network", () => { + const warningMessage = `You are running Hardhat Ignition against an in-process instance of Hardhat Network. +This will execute the deployment, but the results will be lost. +You can use --network to deploy to a different network.`; + + const expectedText = `${chalk.yellow( + chalk.bold(warningMessage) + )}\n\nHardhat Ignition starting for [ MyModule ]...`; + + const actualText = calculateStartingMessage({ + moduleName: "MyModule", + deploymentDir: undefined, + }); + + assert.equal(actualText, expectedText); + }); +}); diff --git a/packages/hardhat-ignition/test/ui/helpers/test-format.ts b/packages/hardhat-ignition/test/ui/helpers/test-format.ts new file mode 100644 index 0000000000..6bc238a42f --- /dev/null +++ b/packages/hardhat-ignition/test/ui/helpers/test-format.ts @@ -0,0 +1,18 @@ +/** + * Formats a multiline string to make appear closer to the command line + * when inside a test file. The first line is ignored, and the whitespace + * at the start of the line is removed. + */ +export function testFormat(expected: string): string { + const lines = expected + .toString() + .substring(1) // Remove the first newline + .split("\n"); + + // calcualte the length of the whitespace prefix based on the first line + const whitespacePrefixLength = lines[0].search(/\S/); + + return lines + .map((line) => line.substring(whitespacePrefixLength)) // strip prefix whitespace + .join("\n"); +} diff --git a/packages/hardhat-ignition/test/ui/pretty-event-handler.ts b/packages/hardhat-ignition/test/ui/pretty-event-handler.ts new file mode 100644 index 0000000000..b3274d1a28 --- /dev/null +++ b/packages/hardhat-ignition/test/ui/pretty-event-handler.ts @@ -0,0 +1,72 @@ +import { assert } from "chai"; + +import { PrettyEventHandler } from "../../src/ui/pretty-event-handler"; + +describe("ui - pretty event handler", () => { + describe("ledger", () => { + it("should set a message on connection start", () => { + const eventHandler = new PrettyEventHandler(undefined, true); + + eventHandler.ledgerConnectionStart(); + + assert.equal(eventHandler.state.ledgerMessage, "Connecting wallet"); + assert.isTrue(eventHandler.state.ledger); + assert.isTrue(eventHandler.state.ledgerMessageIsDisplayed); + }); + + it("should set a message on connection success", () => { + const eventHandler = new PrettyEventHandler(undefined, true); + + eventHandler.ledgerConnectionSuccess(); + + assert.equal(eventHandler.state.ledgerMessage, "Wallet connected"); + }); + + it("should set a message on connection failure", () => { + const eventHandler = new PrettyEventHandler(undefined, true); + + eventHandler.ledgerConnectionFailure(); + + assert.equal( + eventHandler.state.ledgerMessage, + "Wallet connection failed" + ); + }); + + it("should set a message on confirmation start", () => { + const eventHandler = new PrettyEventHandler(undefined, true); + + eventHandler.ledgerConfirmationStart(); + + assert.equal( + eventHandler.state.ledgerMessage, + "Waiting for confirmation on device" + ); + assert.isTrue(eventHandler.state.ledger); + assert.isTrue(eventHandler.state.ledgerMessageIsDisplayed); + }); + + it("should set a message on confirmation success", () => { + const eventHandler = new PrettyEventHandler(undefined, true); + + eventHandler.ledgerConfirmationSuccess(); + + assert.equal( + eventHandler.state.ledgerMessage, + "Transaction approved by device" + ); + assert.isFalse(eventHandler.state.ledger); + }); + + it("should set a message on confirmation failure", () => { + const eventHandler = new PrettyEventHandler(undefined, true); + + eventHandler.ledgerConfirmationFailure(); + + assert.equal( + eventHandler.state.ledgerMessage, + "Transaction confirmation failed" + ); + }); + }); +}); diff --git a/packages/hardhat-ignition/test/utils/bigintReviver.ts b/packages/hardhat-ignition/test/utils/bigintReviver.ts new file mode 100644 index 0000000000..029094e9bd --- /dev/null +++ b/packages/hardhat-ignition/test/utils/bigintReviver.ts @@ -0,0 +1,19 @@ +import { assert } from "chai"; + +import { bigintReviver } from "../../src/utils/bigintReviver"; + +describe("bigintReviver", function () { + it('should convert number strings ending with "n" to BigInt', function () { + assert.deepEqual(JSON.parse('{"a":"1n"}', bigintReviver), { a: BigInt(1) }); + }); + + it("should throw if a number is bigger than Number.MAX_SAFE_INTEGER", function () { + assert.throws(() => { + JSON.parse('{"a":9007199254740992}', bigintReviver); + }, `Parameter "a" exceeds maximum safe integer size. Encode the value as a string using bigint notation: \`$\{value\}n\``); + }); + + it("should not convert regular numbers", function () { + assert.deepEqual(JSON.parse('{"a":1}', bigintReviver), { a: 1 }); + }); +}); diff --git a/packages/hardhat-ignition/test/utils/error-deployment-result-to-exception-message.ts b/packages/hardhat-ignition/test/utils/error-deployment-result-to-exception-message.ts new file mode 100644 index 0000000000..4323e8317b --- /dev/null +++ b/packages/hardhat-ignition/test/utils/error-deployment-result-to-exception-message.ts @@ -0,0 +1,210 @@ +import { + DeploymentResultType, + ExecutionErrorDeploymentResult, + PreviousRunErrorDeploymentResult, + ReconciliationErrorDeploymentResult, + ValidationErrorDeploymentResult, +} from "@nomicfoundation/ignition-core"; +import { assert } from "chai"; + +import { errorDeploymentResultToExceptionMessage } from "../../src/utils/error-deployment-result-to-exception-message"; + +describe("display error deployment result", () => { + describe("validation", () => { + it("should display a validation error", () => { + const result: ValidationErrorDeploymentResult = { + type: DeploymentResultType.VALIDATION_ERROR, + errors: { + "MyModule:MyContract": [ + "The number of params does not match the constructor", + "The name of the contract is invalid", + ], + "MyModule:AnotherContract": ["No library provided"], + }, + }; + + assert.equal( + errorDeploymentResultToExceptionMessage(result), + `The deployment wasn't run because of the following validation errors: + + * MyModule:MyContract: The number of params does not match the constructor + * MyModule:MyContract: The name of the contract is invalid + * MyModule:AnotherContract: No library provided` + ); + }); + }); + + describe("reconciliation", () => { + it("should display a reconciliation error", () => { + const result: ReconciliationErrorDeploymentResult = { + type: DeploymentResultType.RECONCILIATION_ERROR, + errors: { + "MyModule:MyContract": [ + "The params don't match", + "The value doesn't match", + ], + "MyModule:AnotherContract": ["The future is timed out"], + }, + }; + + assert.equal( + errorDeploymentResultToExceptionMessage(result), + `The deployment wasn't run because of the following reconciliation errors: + + * MyModule:MyContract: The params don\'t match + * MyModule:MyContract: The value doesn\'t match + * MyModule:AnotherContract: The future is timed out` + ); + }); + }); + + describe("previous run", () => { + it("should display a previous run error", () => { + const result: PreviousRunErrorDeploymentResult = { + type: DeploymentResultType.PREVIOUS_RUN_ERROR, + errors: { + "MyModule:MyContract": ["The previous run failed"], + "MyModule:AnotherContract": ["The previous run timed out"], + }, + }; + + assert.equal( + errorDeploymentResultToExceptionMessage(result), + `The deployment wasn't run because of the following errors in a previous run: + + * MyModule:MyContract: The previous run failed + * MyModule:AnotherContract: The previous run timed out` + ); + }); + }); + + describe("execution", () => { + it("should display an execution error with timeouts", () => { + const result: ExecutionErrorDeploymentResult = { + type: DeploymentResultType.EXECUTION_ERROR, + started: [], + timedOut: [ + { futureId: "MyModule:MyContract", networkInteractionId: 1 }, + { futureId: "MyModule:AnotherContract", networkInteractionId: 3 }, + ], + held: [], + failed: [], + successful: [], + }; + + assert.equal( + errorDeploymentResultToExceptionMessage(result), + `The deployment wasn't successful, there were timeouts: + +Timed out: + + * MyModule:MyContract/1 + * MyModule:AnotherContract/3` + ); + }); + + it("should display an execution error with holds", () => { + const result: ExecutionErrorDeploymentResult = { + type: DeploymentResultType.EXECUTION_ERROR, + started: [], + timedOut: [], + held: [ + { + futureId: "MyModule:MyContract", + heldId: 1, + reason: "Vote is not complete", + }, + { + futureId: "MyModule:AnotherContract", + heldId: 3, + reason: "Server timed out", + }, + ], + failed: [], + successful: [], + }; + + assert.equal( + errorDeploymentResultToExceptionMessage(result), + `The deployment wasn't successful, there were holds: + +Held: + + * MyModule:MyContract/1: Vote is not complete + * MyModule:AnotherContract/3: Server timed out` + ); + }); + + it("should display an execution error with execution failures", () => { + const result: ExecutionErrorDeploymentResult = { + type: DeploymentResultType.EXECUTION_ERROR, + started: [], + timedOut: [], + held: [], + failed: [ + { + futureId: "MyModule:MyContract", + networkInteractionId: 1, + error: "Reverted with reason x", + }, + { + futureId: "MyModule:AnotherContract", + networkInteractionId: 3, + error: "Reverted with reason y", + }, + ], + successful: [], + }; + + assert.equal( + errorDeploymentResultToExceptionMessage(result), + `The deployment wasn't successful, there were failures: + +Failures: + + * MyModule:MyContract/1: Reverted with reason x + * MyModule:AnotherContract/3: Reverted with reason y` + ); + }); + + it("should display an execution error with both timeouts and execution failures", () => { + const result: ExecutionErrorDeploymentResult = { + type: DeploymentResultType.EXECUTION_ERROR, + started: [], + timedOut: [ + { futureId: "MyModule:FirstContract", networkInteractionId: 1 }, + { futureId: "MyModule:SecondContract", networkInteractionId: 3 }, + ], + held: [], + failed: [ + { + futureId: "MyModule:ThirdContract", + networkInteractionId: 1, + error: "Reverted with reason x", + }, + { + futureId: "MyModule:FourthContract", + networkInteractionId: 3, + error: "Reverted with reason y", + }, + ], + successful: [], + }; + + assert.equal( + errorDeploymentResultToExceptionMessage(result), + `The deployment wasn't successful, there were timeouts and failures: + +Timed out: + + * MyModule:FirstContract/1 + * MyModule:SecondContract/3 + +Failures: + + * MyModule:ThirdContract/1: Reverted with reason x + * MyModule:FourthContract/3: Reverted with reason y` + ); + }); + }); +}); diff --git a/packages/hardhat-ignition/test/utils/load-module.ts b/packages/hardhat-ignition/test/utils/load-module.ts new file mode 100644 index 0000000000..75b33bf2bb --- /dev/null +++ b/packages/hardhat-ignition/test/utils/load-module.ts @@ -0,0 +1,30 @@ +/* eslint-disable import/no-unused-modules */ +import { assert } from "chai"; + +import { loadModule } from "../../src/utils/load-module"; +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("loadModule", function () { + useEphemeralIgnitionProject("user-modules"); + + it("should throw if the full path to the module does not exist", () => { + assert.throws( + () => loadModule("ignition", "./ignition/modules/Fake.js"), + "Could not find a module file at the path: ./ignition/modules/Fake.js" + ); + }); + + it("should throw if the full path to the module is outside the module directory", () => { + const unixErrorMessage = `The referenced module file ./hardhat.config.js is outside the module directory ignition/modules`; + + const expectedErrorMessage = + process.platform === "win32" + ? unixErrorMessage.replace("ignition/modules", "ignition\\modules") + : unixErrorMessage; + + assert.throws( + () => loadModule("ignition", "./hardhat.config.js"), + expectedErrorMessage + ); + }); +}); diff --git a/packages/hardhat-ignition/test/utils/resolve-deployment-id.ts b/packages/hardhat-ignition/test/utils/resolve-deployment-id.ts new file mode 100644 index 0000000000..8532411add --- /dev/null +++ b/packages/hardhat-ignition/test/utils/resolve-deployment-id.ts @@ -0,0 +1,28 @@ +import { assert } from "chai"; + +import { resolveDeploymentId } from "../../src/utils/resolve-deployment-id"; + +describe("deploy id rules", () => { + const exampleChainId = 31337; + + it("should use the user provided id if one is provided", () => { + const deploymentId = resolveDeploymentId( + "my-deployment-id", + exampleChainId + ); + + assert.equal(deploymentId, "my-deployment-id"); + }); + + it("should generate a default id based on the chainId if the user provided no deploymentId", () => { + const deploymentId = resolveDeploymentId(undefined, exampleChainId); + + assert.equal(deploymentId, "chain-31337"); + }); + + it("should throw if the user provided an invalid deploymentId", () => { + assert.throws(() => { + resolveDeploymentId("deployment/test", exampleChainId); + }, /The deployment-id "deployment\/test" contains banned characters, ids can only contain alphanumerics, dashes or underscores/); + }); +}); diff --git a/packages/hardhat-ignition/test/verify/getApiKeyAndUrls.ts b/packages/hardhat-ignition/test/verify/getApiKeyAndUrls.ts new file mode 100644 index 0000000000..1761ba53d5 --- /dev/null +++ b/packages/hardhat-ignition/test/verify/getApiKeyAndUrls.ts @@ -0,0 +1,83 @@ +import { assert } from "chai"; + +import { getApiKeyAndUrls } from "../../src/utils/getApiKeyAndUrls"; + +describe("getApiKeyAndUrls", function () { + it("should return the correct API URLs when given a string", function () { + const apiKeyList = getApiKeyAndUrls("testApiKey", { + network: "mainnet", + chainId: 1, + urls: { + apiURL: "https://api.etherscan.io/api", + browserURL: "https://etherscan.io", + }, + }); + + assert.deepEqual(apiKeyList, [ + "testApiKey", + "https://api.etherscan.io/api", + "https://etherscan.io", + ]); + }); + + it("should return the correct API URLs when given an apiKey object", function () { + const apiKeyList = getApiKeyAndUrls( + { + goerli: "goerliApiKey", + sepolia: "sepoliaApiKey", + }, + { + network: "goerli", + chainId: 5, + urls: { + apiURL: "https://api-goerli.etherscan.io/api", + browserURL: "https://goerli.etherscan.io", + }, + } + ); + + assert.deepEqual(apiKeyList, [ + "goerliApiKey", + "https://api-goerli.etherscan.io/api", + "https://goerli.etherscan.io", + ]); + }); + + it("should return the correct API URLs when given a string and the network is not mainnet", function () { + const apiKeyList = getApiKeyAndUrls("goerliApiKey", { + network: "goerli", + chainId: 5, + urls: { + apiURL: "https://api-goerli.etherscan.io/api", + browserURL: "https://goerli.etherscan.io", + }, + }); + + assert.deepEqual(apiKeyList, [ + "goerliApiKey", + "https://api-goerli.etherscan.io/api", + "https://goerli.etherscan.io", + ]); + }); + + it("should throw when given an object and a nonexistent network name", function () { + assert.throws( + () => + getApiKeyAndUrls( + { + goerli: "goerliApiKey", + sepolia: "sepoliaApiKey", + }, + { + network: "mainnet", + chainId: 1, + urls: { + apiURL: "https://api.etherscan.io/api", + browserURL: "https://etherscan.io", + }, + } + ), + /No etherscan API key configured for network mainnet/ + ); + }); +}); diff --git a/packages/hardhat-ignition/test/verify/index.ts b/packages/hardhat-ignition/test/verify/index.ts new file mode 100644 index 0000000000..9de5b840e1 --- /dev/null +++ b/packages/hardhat-ignition/test/verify/index.ts @@ -0,0 +1,35 @@ +/* eslint-disable import/no-unused-modules */ +import { assert } from "chai"; + +import { useEphemeralIgnitionProject } from "../test-helpers/use-ignition-project"; + +describe("verify", function () { + describe("when there is no etherscan API key configured", function () { + useEphemeralIgnitionProject("verify-no-api-key"); + + it("should throw in the verify task", async function () { + await assert.isRejected( + this.hre.run( + { scope: "ignition", task: "verify" }, + { + deploymentId: "test", + } + ), + /No etherscan API key configured/ + ); + }); + + it("should throw in the deploy task", async function () { + await assert.isRejected( + this.hre.run( + { scope: "ignition", task: "deploy" }, + { + modulePath: "any", + verify: true, + } + ), + /No etherscan API key configured/ + ); + }); + }); +}); diff --git a/packages/hardhat-ignition/test/verify/verifyEtherscanContract.ts b/packages/hardhat-ignition/test/verify/verifyEtherscanContract.ts new file mode 100644 index 0000000000..f671205826 --- /dev/null +++ b/packages/hardhat-ignition/test/verify/verifyEtherscanContract.ts @@ -0,0 +1,56 @@ +import type { Etherscan } from "@nomicfoundation/hardhat-verify/etherscan"; + +import { assert } from "chai"; + +import { verifyEtherscanContract } from "../../src/utils/verifyEtherscanContract"; + +describe("verifyEtherscanContract", function () { + let etherscanInstance: any; + const contractInfo = { + address: "0x123", + compilerVersion: "v0.8.0", + sourceCode: "sourceCode", + name: "name", + args: "args", + }; + + beforeEach(function () { + etherscanInstance = { + verify: async () => ({ message: "guid" }), + getVerificationStatus: async () => ({ + isSuccess: () => true, + message: "message", + }), + getContractUrl: () => "url", + }; + }); + + it("should return a success object when verification succeeds", async function () { + const result = await verifyEtherscanContract( + etherscanInstance as Etherscan, + contractInfo + ); + + assert.deepEqual(result, { + type: "success", + contractURL: "url", + }); + }); + + it("should return a failure object when verification is not successful", async function () { + etherscanInstance.getVerificationStatus = async () => ({ + isSuccess: () => false, + message: "message", + }); + + const result = await verifyEtherscanContract( + etherscanInstance as Etherscan, + contractInfo + ); + + assert.deepEqual(result, { + type: "failure", + reason: new Error("message"), + }); + }); +}); diff --git a/packages/hardhat-ignition/tsconfig.json b/packages/hardhat-ignition/tsconfig.json new file mode 100644 index 0000000000..6e021cd5c9 --- /dev/null +++ b/packages/hardhat-ignition/tsconfig.json @@ -0,0 +1,16 @@ +{ + "extends": "../../config/typescript/tsconfig.json", + "compilerOptions": { + "target": "ES2022", + "outDir": "dist", + "composite": true, + "jsx": "react-jsx" + }, + "references": [ + { "path": "../hardhat-ignition-core" }, + { "path": "../hardhat-core" }, + { "path": "../hardhat-network-helpers" }, + { "path": "../hardhat-verify" }, + { "path": "../hardhat-ignition-ui/tsconfig.node.json" } + ] +} diff --git a/packages/hardhat-ledger/.eslintrc.js b/packages/hardhat-ledger/.eslintrc.js new file mode 100644 index 0000000000..c6de07705a --- /dev/null +++ b/packages/hardhat-ledger/.eslintrc.js @@ -0,0 +1,24 @@ +const { + slowImportsCommonIgnoredModules, +} = require("../../config/eslint/constants"); + +module.exports = { + extends: [`${__dirname}/../../config/eslint/eslintrc.js`], + parserOptions: { + project: `${__dirname}/tsconfig.json`, + sourceType: "module", + }, + overrides: [ + { + files: ["src/index.ts"], + rules: { + "@nomicfoundation/slow-imports/no-top-level-external-import": [ + "error", + { + ignoreModules: [...slowImportsCommonIgnoredModules], + }, + ], + }, + }, + ], +}; diff --git a/packages/hardhat-ledger/.gitignore b/packages/hardhat-ledger/.gitignore new file mode 100644 index 0000000000..b0ee1244f1 --- /dev/null +++ b/packages/hardhat-ledger/.gitignore @@ -0,0 +1,97 @@ +# Node modules +/node_modules + +# Compilation output +/build-test/ +/dist + +# Code coverage artifacts +/coverage +/.nyc_output + +/*.js +/*.js.map +/*.d.ts +/*.d.ts.map +/builtin-tasks +/common +/internal +/types +/utils + +# Below is Github's node gitignore template, +# ignoring the node_modules part, as it'd ignore every node_modules, and we have some for testing + +# Logs +logs +*.log + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +#node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'pnpm pack' +*.tgz + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +test/fixture-projects/*/artifacts +test/fixture-projects/*/cache diff --git a/packages/hardhat-ledger/.mocharc.json b/packages/hardhat-ledger/.mocharc.json new file mode 100644 index 0000000000..d00ceb4138 --- /dev/null +++ b/packages/hardhat-ledger/.mocharc.json @@ -0,0 +1,5 @@ +{ + "require": "ts-node/register/files", + "ignore": ["test/fixture-projects/**/*"], + "timeout": 10000 +} diff --git a/packages/hardhat-ledger/.prettierignore b/packages/hardhat-ledger/.prettierignore new file mode 100644 index 0000000000..8b59d6f54c --- /dev/null +++ b/packages/hardhat-ledger/.prettierignore @@ -0,0 +1,7 @@ +/node_modules +/dist +/test/fixture-projects/**/artifacts +/test/fixture-projects/**/artifacts-dir +/test/fixture-projects/**/cache +CHANGELOG.md +.nyc_output diff --git a/packages/hardhat-ledger/CHANGELOG.md b/packages/hardhat-ledger/CHANGELOG.md new file mode 100644 index 0000000000..d6c75fd9c3 --- /dev/null +++ b/packages/hardhat-ledger/CHANGELOG.md @@ -0,0 +1,26 @@ +# @nomicfoundation/hardhat-ledger + +## 1.1.0 + +### Minor Changes + +- aa09462: Add support for the Prague hardfork + +## 1.0.3 + +### Patch Changes + +- 4912563: Internal restructuing to better support cli UI updates from other Hardhat plugins +- e038de7: Added an option to set the derivation path (thanks @area!). + +## 1.0.2 + +### Patch Changes + +- f60cc9e: Fixed a problem that made `hardhat-ledger` unusable in the Hardhat console (thanks @area!). + +## 1.0.1 + +### Patch Changes + +- d8793639e: Pinned version of @ledgerhq/hw-app-eth because the latest version has breaking changes diff --git a/packages/hardhat-ledger/LICENSE b/packages/hardhat-ledger/LICENSE new file mode 100644 index 0000000000..3b7e8c7eab --- /dev/null +++ b/packages/hardhat-ledger/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Nomic Foundation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/hardhat-ledger/README.md b/packages/hardhat-ledger/README.md new file mode 100644 index 0000000000..8af415ba7b --- /dev/null +++ b/packages/hardhat-ledger/README.md @@ -0,0 +1,117 @@ +[![npm](https://img.shields.io/npm/v/@nomicfoundation/hardhat-ledger.svg)](https://www.npmjs.com/package/@nomicfoundation/hardhat-ledger) [![hardhat](https://hardhat.org/buidler-plugin-badge.svg?1)](https://hardhat.org) + +# hardhat-ledger + +[Hardhat](https://hardhat.org) plugin for integration with a [Ledger hardware wallet](https://www.ledger.com/). + +## What + +This plugin extends the Hardhat provider enabling it to work with a connected Ledger wallet seamlessly. + +## Installation + +```bash +npm install --save-dev @nomicfoundation/hardhat-ledger +``` + +And add the following statement to your `hardhat.config.js`: + +```js +require("@nomicfoundation/hardhat-ledger"); +``` + +Or, if you are using TypeScript, add this to your `hardhat.config.ts`: + +```js +import "@nomicfoundation/hardhat-ledger"; +``` + +## Tasks + +This plugin creates no additional tasks. + +## Environment extensions + +This plugin adds nothing to the Hardhat Runtime Environment. + +## Provider extensions + +The provider supplied by Hardhat will be extended using [`extendProvider`](https://hardhat.org/hardhat-runner/docs/advanced/building-plugins#extending-the-hardhat-provider), decorating it to be a `LedgerProvider`. Any successive calls to `extendProvider` will be added on top of this. + +A `LedgerProvider` knows how to connect and interact with a Ledger wallet + +## Usage + +The only additional step to make this plugin work is to configure it properly through the Hardhat Config. For example, in your `hardhat.config.js`: + +```js +require("@nomicfoundation/hardhat-ledger"); + +module.exports = { + networks: { + hardhat: { + ledgerAccounts: [ + "0xa809931e3b38059adae9bc5455bc567d0509ab92", + "0xda6a52afdae5ff66aa786da68754a227331f56e3", + "0xbc307688a80ec5ed0edc1279c44c1b34f7746bda", + ], + }, + }, +}; +``` + +This will make those three accounts available to the `LedgerProvider`. If you try to send a transaction or sign something using any of those accounts, the provider will try to connect to the Ledger wallet and find a derivation path for that address. By default, the derivation paths that are tried start from `m/44'/60'/0'/0'/0` and go way up to `m/44'/60'/20'/0'/0`. + +An additional (optional) configuration is possible to specify the derivation path that should be used, allowing 'legacy' or otherwise non-standard addresses to still be used with the plugin. An example of such a configuration would be: + +```js + hardhat: { + ledgerAccounts: [...], + ledgerOptions: { + derivationFunction: (x) => `m/44'/60'/0'/${x}` // legacy derivation path + } + } +``` + +If you want to use the provider, you could, for example in a task: + +```js +task("sign", "Signs a message", async (_, hre) => { + const message = + "0x5417aa2a18a44da0675524453ff108c545382f0d7e26605c56bba47c21b5e979"; + const account = "0xa809931e3b38059adae9bc5455bc567d0509ab92"; + + const signature = await hre.network.provider.request({ + method: "personal_sign", + params: [ + "0x5417aa2a18a44da0675524453ff108c545382f0d7e26605c56bba47c21b5e979", + account, + ], + }); + + console.log( + "Signed message", + message, + "for Ledger account", + account, + "and got", + signature + ); +}); +``` + +## Errors + +The package throws and exports a few [errors](https://github.com/NomicFoundation/hardhat/blob/main/packages/hardhat-core/src/config.ts). In case you ever need to catch and check for them, you can use the `public static` method present on each of them. For example: + +```ts +try { + //(...) +} catch (error) { + if (DerivationPathError.isDerivationPathError(error)) { + // error is a DerivationPathError + } +} +``` + +Same for the other errors, all have their corresponding `.isXXXError()` method. diff --git a/packages/hardhat-ledger/package.json b/packages/hardhat-ledger/package.json new file mode 100644 index 0000000000..d2761a026c --- /dev/null +++ b/packages/hardhat-ledger/package.json @@ -0,0 +1,79 @@ +{ + "name": "@nomicfoundation/hardhat-ledger", + "version": "1.1.0", + "description": "Hardhat plugin for the Ledger hardware wallet", + "homepage": "https://github.com/nomicfoundation/hardhat/tree/main/packages/hardhat-ledger", + "repository": "github:nomicfoundation/hardhat", + "author": "Nomic Foundation", + "license": "MIT", + "main": "dist/src/index.js", + "types": "dist/src/index.d.ts", + "keywords": [ + "ethereum", + "smart-contracts", + "hardhat", + "hardhat-plugin", + "ledger", + "hardware-wallet" + ], + "scripts": { + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", + "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", + "prettier": "prettier \"**/*.{js,md,json}\"", + "pretest": "cd ../.. && pnpm build", + "test": "mocha --recursive \"test/**/*.ts\" -c --exit", + "coverage": "nyc pnpm test -- --reporter min", + "build": "tsc --build .", + "prepublishOnly": "pnpm build", + "clean": "rimraf dist" + }, + "files": [ + "dist/src/", + "src/", + "LICENSE", + "README.md" + ], + "dependencies": { + "@ethereumjs/util": "^9.1.0", + "@ledgerhq/errors": "^6.12.6", + "@ledgerhq/hw-app-eth": "6.33.6", + "@ledgerhq/hw-transport": "^6.28.4", + "@ledgerhq/hw-transport-node-hid": "^6.27.13", + "chalk": "^2.4.2", + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "ethers": "^6.1.0", + "fs-extra": "^7.0.1", + "io-ts": "1.10.4", + "ora": "^5.4.1" + }, + "devDependencies": { + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", + "@types/chai": "^4.2.0", + "@types/fs-extra": "^5.1.0", + "@types/mocha": ">=9.1.0", + "@types/node": "^18.0.0", + "@types/sinon": "^9.0.8", + "@typescript-eslint/eslint-plugin": "5.61.0", + "@typescript-eslint/parser": "5.61.0", + "chai": "^4.2.0", + "eslint": "^8.44.0", + "eslint-config-prettier": "8.3.0", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-mocha": "10.4.1", + "eslint-plugin-prettier": "3.4.0", + "hardhat": "workspace:^2.16.0", + "mocha": "^10.0.0", + "nyc": "^15.1.0", + "prettier": "2.4.1", + "rimraf": "^3.0.2", + "sinon": "^9.0.0", + "ts-node": "^10.8.0", + "typescript": "~5.0.0" + }, + "peerDependencies": { + "hardhat": "workspace:^2.16.0" + } +} diff --git a/packages/hardhat-ledger/src/errors.ts b/packages/hardhat-ledger/src/errors.ts new file mode 100644 index 0000000000..4a142cfcd5 --- /dev/null +++ b/packages/hardhat-ledger/src/errors.ts @@ -0,0 +1,68 @@ +import type { TransportError } from "@ledgerhq/errors"; +import { NomicLabsHardhatPluginError } from "hardhat/plugins"; + +export class HardhatLedgerError extends NomicLabsHardhatPluginError { + constructor(message: string, parent?: Error) { + super("@nomicfoundation/hardhat-ledger", message, parent); + } +} + +export class HardhatLedgerNotControlledAddressError extends HardhatLedgerError { + public static instanceOf( + other: any + ): other is HardhatLedgerNotControlledAddressError { + return ( + other !== undefined && + other !== null && + other._isNotControlledAddressError === true + ); + } + + private readonly _isNotControlledAddressError = true; + + constructor(message: string, public address: string) { + super(message); + } +} + +export class HardhatLedgerConnectionError extends HardhatLedgerError { + public static instanceOf(other: any): other is HardhatLedgerConnectionError { + return ( + other !== undefined && other !== null && other._isConnectionError === true + ); + } + + private readonly _isConnectionError = true; + + constructor(error: Error) { + super(`There was an error trying to establish a connection to the Ledger wallet: "${error.message}". + +Make sure your Ledger is connected and unlocked, and that the Ethereum app is open. +`); + + if (error.name === "TransportError") { + const transportError = error as TransportError; + this.message += ` +The error id was: ${transportError.id} +`; + } + } +} + +export class HardhatLedgerDerivationPathError extends HardhatLedgerError { + public static instanceOf( + other: any + ): other is HardhatLedgerDerivationPathError { + return ( + other !== undefined && + other !== null && + other._isDerivationPathError === true + ); + } + + private readonly _isDerivationPathError = true; + + constructor(message: string, public path: string) { + super(message); + } +} diff --git a/packages/hardhat-ledger/src/index.ts b/packages/hardhat-ledger/src/index.ts new file mode 100644 index 0000000000..1db9768c5d --- /dev/null +++ b/packages/hardhat-ledger/src/index.ts @@ -0,0 +1,22 @@ +import { extendConfig, extendProvider } from "hardhat/config"; + +import "./type-extensions"; + +export * from "./errors"; + +extendConfig((config, userConfig) => { + // set ledgerAccounts to the user configured value, or to [] if there isn't any + for (const networkName of Object.keys(config.networks)) { + config.networks[networkName].ledgerAccounts = + userConfig.networks?.[networkName]?.ledgerAccounts ?? []; + } +}); + +extendProvider(async (provider, config, network) => { + const { createLedgerProvider } = await import( + "./internal/create-ledger-provider" + ); + + const networkConfig = config.networks[network]; + return createLedgerProvider(provider, networkConfig); +}); diff --git a/packages/hardhat-ledger/src/internal/cache.ts b/packages/hardhat-ledger/src/internal/cache.ts new file mode 100644 index 0000000000..b9886eb18e --- /dev/null +++ b/packages/hardhat-ledger/src/internal/cache.ts @@ -0,0 +1,44 @@ +import type { Paths } from "env-paths"; +import fs from "fs-extra"; +import path from "path"; + +type CacheableJson = Record; + +export const CACHE_FILE_NAME = "accounts.json"; +const PACKAGE_NAME = "hardhat"; + +export async function write(json: T) { + const ledgerCacheFile = await getLedgerCacheFile(CACHE_FILE_NAME); + await fs.writeJSON(ledgerCacheFile, json); +} + +export async function read(): Promise { + const ledgerCacheFile = await getLedgerCacheFile(CACHE_FILE_NAME); + try { + const file: T = await fs.readJSON(ledgerCacheFile); + return file; + } catch (error) {} +} + +async function getLedgerCacheFile(fileName: string): Promise { + const ledgerCacheDir = await getLedgerCacheDir(); + return path.join(ledgerCacheDir, fileName); +} + +async function getLedgerCacheDir(): Promise { + const cache = await getCacheDir(); + const compilersCache = path.join(cache, "ledger"); + await fs.ensureDir(compilersCache); + return compilersCache; +} + +async function getCacheDir(): Promise { + const { cache } = await generatePaths(PACKAGE_NAME); + await fs.ensureDir(cache); + return cache; +} + +async function generatePaths(packageName: string): Promise { + const { default: envPaths } = await import("env-paths"); + return envPaths(packageName); +} diff --git a/packages/hardhat-ledger/src/internal/create-ledger-provider.ts b/packages/hardhat-ledger/src/internal/create-ledger-provider.ts new file mode 100644 index 0000000000..73c977995a --- /dev/null +++ b/packages/hardhat-ledger/src/internal/create-ledger-provider.ts @@ -0,0 +1,19 @@ +import { EIP1193Provider, NetworkConfig } from "hardhat/types"; + +import { LedgerProvider } from "../provider"; +import { withSpinners } from "./with-spinners"; + +export function createLedgerProvider( + provider: EIP1193Provider, + networkConfig: NetworkConfig +): LedgerProvider { + const accounts = networkConfig.ledgerAccounts; + const derivationFunction = networkConfig.ledgerOptions?.derivationFunction; + + const ledgerProvider = new LedgerProvider( + { accounts, derivationFunction }, + provider + ); + + return withSpinners(ledgerProvider); +} diff --git a/packages/hardhat-ledger/src/internal/utils.ts b/packages/hardhat-ledger/src/internal/utils.ts new file mode 100644 index 0000000000..429866b826 --- /dev/null +++ b/packages/hardhat-ledger/src/internal/utils.ts @@ -0,0 +1,4 @@ +export function toHex(value: string | Buffer): string { + const stringValue = typeof value === "string" ? value : value.toString("hex"); + return stringValue.startsWith("0x") ? stringValue : `0x${stringValue}`; +} diff --git a/packages/hardhat-ledger/src/internal/with-spinners.ts b/packages/hardhat-ledger/src/internal/with-spinners.ts new file mode 100644 index 0000000000..c5be5f509c --- /dev/null +++ b/packages/hardhat-ledger/src/internal/with-spinners.ts @@ -0,0 +1,53 @@ +import ora from "ora"; +import EventEmitter from "events"; + +export type OutputControlledEmitter = EventEmitter & { + isOutputEnabled: boolean; +}; + +export function withSpinners(emitter: T): T { + attachSpinner(emitter, { + startText: "[hardhat-ledger] Connecting wallet", + eventPrefix: "connection", + }); + + attachSpinner(emitter, { + startText: "[hardhat-ledger] Waiting for confirmation", + eventPrefix: "confirmation", + }); + + const derivationSpinner = attachSpinner(emitter, { + startText: "[hardhat-ledger] Finding derivation path", + eventPrefix: "derivation", + }); + emitter.on("derivation_progress", (path: string, index: number) => + emitter.isOutputEnabled + ? (derivationSpinner.text = `[hardhat-ledger] Deriving address #${index} (path "${path}")`) + : undefined + ); + + return emitter; +} + +function attachSpinner( + emitter: OutputControlledEmitter, + spinnerOptions: { + startText: string; + eventPrefix: string; + } +): ora.Ora { + const { startText, eventPrefix } = spinnerOptions; + const spinner = ora({ text: startText, discardStdin: false }); + + emitter.on(`${eventPrefix}_start`, () => + emitter.isOutputEnabled ? spinner.start() : undefined + ); + emitter.on(`${eventPrefix}_success`, () => + emitter.isOutputEnabled ? spinner.succeed() : undefined + ); + emitter.on(`${eventPrefix}_failure`, () => + emitter.isOutputEnabled ? spinner.fail() : undefined + ); + + return spinner; +} diff --git a/packages/hardhat-ledger/src/internal/wrap-transport.ts b/packages/hardhat-ledger/src/internal/wrap-transport.ts new file mode 100644 index 0000000000..1e57f399b3 --- /dev/null +++ b/packages/hardhat-ledger/src/internal/wrap-transport.ts @@ -0,0 +1,8 @@ +import Eth from "@ledgerhq/hw-app-eth"; +import Transport from "@ledgerhq/hw-transport"; + +import { EthWrapper } from "../types"; + +export function wrapTransport(transport: Transport): EthWrapper { + return new Eth(transport); +} diff --git a/packages/hardhat-ledger/src/provider.ts b/packages/hardhat-ledger/src/provider.ts new file mode 100644 index 0000000000..a315612910 --- /dev/null +++ b/packages/hardhat-ledger/src/provider.ts @@ -0,0 +1,456 @@ +import { ethers } from "ethers"; +import * as t from "io-ts"; + +import { isValidAddress } from "@ethereumjs/util"; + +import { isEIP712Message, ledgerService } from "@ledgerhq/hw-app-eth"; +import TransportNodeHid from "@ledgerhq/hw-transport-node-hid"; +import { EIP712Message } from "@ledgerhq/hw-app-eth/lib/modules/EIP712"; +import { EIP1193Provider, RequestArguments } from "hardhat/types"; +import { validateParams } from "hardhat/internal/core/jsonrpc/types/input/validation"; +import { rpcTransactionRequest } from "hardhat/internal/core/jsonrpc/types/input/transactionRequest"; +import { + rpcAddress, + rpcData, + rpcQuantityToBigInt, +} from "hardhat/internal/core/jsonrpc/types/base-types"; +import { ProviderWrapperWithChainId } from "hardhat/internal/core/providers/chainId"; +import { HardhatError } from "hardhat/internal/core/errors"; +import { ERRORS } from "hardhat/internal/core/errors-list"; + +import * as cache from "./internal/cache"; +import { toHex } from "./internal/utils"; +import { wrapTransport } from "./internal/wrap-transport"; +import { LedgerOptions, EthWrapper, Signature, Paths } from "./types"; +import { + HardhatLedgerConnectionError, + HardhatLedgerDerivationPathError, + HardhatLedgerError, + HardhatLedgerNotControlledAddressError, +} from "./errors"; + +export class LedgerProvider extends ProviderWrapperWithChainId { + public static readonly MAX_DERIVATION_ACCOUNTS = 20; + public static readonly DEFAULT_TIMEOUT = 3000; + + public readonly paths: Paths = {}; // { address: path } + public name: string = "LedgerProvider"; + public isOutputEnabled: boolean = true; + + protected _eth: EthWrapper | undefined; + + public static async create( + options: LedgerOptions, + wrappedProvider: EIP1193Provider + ) { + const provider = new LedgerProvider(options, wrappedProvider); + await provider.init(); + return provider; + } + + constructor( + public readonly options: LedgerOptions, + _wrappedProvider: EIP1193Provider + ) { + super(_wrappedProvider); + + this.options.accounts = options.accounts.map((account) => { + if (!isValidAddress(account)) { + throw new HardhatLedgerError( + `The following ledger address from the config is invalid: ${account}` + ); + } + return account.toLowerCase(); + }); + } + + public get eth(): EthWrapper { + if (this._eth === undefined) { + throw new HardhatError(ERRORS.GENERAL.UNINITIALIZED_PROVIDER); + } + return this._eth; + } + + public async init(): Promise { + // If init is called concurrently, it can cause the Ledger to throw + // because the transport might be in use. This is a known problem but shouldn't happen + // as init is not called manually. More info read: https://github.com/NomicFoundation/hardhat/pull/4008#discussion_r1233258204 + + if (this._eth === undefined) { + const openTimeout = + this.options.openTimeout ?? LedgerProvider.DEFAULT_TIMEOUT; + + const connectionTimeout = + this.options.connectionTimeout ?? LedgerProvider.DEFAULT_TIMEOUT; + + try { + this.emit("connection_start"); + + const transport = await TransportNodeHid.create( + openTimeout, + connectionTimeout + ); + this._eth = wrapTransport(transport); + + this.emit("connection_success"); + } catch (error) { + this.emit("connection_failure"); + + if (error instanceof Error) { + throw new HardhatLedgerConnectionError(error); + } + + throw error; + } + } + + try { + const paths = await cache.read(); + if (paths !== undefined) { + Object.assign(this.paths, paths); + } + } catch (error) {} + } + + public async request(args: RequestArguments): Promise { + const params = this._getParams(args); + + if (args.method === "hardhat_setLedgerOutputEnabled") { + return this._setOutputEnabled(params); + } + + if (args.method === "eth_accounts") { + const accounts = (await this._wrappedProvider.request(args)) as string[]; + return [...accounts, ...this.options.accounts]; + } + + if (this._methodRequiresSignature(args.method)) { + try { + if (args.method === "eth_sign") { + return await this._ethSign(params); + } + + if (args.method === "personal_sign") { + return await this._personalSign(params); + } + + if (args.method === "eth_signTypedData_v4") { + return await this._ethSignTypedDataV4(params); + } + + if (args.method === "eth_sendTransaction" && params.length > 0) { + return await this._ethSendTransaction(params); + } + } catch (error) { + // We skip non controlled errors and forward them to the wrapped provider + if (!HardhatLedgerNotControlledAddressError.instanceOf(error)) { + throw error; + } + } + } + + return this._wrappedProvider.request(args); + } + + private _methodRequiresSignature(method: string): boolean { + return [ + "personal_sign", + "eth_sign", + "eth_signTypedData_v4", + "eth_sendTransaction", + ].includes(method); + } + + private async _ethSign(params: any[]): Promise { + if (params.length > 0) { + const [address, data] = validateParams(params, rpcAddress, rpcData); + + await this._requireControlledInit(address); + + if (address !== undefined) { + if (data === undefined) { + throw new HardhatError(ERRORS.NETWORK.ETHSIGN_MISSING_DATA_PARAM); + } + + const path = await this._derivePath(address); + const signature = await this._withConfirmation(() => + this.eth.signPersonalMessage(path, data.toString("hex")) + ); + return this._toRpcSig(signature); + } + } + } + + private async _personalSign(params: any[]): Promise { + if (params.length > 0) { + const [data, address] = validateParams(params, rpcData, rpcAddress); + + await this._requireControlledInit(address); + + if (data !== undefined) { + if (address === undefined) { + throw new HardhatError( + ERRORS.NETWORK.PERSONALSIGN_MISSING_ADDRESS_PARAM + ); + } + + const path = await this._derivePath(address); + const signature = await this._withConfirmation(() => + this.eth.signPersonalMessage(path, data.toString("hex")) + ); + return this._toRpcSig(signature); + } + } + } + + private async _ethSignTypedDataV4(params: any[]): Promise { + const [address, data] = validateParams(params, rpcAddress, t.any as any); + + await this._requireControlledInit(address); + + if (data === undefined) { + throw new HardhatError(ERRORS.NETWORK.ETHSIGN_MISSING_DATA_PARAM); + } + + let typedMessage: EIP712Message; + try { + typedMessage = typeof data === "string" ? JSON.parse(data) : data; + + if (!isEIP712Message(typedMessage)) { + throw new HardhatError( + ERRORS.NETWORK.ETHSIGN_TYPED_DATA_V4_INVALID_DATA_PARAM + ); + } + } catch { + throw new HardhatError( + ERRORS.NETWORK.ETHSIGN_TYPED_DATA_V4_INVALID_DATA_PARAM + ); + } + + const { types, domain, message, primaryType } = typedMessage; + const { EIP712Domain: _, ...structTypes } = types; + + const path = await this._derivePath(address); + const signature = await this._withConfirmation(async () => { + try { + return await this.eth.signEIP712Message(path, typedMessage); + } catch (error) { + return this.eth.signEIP712HashedMessage( + path, + ethers.TypedDataEncoder.hashDomain(domain), + ethers.TypedDataEncoder.hashStruct(primaryType, structTypes, message) + ); + } + }); + + return this._toRpcSig(signature); + } + + private async _ethSendTransaction(params: any[]): Promise { + const [txRequest] = validateParams(params, rpcTransactionRequest); + + await this._requireControlledInit(txRequest.from); + + if (txRequest.gas === undefined) { + throw new HardhatError(ERRORS.NETWORK.MISSING_TX_PARAM_TO_SIGN_LOCALLY, { + param: "gas", + }); + } + + const hasGasPrice = txRequest.gasPrice !== undefined; + const hasEip1559Fields = + txRequest.maxFeePerGas !== undefined || + txRequest.maxPriorityFeePerGas !== undefined; + + if (!hasGasPrice && !hasEip1559Fields) { + throw new HardhatError(ERRORS.NETWORK.MISSING_FEE_PRICE_FIELDS); + } + + if (hasGasPrice && hasEip1559Fields) { + throw new HardhatError(ERRORS.NETWORK.INCOMPATIBLE_FEE_PRICE_FIELDS); + } + + if (hasEip1559Fields && txRequest.maxFeePerGas === undefined) { + throw new HardhatError(ERRORS.NETWORK.MISSING_TX_PARAM_TO_SIGN_LOCALLY, { + param: "maxFeePerGas", + }); + } + + if (hasEip1559Fields && txRequest.maxPriorityFeePerGas === undefined) { + throw new HardhatError(ERRORS.NETWORK.MISSING_TX_PARAM_TO_SIGN_LOCALLY, { + param: "maxPriorityFeePerGas", + }); + } + + const path = await this._derivePath(txRequest.from); + + if (txRequest.nonce === undefined) { + txRequest.nonce = await this._getNonce(txRequest.from); + } + + const chainId = await this._getChainId(); + + const baseTx: ethers.TransactionLike = { + chainId, + gasLimit: txRequest.gas, + gasPrice: txRequest.gasPrice, + maxFeePerGas: txRequest.maxFeePerGas, + maxPriorityFeePerGas: txRequest.maxPriorityFeePerGas, + nonce: Number(txRequest.nonce), + value: txRequest.value, + }; + if (txRequest.to !== undefined) { + baseTx.to = toHex(txRequest.to); + } + if (txRequest.data !== undefined) { + baseTx.data = toHex(txRequest.data); + } + + const txToSign = + ethers.Transaction.from(baseTx).unsignedSerialized.substring(2); + + const resolution = await ledgerService.resolveTransaction(txToSign, {}, {}); + + const signature = await this._withConfirmation(() => + this.eth.signTransaction(path, txToSign, resolution) + ); + + const rawTransaction = ethers.Transaction.from({ + ...baseTx, + signature: { + v: toHex(signature.v), + r: toHex(signature.r), + s: toHex(signature.s), + }, + }).serialized; + + return this._wrappedProvider.request({ + method: "eth_sendRawTransaction", + params: [rawTransaction], + }); + } + + private async _derivePath(addressToFindAsBuffer: Buffer): Promise { + const addressToFind = toHex(addressToFindAsBuffer).toLowerCase(); + + if (this.paths[addressToFind] !== undefined) { + return this.paths[addressToFind]; + } + + this.emit("derivation_start"); + + let path = ""; + try { + for ( + let account = 0; + account <= LedgerProvider.MAX_DERIVATION_ACCOUNTS; + account++ + ) { + path = this._getDerivationPath(account); + + this.emit("derivation_progress", path, account); + + const wallet = await this.eth.getAddress(path); + const address = wallet.address.toLowerCase(); + + if (address === addressToFind) { + this.emit("derivation_success", path); + this.paths[addressToFind] = path; + + void cache.write(this.paths); // hanging promise + + return path; + } + } + } catch (error) { + const message = (error as Error).message; + + this.emit("derivation_failure"); + throw new HardhatLedgerDerivationPathError( + `There was an error trying to derivate path ${path}: "${message}". The wallet might be connected but locked or in the wrong app.`, + path + ); + } + + this.emit("derivation_failure"); + throw new HardhatLedgerDerivationPathError( + `Could not find a valid derivation path for ${addressToFind}. Paths from ${this._getDerivationPath( + 0 + )} to ${this._getDerivationPath( + LedgerProvider.MAX_DERIVATION_ACCOUNTS + )} were searched.`, + path + ); + } + + private _getDerivationPath(index: number): string { + if (this.options.derivationFunction === undefined) { + return `m/44'/60'/${index}'/0/0`; + } else { + return this.options.derivationFunction(index); + } + } + + private async _withConfirmation any>( + func: T + ): Promise> { + try { + this.emit("confirmation_start"); + const result = await func(); + this.emit("confirmation_success"); + + return result; + } catch (error) { + this.emit("confirmation_failure"); + throw new HardhatLedgerError((error as Error).message); + } + } + + private async _toRpcSig(signature: Signature): Promise { + const { toRpcSig, toBytes } = await import("@ethereumjs/util"); + + return toRpcSig( + BigInt(signature.v - 27), + toBytes(toHex(signature.r)), + toBytes(toHex(signature.s)) + ); + } + + private async _getNonce(address: Buffer): Promise { + const { bytesToHex } = await import("@ethereumjs/util"); + + const response = (await this._wrappedProvider.request({ + method: "eth_getTransactionCount", + params: [bytesToHex(address), "pending"], + })) as string; + + return rpcQuantityToBigInt(response); + } + + private async _requireControlledInit(address: Buffer): Promise { + this._requireControlledAddress(address); + await this.init(); + } + + private _requireControlledAddress(address: Buffer): void { + const hexAddress = toHex(address).toLowerCase(); + const isControlledAddress = this.options.accounts.includes(hexAddress); + + if (!isControlledAddress) { + throw new HardhatLedgerNotControlledAddressError( + "Tried to send a transaction with an address we don't control.", + hexAddress + ); + } + } + + /** + * Toggles the provider's output. Use to suppress default feedback and + * manage it via events. + */ + private _setOutputEnabled(params: any[]): void { + const [enabled] = validateParams(params, t.boolean); + + this.isOutputEnabled = enabled; + } +} diff --git a/packages/hardhat-ledger/src/type-extensions.ts b/packages/hardhat-ledger/src/type-extensions.ts new file mode 100644 index 0000000000..4914af3e86 --- /dev/null +++ b/packages/hardhat-ledger/src/type-extensions.ts @@ -0,0 +1,29 @@ +import "hardhat/types/config"; + +declare module "hardhat/types/config" { + interface HardhatNetworkUserConfig { + ledgerAccounts?: string[]; + ledgerOptions?: { + derivationFunction?: (accountNumber: number) => string; + }; + } + interface HardhatNetworkConfig { + ledgerAccounts: string[]; + ledgerOptions?: { + derivationFunction?: (accountNumber: number) => string; + }; + } + + interface HttpNetworkUserConfig { + ledgerAccounts?: string[]; + ledgerOptions?: { + derivationFunction?: (accountNumber: number) => string; + }; + } + interface HttpNetworkConfig { + ledgerAccounts: string[]; + ledgerOptions?: { + derivationFunction?: (accountNumber: number) => string; + }; + } +} diff --git a/packages/hardhat-ledger/src/types.ts b/packages/hardhat-ledger/src/types.ts new file mode 100644 index 0000000000..7d0bf4b0da --- /dev/null +++ b/packages/hardhat-ledger/src/types.ts @@ -0,0 +1,24 @@ +import Eth from "@ledgerhq/hw-app-eth"; + +export interface EthWrapper { + getAddress: Eth["getAddress"]; + signPersonalMessage: Eth["signPersonalMessage"]; + signEIP712Message: Eth["signEIP712Message"]; + signEIP712HashedMessage: Eth["signEIP712HashedMessage"]; + signTransaction: Eth["signTransaction"]; +} + +export interface Signature { + v: number; + s: string; + r: string; +} + +export interface LedgerOptions { + openTimeout?: number; + connectionTimeout?: number; + accounts: string[]; + derivationFunction?: (index: number) => string; +} + +export type Paths = Record; // { address: path } diff --git a/packages/hardhat-ledger/test/.eslintrc.js b/packages/hardhat-ledger/test/.eslintrc.js new file mode 100644 index 0000000000..12ee5882f1 --- /dev/null +++ b/packages/hardhat-ledger/test/.eslintrc.js @@ -0,0 +1,11 @@ +module.exports = { + extends: [`${__dirname}/../.eslintrc.js`], + rules: { + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: true, + }, + ], + }, +}; diff --git a/packages/hardhat-ledger/test/errors.ts b/packages/hardhat-ledger/test/errors.ts new file mode 100644 index 0000000000..b07186d945 --- /dev/null +++ b/packages/hardhat-ledger/test/errors.ts @@ -0,0 +1,80 @@ +import { assert } from "chai"; + +import { + HardhatLedgerConnectionError, + HardhatLedgerDerivationPathError, + HardhatLedgerError, + HardhatLedgerNotControlledAddressError, +} from "../src/errors"; + +describe("HardhatLedgerError", () => { + it("should set the plugin name of the error", () => { + const error = new HardhatLedgerError(""); + assert.equal(error.pluginName, "@nomicfoundation/hardhat-ledger"); + }); + + it("should set the message of the error", () => { + const message = "Some message"; + const error = new HardhatLedgerError(message); + assert.equal(error.message, message); + }); +}); + +describe("HardhatLedgerNotControlledAddressError", () => { + it("should set the message of the error", () => { + const message = "Look, a message"; + const error = new HardhatLedgerNotControlledAddressError(message, ""); + assert.equal(error.message, message); + }); + + it("should store the address", () => { + const address = "0x3d6e2674e40ea221b4a48663d28eff77af564a50"; + const error = new HardhatLedgerNotControlledAddressError("", address); + assert.equal(error.address, address); + }); + + it("should detect a HardhatLedgerNotControlledAddressError", () => { + assert.isFalse( + HardhatLedgerNotControlledAddressError.instanceOf(new Error()) + ); + assert.isTrue( + HardhatLedgerNotControlledAddressError.instanceOf( + new HardhatLedgerNotControlledAddressError("", "") + ) + ); + }); +}); + +describe("HardhatLedgerDerivationPathError", () => { + it("should set the message of the error", () => { + const message = "Yet another message"; + const error = new HardhatLedgerDerivationPathError(message, ""); + assert.equal(error.message, message); + }); + + it("should store the path", () => { + const path = "m/44'/60'/0'/0/0"; + const error = new HardhatLedgerDerivationPathError("", path); + assert.equal(error.path, path); + }); + + it("should detect a HardhatLedgerDerivationPathError", () => { + assert.isFalse(HardhatLedgerDerivationPathError.instanceOf(new Error())); + assert.isTrue( + HardhatLedgerDerivationPathError.instanceOf( + new HardhatLedgerDerivationPathError("", "") + ) + ); + }); +}); + +describe("HardhatLedgerConnectionError", () => { + it("should detect a HardhatLegerConnectionError", () => { + assert.isFalse(HardhatLedgerConnectionError.instanceOf(new Error())); + assert.isTrue( + HardhatLedgerConnectionError.instanceOf( + new HardhatLedgerConnectionError(new Error("")) + ) + ); + }); +}); diff --git a/packages/hardhat-ledger/test/internal/cache.ts b/packages/hardhat-ledger/test/internal/cache.ts new file mode 100644 index 0000000000..c24dd69896 --- /dev/null +++ b/packages/hardhat-ledger/test/internal/cache.ts @@ -0,0 +1,50 @@ +import { assert } from "chai"; +import envPaths from "env-paths"; +import fs from "fs-extra"; +import sinon from "sinon"; +import path from "path"; + +import * as cache from "../../src/internal/cache"; + +describe("cache", () => { + let fsStub: sinon.SinonStubbedInstance; + let cacheDir: string; + + beforeEach(() => { + const { cache: cachePath } = envPaths("hardhat"); + + cacheDir = path.join(cachePath, "ledger", cache.CACHE_FILE_NAME); + fsStub = sinon.stub(fs); + }); + + afterEach(() => { + sinon.restore(); + }); + + describe("write", () => { + it("should write the supplied json to the ledger cache file", async () => { + const json = { some: "json" }; + await cache.write(json); + + // We need to do this by hand cause sinon does not play nice with overloads + const args = fsStub.writeJSON.getCall(0).args; + + assert.equal(args.length, 2); + assert.equal(args[0], cacheDir); + assert.deepEqual(args[1], json); + }); + }); + + describe("read", () => { + it("should read the ledger cache file", async () => { + const json = { another: "json" }; + + // We need to do this cast cause sinon does not play nice with overloads + fsStub.readJSON.returns(Promise.resolve(json) as any); + + const result = await cache.read(); + + assert.deepEqual(result, json); + }); + }); +}); diff --git a/packages/hardhat-ledger/test/internal/create-ledger-provider.ts b/packages/hardhat-ledger/test/internal/create-ledger-provider.ts new file mode 100644 index 0000000000..23de54034a --- /dev/null +++ b/packages/hardhat-ledger/test/internal/create-ledger-provider.ts @@ -0,0 +1,80 @@ +import { assert } from "chai"; +import sinon from "sinon"; + +import { NetworkConfig } from "hardhat/types"; + +import { EthereumMockedProvider } from "../mocks"; +import { createLedgerProvider } from "../../src/internal/create-ledger-provider"; +import * as spinners from "../../src/internal/with-spinners"; + +describe("createLedgerProvider", () => { + let mockedProvider: EthereumMockedProvider; + + beforeEach(() => { + mockedProvider = new EthereumMockedProvider(); + }); + + it("should pass the ledgerAccounts from the config to the LedgerProvider", () => { + const ledgerAccounts = [ + "0x704ad3adfa9eae2be46c907ef5325d0fabe17353", + "0xf4416d306caa15dd4cdf4cd882cd764a6b2aa9b2", + "0xe149ff2797adc146aa2d68d3df3e819c3c38e762", + "0x343fe45cd2d785a5f2e97a00de8436f9c42ef444", + ]; + const config = { ledgerAccounts } as NetworkConfig; + const ledgerProvider = createLedgerProvider(mockedProvider, config); + + assert.deepEqual(ledgerProvider.options.accounts, ledgerAccounts); + // Did not pass a derivation function, so should be undefined + assert.equal(ledgerProvider.options.derivationFunction, undefined); + }); + + it("should pass the ledgerLegacyDerivationPath from the config to the LedgerProvider", () => { + const ledgerAccounts = [ + "0x704ad3adfa9eae2be46c907ef5325d0fabe17353", + "0xf4416d306caa15dd4cdf4cd882cd764a6b2aa9b2", + "0xe149ff2797adc146aa2d68d3df3e819c3c38e762", + "0x343fe45cd2d785a5f2e97a00de8436f9c42ef444", + ]; + const derivationFunction = (accountNumber: number) => { + return `m/44'/60'/0'/${accountNumber}`; // legacy derivation path + }; + const config = { + ledgerAccounts, + ledgerOptions: { + derivationFunction, + }, + } as NetworkConfig; + const ledgerProvider = createLedgerProvider(mockedProvider, config); + + assert.deepEqual( + ledgerProvider.options.derivationFunction, + derivationFunction + ); + }); + + it("should pass the provider to the LedgerProvider", async () => { + const config = { + ledgerAccounts: ["0xf4416d306caa15dd4cdf4cd882cd764a6b2aa9b2"], + } as NetworkConfig; + const ledgerProvider = createLedgerProvider(mockedProvider, config); + const requestStub = sinon.stub(mockedProvider, "request"); + + await ledgerProvider.request({ method: "eth_blockNumber" }); + + sinon.assert.calledOnceWithExactly(requestStub, { + method: "eth_blockNumber", + }); + }); + + it("should return a new LedgerProvider with spinners handlers attached", () => { + const withSpinnerSpy = sinon.spy(spinners, "withSpinners"); + + const config = { + ledgerAccounts: ["0xe149ff2797adc146aa2d68d3df3e819c3c38e762"], + } as NetworkConfig; + const ledgerProvider = createLedgerProvider(mockedProvider, config); + + sinon.assert.calledOnceWithExactly(withSpinnerSpy, ledgerProvider); + }); +}); diff --git a/packages/hardhat-ledger/test/internal/utils.ts b/packages/hardhat-ledger/test/internal/utils.ts new file mode 100644 index 0000000000..6f7c20a9ea --- /dev/null +++ b/packages/hardhat-ledger/test/internal/utils.ts @@ -0,0 +1,20 @@ +import { assert } from "chai"; +import { toHex } from "../../src/internal/utils"; + +describe("toHex", () => { + it("should append 0x to the supplied string value", () => { + assert.equal(toHex("123"), "0x123"); + }); + + it("should not append 0x if the supplied string value already has it", () => { + assert.equal(toHex("0x123"), "0x123"); + }); + + it("should return the 0x hex representation of the Buffer", () => { + // "736f6d6520737472696e67".toString("hex") === "736f6d6520737472696e67" + assert.equal( + toHex(Buffer.from("some string", "utf8")), + "0x736f6d6520737472696e67" + ); + }); +}); diff --git a/packages/hardhat-ledger/test/internal/with-spinners.ts b/packages/hardhat-ledger/test/internal/with-spinners.ts new file mode 100644 index 0000000000..1c8748482f --- /dev/null +++ b/packages/hardhat-ledger/test/internal/with-spinners.ts @@ -0,0 +1,56 @@ +import type { OutputControlledEmitter } from "../../src/internal/with-spinners"; + +import { assert } from "chai"; +import sinon from "sinon"; +import EventEmitter from "events"; +import { withSpinners } from "../../src/internal/with-spinners"; + +describe("withSpinners", () => { + let eventEmitter: OutputControlledEmitter; + + function containsArray(baseArray: Array, values: string[]) { + return values.every((value) => baseArray.includes(value)); + } + + beforeEach(() => { + eventEmitter = new EventEmitter() as OutputControlledEmitter; + }); + + afterEach(() => { + sinon.restore(); + }); + + it("should attach the connection events", () => { + const emitter = withSpinners(eventEmitter); + assert.isTrue( + containsArray(emitter.eventNames(), [ + "connection_start", + "connection_success", + "connection_failure", + ]) + ); + }); + + it("should attach the derivation events", () => { + const emitter = withSpinners(eventEmitter); + assert.isTrue( + containsArray(emitter.eventNames(), [ + "derivation_start", + "derivation_success", + "derivation_failure", + "derivation_progress", + ]) + ); + }); + + it("should attach the confirmation events", () => { + const emitter = withSpinners(eventEmitter); + assert.isTrue( + containsArray(emitter.eventNames(), [ + "confirmation_start", + "confirmation_success", + "confirmation_failure", + ]) + ); + }); +}); diff --git a/packages/hardhat-ledger/test/mocks.ts b/packages/hardhat-ledger/test/mocks.ts new file mode 100644 index 0000000000..8423da4de2 --- /dev/null +++ b/packages/hardhat-ledger/test/mocks.ts @@ -0,0 +1,10 @@ +import EventEmitter from "events"; + +import { EIP1193Provider, RequestArguments } from "hardhat/types"; + +export class EthereumMockedProvider + extends EventEmitter + implements EIP1193Provider +{ + public async request(_args: RequestArguments): Promise {} +} diff --git a/packages/hardhat-ledger/test/provider.ts b/packages/hardhat-ledger/test/provider.ts new file mode 100644 index 0000000000..928a282ce8 --- /dev/null +++ b/packages/hardhat-ledger/test/provider.ts @@ -0,0 +1,756 @@ +import { assert } from "chai"; +import sinon from "sinon"; + +import Eth from "@ledgerhq/hw-app-eth"; +import TransportNodeHid from "@ledgerhq/hw-transport-node-hid"; +import Transport from "@ledgerhq/hw-transport"; +import { EIP712Message } from "@ledgerhq/hw-app-eth/lib/modules/EIP712"; +import { TransportError } from "@ledgerhq/errors"; + +import { RequestArguments } from "hardhat/types"; + +import * as ethWrapper from "../src/internal/wrap-transport"; +import * as cache from "../src/internal/cache"; +import { LedgerProvider } from "../src/provider"; +import { EthWrapper, LedgerOptions } from "../src/types"; +import { + HardhatLedgerConnectionError, + HardhatLedgerDerivationPathError, +} from "../src/errors"; +import { EthereumMockedProvider } from "./mocks"; + +describe("LedgerProvider", () => { + let accounts: string[]; + let mockedProvider: EthereumMockedProvider; + let ethInstanceStub: sinon.SinonStubbedInstance; + let cacheStub: sinon.SinonStubbedInstance; + let provider: LedgerProvider; + + function stubTransport(transport: Transport) { + return sinon + .stub(TransportNodeHid, "create") + .returns(Promise.resolve(transport)); + } + + beforeEach(() => { + accounts = [ + "0xa809931e3b38059adae9bc5455bc567d0509ab92", + "0xda6a52afdae5ff66aa786da68754a227331f56e3", + "0xbc307688a80ec5ed0edc1279c44c1b34f7746bda", + ]; + mockedProvider = new EthereumMockedProvider(); + ethInstanceStub = sinon.createStubInstance(Eth); + cacheStub = sinon.stub(cache); + + sinon.stub(ethWrapper, "wrapTransport").returns(ethInstanceStub); + cacheStub.read.returns(Promise.resolve(undefined)); + + provider = new LedgerProvider({ accounts }, mockedProvider); + }); + + afterEach(() => { + sinon.restore(); + }); + + describe("instance", () => { + it("should lowercase all accounts", () => { + const uppercaseAccounts = [ + "0xA809931E3B38059ADAE9BC5455BC567D0509AB92", + "0xDA6A52AFDAE5FF66AA786DA68754A227331F56E3", + "0xBC307688A80EC5ED0EDC1279C44C1B34F7746BDA", + ]; + const uppercaseProvider = new LedgerProvider( + { accounts: uppercaseAccounts }, + mockedProvider + ); + const lowercasedAccounts = uppercaseAccounts.map((account) => + account.toLowerCase() + ); + + assert.deepEqual(uppercaseProvider.options.accounts, lowercasedAccounts); + }); + + it("should check for valid ethereum addresses", () => { + assert.throws( + () => + new LedgerProvider( + { + accounts: [ + "0xe149ff2797adc146aa2d68d3df3e819c3c38e762", + "0x1", + "0x343fe45cd2d785a5F2e97a00de8436f9c42Ef444", + ], + }, + mockedProvider + ), + "The following ledger address from the config is invalid: 0x1" + ); + }); + }); + + describe("create", () => { + beforeEach(() => { + stubTransport(new Transport()); + }); + + it("should return a provider instance", async () => { + const newProvider = await LedgerProvider.create( + { accounts }, + mockedProvider + ); + assert.instanceOf(newProvider, LedgerProvider); + }); + + it("should init the provider", async () => { + const spy = sinon.spy(LedgerProvider.prototype, "init"); + await LedgerProvider.create({ accounts }, mockedProvider); + assert.isTrue(spy.calledOnce); + }); + }); + + describe("init", () => { + let transport: Transport; + let createStub: sinon.SinonStub; + + beforeEach(() => { + transport = new Transport(); + createStub = stubTransport(transport); + }); + + it("should call the create method on TransportNodeHid", async () => { + await provider.init(); + + sinon.assert.calledOnceWithExactly( + createStub, + LedgerProvider.DEFAULT_TIMEOUT, + LedgerProvider.DEFAULT_TIMEOUT + ); + }); + + it("should only init once on multiple calls", async () => { + await provider.init(); + await provider.init(); + await provider.init(); + + sinon.assert.calledOnceWithExactly( + createStub, + LedgerProvider.DEFAULT_TIMEOUT, + LedgerProvider.DEFAULT_TIMEOUT + ); + }); + + it("should pass the timeout options to the Transport creation", async () => { + const options: LedgerOptions = { + accounts, + openTimeout: 1000, + connectionTimeout: 5432, + }; + const newProvider = new LedgerProvider(options, mockedProvider); + await newProvider.init(); + + sinon.assert.calledOnceWithExactly( + createStub, + options.openTimeout, + options.connectionTimeout + ); + }); + + it("should create an eth instance", async () => { + await provider.init(); + assert.instanceOf(provider.eth, Eth); + }); + + it("should throw a ledger provider error if create does", async () => { + const createError = new Error("Test Error"); + createStub.throws(createError); + + try { + await provider.init(); + } catch (error) { + if (!HardhatLedgerConnectionError.instanceOf(error)) { + assert.fail("Expected a ConnectionError"); + } + assert.include( + error.message, + `There was an error trying to establish a connection to the Ledger wallet: "${createError.message}".` + ); + } + }); + + it("should throw an error with the proper explanation if a transport error is thrown", async () => { + const createError = new TransportError( + "Transport Error", + "Transport Error Id" + ); + createStub.throws(createError); + + try { + await provider.init(); + } catch (error) { + if (!HardhatLedgerConnectionError.instanceOf(error)) { + assert.fail("Expected a ConnectionError"); + } + assert.include( + error.message, + `There was an error trying to establish a connection to the Ledger wallet: "${createError.message}".` + ); + assert.include(error.message, `The error id was: ${createError.id}`); + } + }); + + it("should start the paths cache with what the cache returns", async () => { + const newPaths = { + "0xe149ff2797adc146aa2d68d3df3e819c3c38e762": "m/44'/60'/0'/0/0", + }; + const oldPaths = { ...provider.paths }; // new object + + cacheStub.read.returns(Promise.resolve(newPaths)); + await provider.init(); + + assert.deepEqual(oldPaths, {}); + assert.deepEqual(newPaths, provider.paths); + }); + + describe("events", () => { + let emitSpy: sinon.SinonSpy; + + beforeEach(() => { + emitSpy = sinon.spy(provider, "emit"); + }); + + it("should emit the connection_start event", async () => { + await provider.init(); + sinon.assert.calledWithExactly(emitSpy, "connection_start"); + }); + + it("should emit the connection_success event if everything goes right", async () => { + await provider.init(); + sinon.assert.calledWithExactly(emitSpy, "connection_start"); + }); + + it("should emit the connection_failure if the connection fails", async () => { + try { + createStub.throws(new Error()); + await provider.init(); + } catch (error) {} + sinon.assert.calledWithExactly(emitSpy, "connection_failure"); + }); + }); + }); + + describe("request", () => { + let path: string; + let account: { address: string; publicKey: string }; + let rsv: { v: number; r: string; s: string }; + let txRsv: { v: string; r: string; s: string }; + let signature: string; + let dataToSign: string; + let typedMessage: EIP712Message; + let initSpy: sinon.SinonSpy; + + beforeEach(async () => { + stubTransport(new Transport()); + + initSpy = sinon.spy(provider, "init"); + + path = "m/44'/60'/1'/0/0"; + account = { + address: accounts[1], + publicKey: "0x1", + }; + ethInstanceStub.getAddress.callsFake(async (searchedPath: string) => + searchedPath === path ? account : { address: "0x0", publicKey: "0x0" } + ); + + rsv = { + v: 55, + r: "4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d", + s: "7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd0", + }; + txRsv = { + v: "f4f5", + r: "4ab14d7e96a8bc7390cfffa0260d4b82848428ce7f5b8dd367d13bf31944b6c0", + s: "3cc226daa6a2f4e22334c59c2e04ac72672af72907ec9c4a601189858ba60069", + }; + signature = + "0x4f4c17305743700648bc4f6cd3038ec6f6af0df73e31757007b7f59df7bee88d7e1941b264348e80c78c4027afc65a87b0a5e43e86742b8ca0823584c6788fd01c"; + dataToSign = + "0x5417aa2a18a44da0675524453ff108c545382f0d7e26605c56bba47c21b5e979"; + + typedMessage = { + types: { + EIP712Domain: [ + { name: "name", type: "string" }, + { name: "version", type: "string" }, + { name: "chainId", type: "uint256" }, + { name: "verifyingContract", type: "address" }, + ], + Person: [ + { name: "name", type: "string" }, + { name: "wallet", type: "address" }, + ], + Mail: [ + { name: "from", type: "Person" }, + { name: "to", type: "Person" }, + { name: "contents", type: "string" }, + ], + }, + primaryType: "Mail", + domain: { + name: "Ether Mail", + version: "1", + chainId: 1, + verifyingContract: "0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC", + }, + message: { + from: { + name: "Cow", + wallet: "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + }, + to: { + name: "Bob", + wallet: "0xbBbBBBBbbBBBbbbBbbBbbbbBBbBbbbbBbBbbBBbB", + }, + contents: "Hello, Bob!", + }, + }; + }); + + describe("unsupported methods", () => { + it("should not init the provider if and unsupported JSONRPC method is called", async () => { + sinon.stub(mockedProvider, "request"); + await provider.request({ method: "eth_blockNumber" }); + await provider.request({ method: "eth_getBlockByNumber" }); + await provider.request({ method: "net_version" }); + + sinon.assert.notCalled(initSpy); + }); + + it("should forward unsupported JSONRPC methods to the wrapped provider", async () => { + const requestStub = sinon.stub(mockedProvider, "request"); + + const blockNumberArgs = { + method: "eth_blockNumber", + params: [1, 2, 3], + }; + await provider.request(blockNumberArgs); + + const netVersionArgs = { + method: "eth_getBlockByNumber", + params: ["2.0"], + }; + await provider.request(netVersionArgs); + + sinon.assert.calledTwice(requestStub); + sinon.assert.calledWith(requestStub.getCall(0), blockNumberArgs); + sinon.assert.calledWith(requestStub.getCall(1), netVersionArgs); + }); + }); + + describe("supported (sign) methods", () => { + it("should forward to the wrapped provider if the address doing the signing is not controlled", async () => { + const requestStub = sinon.stub(mockedProvider, "request"); + + // the address is not on the accounts the providers manage + const uncontrolledAddress = + "0x76F8654a8e981A4a5D634c2d3cE56E195a65c319"; + + const requestArgs = [ + { + method: "eth_sign", + params: [uncontrolledAddress, dataToSign], + }, + { + method: "personal_sign", + params: [dataToSign, uncontrolledAddress], + }, + { + method: "eth_signTypedData_v4", + params: [uncontrolledAddress, typedMessage], + }, + { + method: "eth_sendTransaction", + params: [ + { + from: uncontrolledAddress, + to: accounts[1], + value: "0x100", + gas: "0x1000000", + gasPrice: "0x100", + gasLimit: "0x1000000", + }, + ], + }, + ]; + + for (const [index, args] of requestArgs.entries()) { + await provider.request(args); + sinon.assert.calledWithExactly(requestStub.getCall(index), args); + } + + sinon.assert.notCalled(initSpy); + }); + + it("should return the configured and base accounts when the JSONRPC eth_accounts method is called", async () => { + const baseAccounts = [ + "0x18225dbbd263d5a01ac537db4d1eefc12fae8b24", + "0x704ad3adfa9eae2be46c907ef5325d0fabe17353", + ]; + sinon.stub(mockedProvider, "request").callsFake(async (args) => { + if (args.method === "eth_accounts") { + return baseAccounts; + } + }); + + const resultAccounts = await provider.request({ + method: "eth_accounts", + }); + assert.deepEqual([...baseAccounts, ...accounts], resultAccounts); + sinon.assert.notCalled(initSpy); + }); + + it("should call the ledger's signPersonalMessage method when the JSONRPC personal_sign method is called", async () => { + const stub = ethInstanceStub.signPersonalMessage.returns( + Promise.resolve(rsv) + ); + + const resultSignature = await provider.request({ + method: "personal_sign", + params: [dataToSign, account.address], + }); + + sinon.assert.calledOnceWithExactly(stub, path, dataToSign.slice(2)); // slices 0x + assert.deepEqual(signature, resultSignature); + sinon.assert.calledOnce(initSpy); + }); + + it("should call the ledger's signPersonalMessage method when the JSONRPC eth_sign method is called", async () => { + const stub = ethInstanceStub.signPersonalMessage.returns( + Promise.resolve(rsv) + ); + + const resultSignature = await provider.request({ + method: "eth_sign", + params: [account.address, dataToSign], + }); + + sinon.assert.calledOnceWithExactly(stub, path, dataToSign.slice(2)); // slices 0x + assert.deepEqual(signature, resultSignature); + sinon.assert.calledOnce(initSpy); + }); + + it("should call the ledger's signEIP712Message method when the JSONRPC eth_signTypedData_v4 method is called", async () => { + const stub = ethInstanceStub.signEIP712Message.returns( + Promise.resolve(rsv) + ); + + const resultSignature = await provider.request({ + method: "eth_signTypedData_v4", + params: [account.address, typedMessage], + }); + + sinon.assert.calledOnceWithExactly(stub, path, typedMessage); + assert.deepEqual(signature, resultSignature); + sinon.assert.calledOnce(initSpy); + }); + + it("should call the ledger's signEIP712HashedMessage method when the JSONRPC eth_signTypedData_v4 method is called", async () => { + ethInstanceStub.signEIP712Message.throws("Unsupported Ledger"); + + const stub = ethInstanceStub.signEIP712HashedMessage.returns( + Promise.resolve(rsv) + ); + + const resultSignature = await provider.request({ + method: "eth_signTypedData_v4", + params: [account.address, typedMessage], + }); + + sinon.assert.calledOnceWithExactly( + stub, + path, + "0xf2cee375fa42b42143804025fc449deafd50cc031ca257e0b194a650a912090f", // hash domain + "0xc52c0ee5d84264471806290a3f2c4cecfc5490626bf912d01f240d7a274b371e" // hash struct + ); + assert.deepEqual(signature, resultSignature); + sinon.assert.calledOnce(initSpy); + }); + + it("should call the ledger's signTransaction method when the JSONRPC eth_sendTransaction method is called", async () => { + const numberToRpcQuantity = (n: number | bigint) => + `0x${n.toString(16)}`; + + const tx = + "0xf8626464830f4240949f649fe750340a295dddbbd7e1ec8f378cf24b43648082f4f5a04ab14d7e96a8bc7390cfffa0260d4b82848428ce7f5b8dd367d13bf31944b6c0a03cc226daa6a2f4e22334c59c2e04ac72672af72907ec9c4a601189858ba60069"; + + const requestStub = sinon.stub(); + sinon.replace( + mockedProvider, + "request", + async (args: RequestArguments) => { + requestStub(args); + + switch (args.method) { + case "eth_chainId": + return "0x7a69"; + case "eth_getTransactionCount": + return "0x64"; + case "eth_sendRawTransaction": + return tx; + } + } + ); + + const signTransactionStub = ethInstanceStub.signTransaction.returns( + Promise.resolve(txRsv) + ); + + const resultTx = await provider.request({ + method: "eth_sendTransaction", + params: [ + { + from: account.address, + to: accounts[1], + value: numberToRpcQuantity(100), + gas: numberToRpcQuantity(1000000), + gasPrice: numberToRpcQuantity(100), + gasLimit: numberToRpcQuantity(1000000), + }, + ], + }); + + sinon.assert.calledOnceWithExactly( + signTransactionStub, + path, + "01e1827a696464830f424094da6a52afdae5ff66aa786da68754a227331f56e36480c0", + { + nfts: [], + erc20Tokens: [], + externalPlugin: [], + plugin: [], + domains: [], + } + ); + sinon.assert.calledWithExactly(requestStub.getCall(0), { + method: "eth_getTransactionCount", + params: [account.address, "pending"], + }); + sinon.assert.calledWithExactly(requestStub.getCall(1), { + method: "eth_chainId", + }); + sinon.assert.calledWithExactly(requestStub.getCall(2), { + method: "eth_sendRawTransaction", + params: [ + "0x01f864827a696464830f424094da6a52afdae5ff66aa786da68754a227331f56e36480c080a04ab14d7e96a8bc7390cfffa0260d4b82848428ce7f5b8dd367d13bf31944b6c0a03cc226daa6a2f4e22334c59c2e04ac72672af72907ec9c4a601189858ba60069", + ], + }); + assert.equal(tx, resultTx); + sinon.assert.calledOnce(initSpy); + }); + }); + + describe("path derivation", () => { + async function requestPersonalSign() { + ethInstanceStub.signPersonalMessage.returns(Promise.resolve(rsv)); + await provider.request({ + method: "personal_sign", + params: [dataToSign, account.address], + }); + } + + it("should cache the derived path from the supplied accounts", async () => { + await requestPersonalSign(); + await requestPersonalSign(); + await requestPersonalSign(); + await requestPersonalSign(); + + sinon.assert.calledTwice(ethInstanceStub.getAddress); + sinon.assert.calledWith(ethInstanceStub.getAddress, "m/44'/60'/0'/0/0"); + sinon.assert.calledWith(ethInstanceStub.getAddress, "m/44'/60'/1'/0/0"); + }); + + it("should cache the path per address on the paths property", async () => { + await requestPersonalSign(); + await requestPersonalSign(); + + assert.deepEqual(provider.paths, { [accounts[1]]: path }); + }); + + it("should write the cache with the new paths", async () => { + await requestPersonalSign(); + await requestPersonalSign(); + await requestPersonalSign(); + + sinon.assert.calledOnceWithExactly(cacheStub.write, { + [accounts[1]]: path, + }); + }); + + it("should not break if caching fails", async () => { + cacheStub.write.returns(Promise.reject(new Error("Write error"))); + + let hasThrown = false; + try { + await requestPersonalSign(); + } catch (error) { + console.log(error); + hasThrown = true; + } + + assert.isFalse(hasThrown); + }); + + it("should throw a DerivationPathError if trying to get the address fails", async () => { + const errorMessage = "Getting the address broke"; + ethInstanceStub.getAddress.throws(new Error(errorMessage)); + try { + await requestPersonalSign(); + } catch (error) { + const errorPath = "m/44'/60'/0'/0/0"; + if (!HardhatLedgerDerivationPathError.instanceOf(error)) { + assert.fail("Expected a DerivationPathError"); + } + assert.equal(error.path, errorPath); + assert.equal( + (error as HardhatLedgerDerivationPathError).message, + `There was an error trying to derivate path ${errorPath}: "${errorMessage}". The wallet might be connected but locked or in the wrong app.` + ); + } + }); + + it("should throw a DerivationPathError if the max number of derivations is searched without a result", async () => { + try { + ethInstanceStub.getAddress.callsFake(async () => ({ + address: "0x0", + publicKey: "0x0", + })); + await requestPersonalSign(); + } catch (error) { + const errorPath = `m/44'/60'/${LedgerProvider.MAX_DERIVATION_ACCOUNTS}'/0/0`; + if (!HardhatLedgerDerivationPathError.instanceOf(error)) { + assert.fail("Expected a DerivationPathError"); + } + assert.equal(error.path, errorPath); + assert.equal( + (error as HardhatLedgerDerivationPathError).message, + `Could not find a valid derivation path for ${accounts[1]}. Paths from m/44'/60'/0'/0/0 to ${errorPath} were searched.` + ); + } + }); + }); + + describe("events", () => { + let emitSpy: sinon.SinonSpy; + + beforeEach(() => { + emitSpy = sinon.spy(provider, "emit"); + }); + + describe("confirmation", () => { + it("should emit the confirmation_start event when a request for signing is made", async () => { + ethInstanceStub.signPersonalMessage.returns(Promise.resolve(rsv)); + await provider.request({ + method: "personal_sign", + params: [dataToSign, account.address], + }); + + sinon.assert.calledWithExactly(emitSpy, "confirmation_start"); + }); + + it("should emit the confirmation_success event when a request for signing goes OK", async () => { + ethInstanceStub.signPersonalMessage.returns(Promise.resolve(rsv)); + await provider.request({ + method: "eth_sign", + params: [account.address, dataToSign], + }); + + sinon.assert.calledWithExactly(emitSpy, "confirmation_success"); + }); + + it("should emit the confirmation_failure event when a request for signing breaks", async () => { + ethInstanceStub.signEIP712Message.throws(new Error()); + ethInstanceStub.signEIP712HashedMessage.throws(new Error()); + try { + await provider.request({ + method: "eth_signTypedData_v4", + params: [account.address, typedMessage], + }); + } catch (error) {} + + sinon.assert.calledWithExactly(emitSpy, "confirmation_failure"); + }); + }); + + describe("derivation", () => { + async function requestSign() { + ethInstanceStub.signPersonalMessage.returns(Promise.resolve(rsv)); + await provider.request({ + method: "eth_sign", + params: [account.address, dataToSign], + }); + } + + it("should emit the derivation_start event when a request for signing is made", async () => { + await requestSign(); + sinon.assert.calledWithExactly(emitSpy, "derivation_start"); + }); + + it("should emit the derivation_progress event with the derived paths when a request for signing is made", async () => { + await requestSign(); + sinon.assert.calledWithExactly( + emitSpy, + "derivation_progress", + "m/44'/60'/0'/0/0", + 0 + ); + sinon.assert.calledWithExactly( + emitSpy, + "derivation_progress", + "m/44'/60'/1'/0/0", + 1 + ); + }); + + it("should emit the derivation_success event with the path when a request for signing is made and succeeds", async () => { + await requestSign(); + sinon.assert.calledWithExactly( + emitSpy, + "derivation_success", + "m/44'/60'/1'/0/0" + ); + }); + + it("should emit the derivation_failure event when a request for signing is made and breaks", async () => { + try { + ethInstanceStub.getAddress.throws(new Error()); + await requestSign(); + } catch (error) {} + sinon.assert.calledWithExactly(emitSpy, "derivation_failure"); + }); + + it("should emit the derivation_failure event when a request for signing is made and can't find a valid path", async () => { + try { + ethInstanceStub.getAddress.callsFake(async () => ({ + address: "0x0", + publicKey: "0x0", + })); + await requestSign(); + } catch (error) {} + sinon.assert.calledWithExactly(emitSpy, "derivation_failure"); + }); + }); + + describe("eth_accounts", () => { + beforeEach(() => { + // eth_accounts will be called to merge the accounts + sinon.stub(mockedProvider, "request").returns(Promise.resolve([])); + }); + + it("should not emit a connection or derivation event with eth_accounts", async () => { + await provider.request({ method: "eth_accounts" }); + sinon.assert.notCalled(emitSpy); + }); + }); + }); + }); +}); diff --git a/packages/hardhat-ledger/tsconfig.json b/packages/hardhat-ledger/tsconfig.json new file mode 100644 index 0000000000..f3ad7b97c6 --- /dev/null +++ b/packages/hardhat-ledger/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../config/typescript/tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "composite": true + }, + "exclude": ["./dist", "./node_modules", "./test/**/hardhat.config.ts"], + "references": [ + { + "path": "../hardhat-core/src" + } + ] +} diff --git a/packages/hardhat-network-helpers/.eslintrc.js b/packages/hardhat-network-helpers/.eslintrc.js index 889740f226..c6de07705a 100644 --- a/packages/hardhat-network-helpers/.eslintrc.js +++ b/packages/hardhat-network-helpers/.eslintrc.js @@ -1,7 +1,24 @@ +const { + slowImportsCommonIgnoredModules, +} = require("../../config/eslint/constants"); + module.exports = { extends: [`${__dirname}/../../config/eslint/eslintrc.js`], parserOptions: { project: `${__dirname}/tsconfig.json`, sourceType: "module", }, + overrides: [ + { + files: ["src/index.ts"], + rules: { + "@nomicfoundation/slow-imports/no-top-level-external-import": [ + "error", + { + ignoreModules: [...slowImportsCommonIgnoredModules], + }, + ], + }, + }, + ], }; diff --git a/packages/hardhat-network-helpers/.gitignore b/packages/hardhat-network-helpers/.gitignore index 80110bdc12..8707b8ac84 100644 --- a/packages/hardhat-network-helpers/.gitignore +++ b/packages/hardhat-network-helpers/.gitignore @@ -21,10 +21,6 @@ # Logs logs *.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json @@ -63,21 +59,15 @@ jspm_packages/ # TypeScript v1 declaration files typings/ -# Optional npm cache directory -.npm - # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history -# Output of 'npm pack' +# Output of 'pnpm pack' *.tgz -# Yarn Integrity file -.yarn-integrity - # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/packages/hardhat-network-helpers/.prettierignore b/packages/hardhat-network-helpers/.prettierignore index c66ddcfc8a..2ef4541cbc 100644 --- a/packages/hardhat-network-helpers/.prettierignore +++ b/packages/hardhat-network-helpers/.prettierignore @@ -10,3 +10,4 @@ /test/fixture-projects/**/artifacts /test/fixture-projects/**/cache CHANGELOG.md +!.eslintrc.js diff --git a/packages/hardhat-network-helpers/CHANGELOG.md b/packages/hardhat-network-helpers/CHANGELOG.md index 6c554ac9e1..b9a81d7d8e 100644 --- a/packages/hardhat-network-helpers/CHANGELOG.md +++ b/packages/hardhat-network-helpers/CHANGELOG.md @@ -1,5 +1,29 @@ # @nomicfoundation/hardhat-network-helpers +## 1.0.12 + +### Patch Changes + +- 8fa15e7: Add support for ZKsync's development mode + +## 1.0.11 + +### Patch Changes + +- 8be0c2c: Improve an error message and add a utility to clear all the existing snaphosts. + +## 1.0.10 + +### Patch Changes + +- 43d75470c: Added support for using network helpers on anvil network (thanks @tmigone!) + +## 1.0.9 + +### Patch Changes + +- 9715d4195: Added support for receiving Date instances in `increaseTo` network helper (thanks @Saty248) + ## 1.0.8 ### Patch Changes diff --git a/packages/hardhat-network-helpers/LICENSE b/packages/hardhat-network-helpers/LICENSE index 3b8858c555..3b7e8c7eab 100644 --- a/packages/hardhat-network-helpers/LICENSE +++ b/packages/hardhat-network-helpers/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Nomic Labs LLC +Copyright (c) 2023 Nomic Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/packages/hardhat-network-helpers/package.json b/packages/hardhat-network-helpers/package.json index 18d28fe319..513f5c25a5 100644 --- a/packages/hardhat-network-helpers/package.json +++ b/packages/hardhat-network-helpers/package.json @@ -1,6 +1,6 @@ { "name": "@nomicfoundation/hardhat-network-helpers", - "version": "1.0.8", + "version": "1.0.12", "description": "Hardhat utils for testing", "homepage": "https://github.com/nomicfoundation/hardhat/tree/main/packages/hardhat-network-helpers", "repository": "github:nomicfoundation/hardhat", @@ -15,13 +15,14 @@ "testing" ], "scripts": { - "lint": "yarn prettier --check && yarn eslint", - "lint:fix": "yarn prettier --write && yarn eslint --fix", + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", "prettier": "prettier \"**/*.{js,md,json}\"", + "pretest": "cd ../.. && pnpm build", "test": "mocha --recursive \"test/**/*.ts\" --exit", "build": "tsc --build .", - "prepublishOnly": "yarn build", + "prepublishOnly": "pnpm build", "clean": "rimraf dist internal types *.{d.ts,js}{,.map} build-test tsconfig.tsbuildinfo" }, "files": [ @@ -40,27 +41,30 @@ "ethereumjs-util": "^7.1.4" }, "devDependencies": { + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", "@types/chai": "^4.2.0", + "@types/chai-as-promised": "^7.1.3", "@types/mocha": ">=9.1.0", - "@types/node": "^14.0.0", - "@typescript-eslint/eslint-plugin": "5.53.0", - "@typescript-eslint/parser": "5.53.0", + "@types/node": "^18.0.0", + "@typescript-eslint/eslint-plugin": "5.61.0", + "@typescript-eslint/parser": "5.61.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", - "eslint": "^7.29.0", + "eslint": "^8.44.0", "eslint-config-prettier": "8.3.0", - "eslint-plugin-import": "2.24.1", - "eslint-plugin-no-only-tests": "3.0.0", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-mocha": "10.4.1", "eslint-plugin-prettier": "3.4.0", - "ethers": "^5.0.0", - "hardhat": "^2.9.5", + "ethers-v5": "npm:ethers@5", + "hardhat": "workspace:^2.9.5", "mocha": "^10.0.0", "prettier": "2.4.1", "rimraf": "^3.0.2", "ts-node": "^10.8.0", - "typescript": "~4.7.4" + "typescript": "~5.0.0" }, "peerDependencies": { - "hardhat": "^2.9.5" + "hardhat": "workspace:^2.9.5" } } diff --git a/packages/hardhat-network-helpers/src/errors.ts b/packages/hardhat-network-helpers/src/errors.ts index 2a7214ca69..3746ee0aa0 100644 --- a/packages/hardhat-network-helpers/src/errors.ts +++ b/packages/hardhat-network-helpers/src/errors.ts @@ -17,7 +17,7 @@ export class FixtureSnapshotError extends CustomError { super( `There was an error reverting the snapshot of the fixture. -This might be caused by using nested loadFixture calls in a test, for example by using multiple beforeEach calls. This is not supported yet.`, +This might be caused by using hardhat_reset and loadFixture calls in a testcase.`, parent ); } diff --git a/packages/hardhat-network-helpers/src/helpers/reset.ts b/packages/hardhat-network-helpers/src/helpers/reset.ts index ad1fc5cd09..70abd2aafa 100644 --- a/packages/hardhat-network-helpers/src/helpers/reset.ts +++ b/packages/hardhat-network-helpers/src/helpers/reset.ts @@ -1,4 +1,6 @@ import type { NumberLike } from "../types"; +import { clearSnapshots } from "../loadFixture"; + import { getHardhatProvider, toNumber } from "../utils"; export async function reset( @@ -6,7 +8,7 @@ export async function reset( blockNumber?: NumberLike ): Promise { const provider = await getHardhatProvider(); - + await clearSnapshots(); if (url === undefined) { await provider.request({ method: "hardhat_reset", diff --git a/packages/hardhat-network-helpers/src/helpers/time/increaseTo.ts b/packages/hardhat-network-helpers/src/helpers/time/increaseTo.ts index e86f15090d..3dc166a5a3 100644 --- a/packages/hardhat-network-helpers/src/helpers/time/increaseTo.ts +++ b/packages/hardhat-network-helpers/src/helpers/time/increaseTo.ts @@ -2,16 +2,19 @@ import type { NumberLike } from "../../types"; import { getHardhatProvider, toRpcQuantity, toBigInt } from "../../utils"; import { mine } from "../mine"; +import { millis } from "./duration"; /** * Mines a new block whose timestamp is `timestamp` * - * @param timestamp Must be bigger than the latest block's timestamp + * @param timestamp Can be `Date` or Epoch seconds. Must be bigger than the latest block's timestamp */ -export async function increaseTo(timestamp: NumberLike): Promise { +export async function increaseTo(timestamp: NumberLike | Date): Promise { const provider = await getHardhatProvider(); - const normalizedTimestamp = toBigInt(timestamp); + const normalizedTimestamp = toBigInt( + timestamp instanceof Date ? millis(timestamp.valueOf()) : timestamp + ); await provider.request({ method: "evm_setNextBlockTimestamp", diff --git a/packages/hardhat-network-helpers/src/loadFixture.ts b/packages/hardhat-network-helpers/src/loadFixture.ts index 76d53c3a74..0a1101abbb 100644 --- a/packages/hardhat-network-helpers/src/loadFixture.ts +++ b/packages/hardhat-network-helpers/src/loadFixture.ts @@ -68,3 +68,10 @@ export async function loadFixture(fixture: Fixture): Promise { return data; } } + +/** + * Clears every existing snapshot. + */ +export async function clearSnapshots() { + snapshots = []; +} diff --git a/packages/hardhat-network-helpers/src/utils.ts b/packages/hardhat-network-helpers/src/utils.ts index 53d6b2305b..af8f013390 100644 --- a/packages/hardhat-network-helpers/src/utils.ts +++ b/packages/hardhat-network-helpers/src/utils.ts @@ -5,31 +5,32 @@ import type { NumberLike } from "./types"; import { HardhatNetworkHelpersError, OnlyHardhatNetworkError } from "./errors"; -let cachedIsHardhatNetwork: boolean; -async function checkIfHardhatNetwork( +let cachedIsDevelopmentNetwork: boolean; +async function checkIfDevelopmentNetwork( provider: EIP1193Provider, networkName: string ): Promise { let version: string | undefined; - if (cachedIsHardhatNetwork === undefined) { + if (cachedIsDevelopmentNetwork === undefined) { try { version = (await provider.request({ method: "web3_clientVersion", })) as string; - cachedIsHardhatNetwork = version - .toLowerCase() - .startsWith("hardhatnetwork"); + cachedIsDevelopmentNetwork = + version.toLowerCase().startsWith("hardhatnetwork") || + version.toLowerCase().startsWith("zksync") || + version.toLowerCase().startsWith("anvil"); } catch (e) { - cachedIsHardhatNetwork = false; + cachedIsDevelopmentNetwork = false; } } - if (!cachedIsHardhatNetwork) { + if (!cachedIsDevelopmentNetwork) { throw new OnlyHardhatNetworkError(networkName, version); } - return cachedIsHardhatNetwork; + return cachedIsDevelopmentNetwork; } export async function getHardhatProvider(): Promise { @@ -37,7 +38,7 @@ export async function getHardhatProvider(): Promise { const provider = hre.network.provider; - await checkIfHardhatNetwork(provider, hre.network.name); + await checkIfDevelopmentNetwork(provider, hre.network.name); return hre.network.provider; } diff --git a/packages/hardhat-network-helpers/test/helpers/getStorageAt.ts b/packages/hardhat-network-helpers/test/helpers/getStorageAt.ts index 46de0a1624..06236298dc 100644 --- a/packages/hardhat-network-helpers/test/helpers/getStorageAt.ts +++ b/packages/hardhat-network-helpers/test/helpers/getStorageAt.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; import { BN } from "ethereumjs-util"; -import { ethers } from "ethers"; +import { ethers } from "ethers-v5"; import * as hh from "../../src"; import { BlockTag, NumberLike } from "../../src/types"; diff --git a/packages/hardhat-network-helpers/test/helpers/mine.ts b/packages/hardhat-network-helpers/test/helpers/mine.ts index 97945826d1..8cf7674389 100644 --- a/packages/hardhat-network-helpers/test/helpers/mine.ts +++ b/packages/hardhat-network-helpers/test/helpers/mine.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; import { BN } from "ethereumjs-util"; -import { ethers } from "ethers"; +import { ethers } from "ethers-v5"; import * as hh from "../../src"; import { NumberLike } from "../../src/types"; diff --git a/packages/hardhat-network-helpers/test/helpers/mineUpTo.ts b/packages/hardhat-network-helpers/test/helpers/mineUpTo.ts index bce852065a..3010630e27 100644 --- a/packages/hardhat-network-helpers/test/helpers/mineUpTo.ts +++ b/packages/hardhat-network-helpers/test/helpers/mineUpTo.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; import { BN } from "ethereumjs-util"; -import { ethers } from "ethers"; +import { ethers } from "ethers-v5"; import * as hh from "../../src"; import { useEnvironment } from "../test-utils"; diff --git a/packages/hardhat-network-helpers/test/helpers/reset.ts b/packages/hardhat-network-helpers/test/helpers/reset.ts index 8a8845aea7..c312eea953 100644 --- a/packages/hardhat-network-helpers/test/helpers/reset.ts +++ b/packages/hardhat-network-helpers/test/helpers/reset.ts @@ -1,9 +1,7 @@ import { assert } from "chai"; - import * as hh from "../../src"; import { INFURA_URL } from "../setup"; import { useEnvironment } from "../test-utils"; - describe("resetWithoutFork", function () { useEnvironment("simple"); @@ -26,12 +24,12 @@ describe("resetWithoutFork", function () { const mainnetBlockNumber = await hh.time.latestBlock(); - // fork goerli - await hh.reset(INFURA_URL.replace("mainnet", "goerli")); + // fork sepolia + await hh.reset(INFURA_URL.replace("mainnet", "sepolia")); - const goerliBlockNumber = await hh.time.latestBlock(); + const sepoliaBlockNumber = await hh.time.latestBlock(); - const blockNumberDelta = Math.abs(mainnetBlockNumber - goerliBlockNumber); + const blockNumberDelta = Math.abs(mainnetBlockNumber - sepoliaBlockNumber); // check that there is a significative difference between the latest // block numbers of each chain @@ -56,3 +54,13 @@ describe("resetWithoutFork", function () { assert.equal(olderMainnetBlockNumber, mainnetBlockNumber - 1000); }); }); + +describe("should clear snapshot upon reset", function () { + useEnvironment("simple"); + it("checks if the snapshot is cleared upon hardhat_reset", async function () { + const snapshotBeforeReset = await hh.takeSnapshot(); + await hh.reset(); + const snapshotAfterReset = await hh.takeSnapshot(); + assert.equal(snapshotBeforeReset.snapshotId, snapshotAfterReset.snapshotId); + }); +}); diff --git a/packages/hardhat-network-helpers/test/helpers/setBalance.ts b/packages/hardhat-network-helpers/test/helpers/setBalance.ts index 040a26a770..1af4b3c88d 100644 --- a/packages/hardhat-network-helpers/test/helpers/setBalance.ts +++ b/packages/hardhat-network-helpers/test/helpers/setBalance.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; import { BN } from "ethereumjs-util"; -import { ethers } from "ethers"; +import { ethers } from "ethers-v5"; import * as hh from "../../src"; import { NumberLike } from "../../src/types"; diff --git a/packages/hardhat-network-helpers/test/helpers/setBlockGasLimit.ts b/packages/hardhat-network-helpers/test/helpers/setBlockGasLimit.ts index 5604bf0f48..0a717d924c 100644 --- a/packages/hardhat-network-helpers/test/helpers/setBlockGasLimit.ts +++ b/packages/hardhat-network-helpers/test/helpers/setBlockGasLimit.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; import { BN } from "ethereumjs-util"; -import { ethers } from "ethers"; +import { ethers } from "ethers-v5"; import * as hh from "../../src"; import { NumberLike } from "../../src/types"; diff --git a/packages/hardhat-network-helpers/test/helpers/setNextBlockBaseFeePerGas.ts b/packages/hardhat-network-helpers/test/helpers/setNextBlockBaseFeePerGas.ts index 85b078a25a..e9404cb891 100644 --- a/packages/hardhat-network-helpers/test/helpers/setNextBlockBaseFeePerGas.ts +++ b/packages/hardhat-network-helpers/test/helpers/setNextBlockBaseFeePerGas.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; import { BN } from "ethereumjs-util"; -import { ethers } from "ethers"; +import { ethers } from "ethers-v5"; import * as hh from "../../src"; import { NumberLike } from "../../src/types"; diff --git a/packages/hardhat-network-helpers/test/helpers/setNonce.ts b/packages/hardhat-network-helpers/test/helpers/setNonce.ts index b1f5ea7a45..2e619a7237 100644 --- a/packages/hardhat-network-helpers/test/helpers/setNonce.ts +++ b/packages/hardhat-network-helpers/test/helpers/setNonce.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; import { BN } from "ethereumjs-util"; -import { ethers } from "ethers"; +import { ethers } from "ethers-v5"; import * as hh from "../../src"; import { NumberLike } from "../../src/types"; diff --git a/packages/hardhat-network-helpers/test/helpers/setPrevRandao.ts b/packages/hardhat-network-helpers/test/helpers/setPrevRandao.ts index a42db5b6ce..b1dbe96060 100644 --- a/packages/hardhat-network-helpers/test/helpers/setPrevRandao.ts +++ b/packages/hardhat-network-helpers/test/helpers/setPrevRandao.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; import { BN } from "ethereumjs-util"; -import { ethers } from "ethers"; +import { ethers } from "ethers-v5"; import * as hh from "../../src"; import { NumberLike } from "../../src/types"; @@ -18,7 +18,7 @@ describe("setPrevRandao", function () { return BigInt(block.mixHash); }; - it("should allow setting the next block's prevrandao", async function () { + it("should allow setting the next block's prevRandao", async function () { await hh.setPrevRandao(12345); await hh.mine(); diff --git a/packages/hardhat-network-helpers/test/helpers/setStorageAt.ts b/packages/hardhat-network-helpers/test/helpers/setStorageAt.ts index 18aac66834..62de311629 100644 --- a/packages/hardhat-network-helpers/test/helpers/setStorageAt.ts +++ b/packages/hardhat-network-helpers/test/helpers/setStorageAt.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; import { BN } from "ethereumjs-util"; -import { ethers } from "ethers"; +import { ethers } from "ethers-v5"; import * as hh from "../../src"; import { toPaddedRpcQuantity } from "../../src/utils"; diff --git a/packages/hardhat-network-helpers/test/helpers/time/advanceBlock.ts b/packages/hardhat-network-helpers/test/helpers/time/advanceBlock.ts index 352462d271..ea7ffebbc6 100644 --- a/packages/hardhat-network-helpers/test/helpers/time/advanceBlock.ts +++ b/packages/hardhat-network-helpers/test/helpers/time/advanceBlock.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; import { BN } from "ethereumjs-util"; -import { ethers } from "ethers"; +import { ethers } from "ethers-v5"; import * as hh from "../../../src"; import { NumberLike } from "../../../src/types"; diff --git a/packages/hardhat-network-helpers/test/helpers/time/advanceBlockTo.ts b/packages/hardhat-network-helpers/test/helpers/time/advanceBlockTo.ts index 44c4031bee..6d6d6315e4 100644 --- a/packages/hardhat-network-helpers/test/helpers/time/advanceBlockTo.ts +++ b/packages/hardhat-network-helpers/test/helpers/time/advanceBlockTo.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; import { BN } from "ethereumjs-util"; -import { ethers } from "ethers"; +import { ethers } from "ethers-v5"; import * as hh from "../../../src"; import { useEnvironment } from "../../test-utils"; diff --git a/packages/hardhat-network-helpers/test/helpers/time/increase.ts b/packages/hardhat-network-helpers/test/helpers/time/increase.ts index 719fa169a9..ce14bc809c 100644 --- a/packages/hardhat-network-helpers/test/helpers/time/increase.ts +++ b/packages/hardhat-network-helpers/test/helpers/time/increase.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; import { BN } from "ethereumjs-util"; -import { ethers } from "ethers"; +import { ethers } from "ethers-v5"; import * as hh from "../../../src"; import { NumberLike } from "../../../src/types"; diff --git a/packages/hardhat-network-helpers/test/helpers/time/increaseTo.ts b/packages/hardhat-network-helpers/test/helpers/time/increaseTo.ts index 9e4301cd79..b57c452149 100644 --- a/packages/hardhat-network-helpers/test/helpers/time/increaseTo.ts +++ b/packages/hardhat-network-helpers/test/helpers/time/increaseTo.ts @@ -1,6 +1,6 @@ import { assert } from "chai"; import { BN } from "ethereumjs-util"; -import { ethers } from "ethers"; +import { ethers } from "ethers-v5"; import * as hh from "../../../src"; import { useEnvironment } from "../../test-utils"; @@ -91,6 +91,19 @@ describe("time#increaseTo", function () { assert.equal(newTimestamp, endTimestamp); assert(endTimestamp - initialTimestamp === 3600); }); + + it(`should accept an argument of type [Date]`, async function () { + const initialTimestamp = await hh.time.latest(); + + const newTimestamp = initialTimestamp + 3600; + // multiply by 1000 because Date accepts Epoch millis + await hh.time.increaseTo(new Date(newTimestamp * 1000)); + + const endTimestamp = await hh.time.latest(); + + assert.equal(newTimestamp, endTimestamp); + assert(endTimestamp - initialTimestamp === 3600); + }); }); }); diff --git a/packages/hardhat-shorthand/.gitignore b/packages/hardhat-shorthand/.gitignore index c00d7e7296..4aca21f18d 100644 --- a/packages/hardhat-shorthand/.gitignore +++ b/packages/hardhat-shorthand/.gitignore @@ -15,10 +15,6 @@ # Logs logs *.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json @@ -57,21 +53,15 @@ jspm_packages/ # TypeScript v1 declaration files typings/ -# Optional npm cache directory -.npm - # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history -# Output of 'npm pack' +# Output of 'pnpm pack' *.tgz -# Yarn Integrity file -.yarn-integrity - # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/packages/hardhat-shorthand/LICENSE b/packages/hardhat-shorthand/LICENSE index 3b8858c555..3b7e8c7eab 100644 --- a/packages/hardhat-shorthand/LICENSE +++ b/packages/hardhat-shorthand/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Nomic Labs LLC +Copyright (c) 2023 Nomic Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/packages/hardhat-shorthand/package.json b/packages/hardhat-shorthand/package.json index 4bd3900b7e..881cab72d3 100644 --- a/packages/hardhat-shorthand/package.json +++ b/packages/hardhat-shorthand/package.json @@ -7,8 +7,8 @@ "author": "Nomic Labs LLC", "license": "MIT", "bin": { - "hh": "dist/src/index.js", - "hardhat-completion": "dist/src/completion.js" + "hardhat-completion": "dist/src/completion.js", + "hh": "dist/src/index.js" }, "keywords": [ "ethereum", @@ -17,13 +17,14 @@ "cli" ], "scripts": { - "lint": "yarn prettier --check && yarn eslint", - "lint:fix": "yarn prettier --write && yarn eslint --fix", + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", "prettier": "prettier \"**/*.{js,md,json}\"", + "pretest": "cd ../.. && pnpm build", "test": "mocha --recursive \"test/**/*.ts\" --exit", "build": "tsc --build .", - "prepublishOnly": "yarn build", + "prepublishOnly": "pnpm build", "clean": "rimraf dist" }, "files": [ @@ -33,24 +34,28 @@ "README.md" ], "devDependencies": { + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", "@types/chai": "^4.2.0", + "@types/debug": "^4.1.4", "@types/fs-extra": "^5.1.0", "@types/mocha": ">=9.1.0", - "@types/node": "^14.0.0", - "@typescript-eslint/eslint-plugin": "5.53.0", - "@typescript-eslint/parser": "5.53.0", + "@types/node": "^18.0.0", + "@types/semver": "^6.0.2", + "@typescript-eslint/eslint-plugin": "5.61.0", + "@typescript-eslint/parser": "5.61.0", "chai": "^4.2.0", - "eslint": "^7.29.0", + "eslint": "^8.44.0", "eslint-config-prettier": "8.3.0", - "eslint-plugin-import": "2.24.1", - "eslint-plugin-no-only-tests": "3.0.0", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-mocha": "10.4.1", "eslint-plugin-prettier": "3.4.0", - "hardhat": "^2.0.0", + "hardhat": "workspace:^2.0.0", "mocha": "^10.0.0", "prettier": "2.4.1", "rimraf": "^3.0.2", "ts-node": "^10.8.0", - "typescript": "~4.7.4" + "typescript": "~5.0.0" }, "dependencies": { "@fvictorio/tabtab": "^0.0.3", diff --git a/packages/hardhat-solhint/.eslintrc.js b/packages/hardhat-solhint/.eslintrc.js index 889740f226..c6de07705a 100644 --- a/packages/hardhat-solhint/.eslintrc.js +++ b/packages/hardhat-solhint/.eslintrc.js @@ -1,7 +1,24 @@ +const { + slowImportsCommonIgnoredModules, +} = require("../../config/eslint/constants"); + module.exports = { extends: [`${__dirname}/../../config/eslint/eslintrc.js`], parserOptions: { project: `${__dirname}/tsconfig.json`, sourceType: "module", }, + overrides: [ + { + files: ["src/index.ts"], + rules: { + "@nomicfoundation/slow-imports/no-top-level-external-import": [ + "error", + { + ignoreModules: [...slowImportsCommonIgnoredModules], + }, + ], + }, + }, + ], }; diff --git a/packages/hardhat-solhint/.gitignore b/packages/hardhat-solhint/.gitignore index c00d7e7296..4aca21f18d 100644 --- a/packages/hardhat-solhint/.gitignore +++ b/packages/hardhat-solhint/.gitignore @@ -15,10 +15,6 @@ # Logs logs *.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json @@ -57,21 +53,15 @@ jspm_packages/ # TypeScript v1 declaration files typings/ -# Optional npm cache directory -.npm - # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history -# Output of 'npm pack' +# Output of 'pnpm pack' *.tgz -# Yarn Integrity file -.yarn-integrity - # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/packages/hardhat-solhint/CHANGELOG.md b/packages/hardhat-solhint/CHANGELOG.md index 97e3f64503..a006016888 100644 --- a/packages/hardhat-solhint/CHANGELOG.md +++ b/packages/hardhat-solhint/CHANGELOG.md @@ -1,5 +1,24 @@ # @nomiclabs/hardhat-solhint +## 4.0.1 + +### Patch Changes + +- efa905d: Fix for corrupted Hardhat peer dependency version from pnpm. + +## 4.0.0 + +### Major Changes + +- cc79bd7: Ensured the check task exits with exit code 1 when solhint raises any errors; this is a breaking change since the check task would previously always exit with exit code 0 +- 9cae5e7: Updated solhint dependency to [v5.0.2](https://github.com/protofire/solhint/releases/tag/v5.0.2) + +## 3.1.0 + +### Minor Changes + +- bcb688f: Added support for `.solhintignore` files (thanks @yhuard!) + ## 3.0.1 ### Patch Changes diff --git a/packages/hardhat-solhint/LICENSE b/packages/hardhat-solhint/LICENSE index 3b8858c555..3b7e8c7eab 100644 --- a/packages/hardhat-solhint/LICENSE +++ b/packages/hardhat-solhint/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Nomic Labs LLC +Copyright (c) 2023 Nomic Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/packages/hardhat-solhint/package.json b/packages/hardhat-solhint/package.json index eee048881f..fa79057cd7 100644 --- a/packages/hardhat-solhint/package.json +++ b/packages/hardhat-solhint/package.json @@ -1,6 +1,6 @@ { "name": "@nomiclabs/hardhat-solhint", - "version": "3.0.1", + "version": "4.0.1", "description": "Hardhat plugin for solhint", "repository": "github:nomiclabs/hardhat", "homepage": "https://github.com/nomiclabs/hardhat/tree/main/packages/hardhat-solhint", @@ -18,13 +18,14 @@ "linter" ], "scripts": { - "lint": "yarn prettier --check && yarn eslint", - "lint:fix": "yarn prettier --write && yarn eslint --fix", + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", "prettier": "prettier \"**/*.{js,md,json}\"", + "pretest": "cd ../.. && pnpm build", "test": "mocha --recursive \"test/**/*.ts\" --exit", "build": "tsc --build .", - "prepublishOnly": "yarn build", + "prepublishOnly": "pnpm build", "clean": "rimraf dist" }, "files": [ @@ -34,31 +35,34 @@ "README.md" ], "dependencies": { - "solhint": "^3.4.0" + "solhint": "^5.0.2" }, "devDependencies": { + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", "@types/chai": "^4.2.0", "@types/fs-extra": "^5.1.0", "@types/mocha": ">=9.1.0", - "@types/node": "^14.0.0", - "@typescript-eslint/eslint-plugin": "5.53.0", - "@typescript-eslint/parser": "5.53.0", + "@types/node": "^18.0.0", + "@types/sinon": "^9.0.8", + "@typescript-eslint/eslint-plugin": "5.61.0", + "@typescript-eslint/parser": "5.61.0", "chai": "^4.2.0", - "eslint": "^7.29.0", + "eslint": "^8.44.0", "eslint-config-prettier": "8.3.0", - "eslint-plugin-import": "2.24.1", - "eslint-plugin-no-only-tests": "3.0.0", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-mocha": "10.4.1", "eslint-plugin-prettier": "3.4.0", "fs-extra": "^7.0.1", - "hardhat": "^2.0.0", + "hardhat": "workspace:^2.0.0", "mocha": "^10.0.0", "prettier": "2.4.1", "rimraf": "^3.0.2", "sinon": "^9.0.0", "ts-node": "^10.8.0", - "typescript": "~4.7.4" + "typescript": "~5.0.0" }, "peerDependencies": { - "hardhat": "^2.0.0" + "hardhat": "workspace:^2.0.0" } } diff --git a/packages/hardhat-solhint/src/index.ts b/packages/hardhat-solhint/src/index.ts index fabe552bd4..5b5c6a514e 100644 --- a/packages/hardhat-solhint/src/index.ts +++ b/packages/hardhat-solhint/src/index.ts @@ -1,7 +1,7 @@ import * as fs from "fs"; import { subtask, task } from "hardhat/config"; import { NomicLabsHardhatPluginError } from "hardhat/internal/core/errors"; -import { join } from "path"; +import { join, relative } from "path"; function getDefaultConfig() { return { @@ -43,6 +43,19 @@ async function hasConfigFile(rootDirectory: string) { return false; } +function readIgnore(rootDirectory: string) { + try { + return fs + .readFileSync(join(rootDirectory, ".solhintignore")) + .toString() + .split("\n") + .map((i) => i.trim()) + .filter(Boolean); + } catch (e) { + return []; + } +} + async function getSolhintConfig(rootDirectory: string) { let solhintConfig; const { @@ -73,6 +86,14 @@ async function getSolhintConfig(rootDirectory: string) { ); } + const configExcludeFiles = Array.isArray(solhintConfig.excludedFiles) + ? solhintConfig.excludedFiles + : []; + solhintConfig.excludedFiles = [ + ...configExcludeFiles, + ...readIgnore(rootDirectory), + ]; + return solhintConfig; } @@ -83,10 +104,19 @@ function printReport(reports: any) { subtask("hardhat-solhint:run-solhint", async (_, { config }) => { const { processPath } = require("solhint/lib/index"); - return processPath( - join(config.paths.sources, "**", "*.sol").replace(/\\/g, "/"), - await getSolhintConfig(config.paths.root) - ); + + // Create a glob pattern that matches all the .sol files within the sources folder + const solFilesGlob = join(config.paths.sources, "**", "*.sol"); + + // Make glob pattern relative to Hardhat's root directory + // See https://github.com/kaelzhang/node-ignore/tree/5.2.4#1-pathname-should-be-a-pathrelatived-pathname + const relativeGlob = relative(config.paths.root, solFilesGlob); + + // Fix for Windows users: replace back-slashes with forward-slashes + // See https://github.com/isaacs/node-glob/tree/v8.0.3#windows + const normalizedGlob = relativeGlob.replace(/\\/g, "/"); + + return processPath(normalizedGlob, await getSolhintConfig(config.paths.root)); }); task("check", async (_, { run }, runSuper) => { @@ -97,4 +127,16 @@ task("check", async (_, { run }, runSuper) => { const reports = await run("hardhat-solhint:run-solhint"); printReport(reports); + + const errorsCount = reports.reduce( + (acc: number, i: { errorCount: number }) => { + return acc + i.errorCount; + }, + 0 + ); + + if (errorsCount > 0) { + process.exitCode = 1; + return; + } }); diff --git a/packages/hardhat-solhint/test/fixture-projects/no-errors-project/.solhint.json b/packages/hardhat-solhint/test/fixture-projects/no-errors-project/.solhint.json new file mode 100644 index 0000000000..3b8ee84ad4 --- /dev/null +++ b/packages/hardhat-solhint/test/fixture-projects/no-errors-project/.solhint.json @@ -0,0 +1,3 @@ +{ + "extends": "solhint:all" +} diff --git a/packages/hardhat-solhint/test/fixture-projects/no-errors-project/contracts/Greeter.sol b/packages/hardhat-solhint/test/fixture-projects/no-errors-project/contracts/Greeter.sol new file mode 100644 index 0000000000..38d74f1e21 --- /dev/null +++ b/packages/hardhat-solhint/test/fixture-projects/no-errors-project/contracts/Greeter.sol @@ -0,0 +1,15 @@ +pragma solidity ^0.8.28; + + +contract Greeter { + + string greeting; + constructor(string memory _greeting) public { + greeting = _greeting; + } + + function greet() public view returns (string memory) { + return greeting; + } + +} diff --git a/packages/hardhat-solhint/test/fixture-projects/no-errors-project/hardhat.config.js b/packages/hardhat-solhint/test/fixture-projects/no-errors-project/hardhat.config.js new file mode 100644 index 0000000000..d851e726c8 --- /dev/null +++ b/packages/hardhat-solhint/test/fixture-projects/no-errors-project/hardhat.config.js @@ -0,0 +1,5 @@ +require("../../../src/index"); + +module.exports = { + solidity: "0.5.15", +}; diff --git a/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/.solhint.json b/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/.solhint.json new file mode 100644 index 0000000000..d5ee2d6700 --- /dev/null +++ b/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/.solhint.json @@ -0,0 +1,4 @@ +{ + "extends": "solhint:all", + "excludedFiles": ["contracts/Greeter3.sol"] +} diff --git a/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/.solhintignore b/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/.solhintignore new file mode 100644 index 0000000000..847f2d4893 --- /dev/null +++ b/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/.solhintignore @@ -0,0 +1 @@ +contracts/Greeter2.sol diff --git a/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/contracts/Greeter.sol b/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/contracts/Greeter.sol new file mode 100644 index 0000000000..7b96d96c80 --- /dev/null +++ b/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/contracts/Greeter.sol @@ -0,0 +1,17 @@ +pragma solidity ^0.5.1; + + +contract Greeter { + + string greeting; + string bad; + constructor(string memory _greeting) public { + greeting = _greeting; + bad = "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad"; + } + + function greet() public view returns (string memory) { + return greeting; + } + +} diff --git a/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/contracts/Greeter2.sol b/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/contracts/Greeter2.sol new file mode 100644 index 0000000000..3fbd23afe6 --- /dev/null +++ b/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/contracts/Greeter2.sol @@ -0,0 +1,15 @@ +pragma solidity ^0.5.1; + +contract Greeter2 { + string greeting; + string bad; + + constructor(string memory _greeting) public { + greeting = _greeting; + bad = "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad"; + } + + function greet() public view returns (string memory) { + return greeting; + } +} diff --git a/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/contracts/Greeter3.sol b/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/contracts/Greeter3.sol new file mode 100644 index 0000000000..8d82db2ef0 --- /dev/null +++ b/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/contracts/Greeter3.sol @@ -0,0 +1,15 @@ +pragma solidity ^0.5.1; + +contract Greeter3 { + string greeting; + string bad; + + constructor(string memory _greeting) public { + greeting = _greeting; + bad = "baaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaad"; + } + + function greet() public view returns (string memory) { + return greeting; + } +} diff --git a/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/hardhat.config.js b/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/hardhat.config.js new file mode 100644 index 0000000000..d851e726c8 --- /dev/null +++ b/packages/hardhat-solhint/test/fixture-projects/solhintignore-project/hardhat.config.js @@ -0,0 +1,5 @@ +require("../../../src/index"); + +module.exports = { + solidity: "0.5.15", +}; diff --git a/packages/hardhat-solhint/test/tests.ts b/packages/hardhat-solhint/test/tests.ts index 690c0a00db..9247b33774 100644 --- a/packages/hardhat-solhint/test/tests.ts +++ b/packages/hardhat-solhint/test/tests.ts @@ -36,11 +36,50 @@ describe("Solhint plugin", function () { ); }); - it("should run the check task without throwing an error", async function () { + it("should run the check task and set the exit code to 1", async function () { const consoleLogStub = sinon.stub(console, "log"); await this.env.run("check"); assert.isTrue(consoleLogStub.calledOnce); + assert.strictEqual(process.exitCode, 1); consoleLogStub.restore(); + process.exitCode = undefined; + }); + }); + + describe("Project with no errors", function () { + useEnvironment("no-errors-project"); + + it("should run the check task and not set the exit code", async function () { + const consoleLogStub = sinon.stub(console, "log"); + await this.env.run("check"); + assert.isTrue(consoleLogStub.calledOnce); + assert.strictEqual(process.exitCode, undefined); + }); + }); + + describe("Project with .solhintignore file", function () { + useEnvironment("solhintignore-project"); + + it("should not return a report for the ignored files", async function () { + const reports = await this.env.run("hardhat-solhint:run-solhint"); + // Greeter.sol is not ignored, Solhint should return a report + assert.isTrue( + reports.some((report: any) => + report.file.includes("contracts/Greeter.sol") + ) + ); + // Greeter2.sol is ignored in the .solhintignore file, Solhint should not return a report + assert.isFalse( + reports.some((report: any) => + report.file.includes("contracts/Greeter2.sol") + ) + ); + // Greeter3.sol is ignored in the .solhint.json file, Solhint should not return a report + assert.isFalse( + reports.some((report: any) => + report.file.includes("contracts/Greeter2.sol") + ) + ); }); }); diff --git a/packages/hardhat-solpp/.eslintrc.js b/packages/hardhat-solpp/.eslintrc.js index 889740f226..c6de07705a 100644 --- a/packages/hardhat-solpp/.eslintrc.js +++ b/packages/hardhat-solpp/.eslintrc.js @@ -1,7 +1,24 @@ +const { + slowImportsCommonIgnoredModules, +} = require("../../config/eslint/constants"); + module.exports = { extends: [`${__dirname}/../../config/eslint/eslintrc.js`], parserOptions: { project: `${__dirname}/tsconfig.json`, sourceType: "module", }, + overrides: [ + { + files: ["src/index.ts"], + rules: { + "@nomicfoundation/slow-imports/no-top-level-external-import": [ + "error", + { + ignoreModules: [...slowImportsCommonIgnoredModules], + }, + ], + }, + }, + ], }; diff --git a/packages/hardhat-solpp/.gitignore b/packages/hardhat-solpp/.gitignore index c00d7e7296..4aca21f18d 100644 --- a/packages/hardhat-solpp/.gitignore +++ b/packages/hardhat-solpp/.gitignore @@ -15,10 +15,6 @@ # Logs logs *.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json @@ -57,21 +53,15 @@ jspm_packages/ # TypeScript v1 declaration files typings/ -# Optional npm cache directory -.npm - # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history -# Output of 'npm pack' +# Output of 'pnpm pack' *.tgz -# Yarn Integrity file -.yarn-integrity - # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/packages/hardhat-solpp/LICENSE b/packages/hardhat-solpp/LICENSE index 3b8858c555..3b7e8c7eab 100644 --- a/packages/hardhat-solpp/LICENSE +++ b/packages/hardhat-solpp/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Nomic Labs LLC +Copyright (c) 2023 Nomic Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/packages/hardhat-solpp/README.md b/packages/hardhat-solpp/README.md index 386490a54c..760e72d35f 100644 --- a/packages/hardhat-solpp/README.md +++ b/packages/hardhat-solpp/README.md @@ -38,7 +38,7 @@ Install it, run `npx hardhat compile` and solc will compile the solpp generated ## Configuration -This plugin can by configured by setting a `solpp` entry in `hardhat.config.js`. Its options are: +This plugin can be configured by setting a `solpp` entry in `hardhat.config.js`. Its options are: - `defs`: is an object where each property is the symbol's name and its value is the actual definition. Definitions can be numbers, string, expressions, lists, or functions. For more detail about symbols you can check [solpp README](https://github.com/merklejerk/solpp). - `cwd: string`: directory where the contracts are located, it will be used for flattening purposes, by default it will be the project's source directory. diff --git a/packages/hardhat-solpp/package.json b/packages/hardhat-solpp/package.json index 790862f71c..8e4049a43d 100644 --- a/packages/hardhat-solpp/package.json +++ b/packages/hardhat-solpp/package.json @@ -18,13 +18,14 @@ "solpp" ], "scripts": { - "lint": "yarn prettier --check && yarn eslint", - "lint:fix": "yarn prettier --write && yarn eslint --fix", + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", "prettier": "prettier \"**/*.{js,md,json}\"", + "pretest": "cd ../.. && pnpm build", "test": "mocha --recursive \"test/**/*.ts\" --exit", "build": "tsc --build .", - "prepublishOnly": "yarn build", + "prepublishOnly": "pnpm build", "clean": "rimraf dist" }, "files": [ @@ -38,26 +39,28 @@ "solpp": "^0.11.5" }, "devDependencies": { + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", "@types/chai": "^4.2.0", "@types/fs-extra": "^5.1.0", "@types/mocha": ">=9.1.0", - "@types/node": "^14.0.0", - "@typescript-eslint/eslint-plugin": "5.53.0", - "@typescript-eslint/parser": "5.53.0", + "@types/node": "^18.0.0", + "@typescript-eslint/eslint-plugin": "5.61.0", + "@typescript-eslint/parser": "5.61.0", "chai": "^4.2.0", - "eslint": "^7.29.0", + "eslint": "^8.44.0", "eslint-config-prettier": "8.3.0", - "eslint-plugin-import": "2.24.1", - "eslint-plugin-no-only-tests": "3.0.0", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-mocha": "10.4.1", "eslint-plugin-prettier": "3.4.0", - "hardhat": "^2.0.0", + "hardhat": "workspace:^2.0.0", "mocha": "^10.0.0", "prettier": "2.4.1", "rimraf": "^3.0.2", "ts-node": "^10.8.0", - "typescript": "~4.7.4" + "typescript": "~5.0.0" }, "peerDependencies": { - "hardhat": "^2.0.0" + "hardhat": "workspace:^2.0.0" } } diff --git a/packages/hardhat-solpp/test/fixture-projects/hardhat-project/contracts/B.sol b/packages/hardhat-solpp/test/fixture-projects/hardhat-project/contracts/B.sol index 0fddf74bc4..b8f8d01ed8 100644 --- a/packages/hardhat-solpp/test/fixture-projects/hardhat-project/contracts/B.sol +++ b/packages/hardhat-solpp/test/fixture-projects/hardhat-project/contracts/B.sol @@ -2,7 +2,7 @@ pragma solidity >=0.4.21 <0.6.0; contract B { function bar(uint256 x) pure returns (uint256) { - // Repeat code with a a for loop. + // Repeat code with a for loop. return x /* #for V in range(1,4) */+ $$(V+1)/* #done */; // -> return x + 1 + 2 + 3; } } diff --git a/packages/hardhat-solpp/test/tests.ts b/packages/hardhat-solpp/test/tests.ts index 02cce468da..5da69c1ee4 100644 --- a/packages/hardhat-solpp/test/tests.ts +++ b/packages/hardhat-solpp/test/tests.ts @@ -19,8 +19,8 @@ export async function expectErrorAsync( } } -describe("Solpp plugin", async function () { - describe("js-config-project", async function () { +describe("Solpp plugin", function () { + describe("js-config-project", function () { useEnvironment("js-config-project"); it("should evaluate symbols as javascript functions", async function () { @@ -36,7 +36,7 @@ describe("Solpp plugin", async function () { }); }); - describe("json-config-project", async function () { + describe("json-config-project", function () { useEnvironment("json-config-project"); it("should load definitions from json", async function () { @@ -54,7 +54,7 @@ describe("Solpp plugin", async function () { }); }); - describe("hardhat-project", async function () { + describe("hardhat-project", function () { useEnvironment("hardhat-project"); it("should create processed contracts in the cache directory", async function () { @@ -102,7 +102,7 @@ describe("Solpp plugin", async function () { }); // This test skipped because solpp won't fail if a contract has an non-defined symbol. - describe.skip("fail-project", async function () { + describe.skip("fail-project", function () { useEnvironment("fail-project"); it("should fail when symbol does not exist", async function () { diff --git a/packages/hardhat-toolbox-viem/.eslintrc.js b/packages/hardhat-toolbox-viem/.eslintrc.js new file mode 100644 index 0000000000..44ed8ed6d5 --- /dev/null +++ b/packages/hardhat-toolbox-viem/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: [`${__dirname}/../../config/eslint/eslintrc.js`], + parserOptions: { + project: `${__dirname}/src/tsconfig.json`, + sourceType: "module", + }, +}; diff --git a/packages/hardhat-toolbox-viem/.gitignore b/packages/hardhat-toolbox-viem/.gitignore new file mode 100644 index 0000000000..bf1014bb51 --- /dev/null +++ b/packages/hardhat-toolbox-viem/.gitignore @@ -0,0 +1,92 @@ +# Node modules +/node_modules + +# Compilation output +/build-test/ +/dist +/internal +/*.js +/*.js.map +/*.d.ts +/*.d.ts.map + +!.eslintrc.js + +# Code coverage artifacts +/coverage +/.nyc_output + +# Below is Github's node gitignore template, +# ignoring the node_modules part, as it'd ignore every node_modules, and we have some for testing + +# Logs +logs +*.log + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +#node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'pnpm pack' +*.tgz + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + diff --git a/packages/hardhat-toolbox-viem/.mocharc.json b/packages/hardhat-toolbox-viem/.mocharc.json new file mode 100644 index 0000000000..d00ceb4138 --- /dev/null +++ b/packages/hardhat-toolbox-viem/.mocharc.json @@ -0,0 +1,5 @@ +{ + "require": "ts-node/register/files", + "ignore": ["test/fixture-projects/**/*"], + "timeout": 10000 +} diff --git a/packages/hardhat-toolbox-viem/.prettierignore b/packages/hardhat-toolbox-viem/.prettierignore new file mode 100644 index 0000000000..1961b8ba50 --- /dev/null +++ b/packages/hardhat-toolbox-viem/.prettierignore @@ -0,0 +1,13 @@ +/node_modules +/dist +/internal +/test/fixture-projects/**/artifacts +/test/fixture-projects/**/artifacts-dir +/test/fixture-projects/**/cache +/*.d.ts +/*.d.ts.map +/*.js +/*.js.map +/build-test +CHANGELOG.md +!.eslintrc.js diff --git a/packages/hardhat-toolbox-viem/CHANGELOG.md b/packages/hardhat-toolbox-viem/CHANGELOG.md new file mode 100644 index 0000000000..324dbf9078 --- /dev/null +++ b/packages/hardhat-toolbox-viem/CHANGELOG.md @@ -0,0 +1,18 @@ +# @nomicfoundation/hardhat-toolbox-viem + +## 3.0.0 + +### Major Changes + +- 92d140f: Include Hardhat Ignition in the toolboxes. +- cfec932: Upgraded hardhat-toolbox-viem and project creation to support viem@2 + +### Patch Changes + +- Updated dependencies [92d140f] + +## 2.0.0 + +### Major Changes + +- 23665f399: Upgraded hardhat-verify dependency diff --git a/packages/hardhat-toolbox-viem/LICENSE b/packages/hardhat-toolbox-viem/LICENSE new file mode 100644 index 0000000000..3b7e8c7eab --- /dev/null +++ b/packages/hardhat-toolbox-viem/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Nomic Foundation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/hardhat-toolbox-viem/README.md b/packages/hardhat-toolbox-viem/README.md new file mode 100644 index 0000000000..51ff7fb1b7 --- /dev/null +++ b/packages/hardhat-toolbox-viem/README.md @@ -0,0 +1,29 @@ +[![npm](https://img.shields.io/npm/v/@nomicfoundation/hardhat-toolbox-viem.svg)](https://www.npmjs.com/package/@nomicfoundation/hardhat-toolbox-viem) [![hardhat](https://hardhat.org/buidler-plugin-badge.svg?1)](https://hardhat.org) + +# Hardhat Toolbox (Viem based) + +The `@nomicfoundation/hardhat-toolbox-viem` plugin bundles all the commonly used packages and Hardhat plugins we recommend to start developing with Hardhat. + +When you use this plugin, you'll be able to: + +- Interact with your contracts using [Viem](https://viem.sh/) and the [`hardhat-viem`](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-viem) plugin. +- Test your contracts with [Mocha](https://mochajs.org/), [Chai](https://chaijs.com/) and [Chai as Promised](https://github.com/domenic/chai-as-promised#chai-assertions-for-promises). Note: the plugin Hardhat Chai Matchers is currently not available for Viem. +- Deploy your contracts with [Hardhat Ignition](https://hardhat.org/ignition). +- Interact with Hardhat Network with our [Hardhat Network Helpers](https://hardhat.org/hardhat-network-helpers). +- Verify the source code of your contracts with the [hardhat-verify](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-verify) plugin. +- Get metrics on the gas used by your contracts with the [hardhat-gas-reporter](https://github.com/cgewecke/hardhat-gas-reporter) plugin. +- Measure your tests coverage with [solidity-coverage](https://github.com/sc-forks/solidity-coverage). + +**Note:** you might want to pin Viem-related dependencies because Viem does not strictly follow semantic versioning for type changes. You can read more [here](https://hardhat.org/hardhat-runner/docs/advanced/using-viem#managing-types-and-version-stability). + +### Usage + +To create a new project that uses the Toolbox, check our [Setting up a project guide](https://hardhat.org/hardhat-runner/docs/guides/project-setup) but select the _Create a TypeScript project (with Viem)_ option instead. + +### Network Helpers + +When the Toolbox is installed using npm 7 or later, its peer dependencies are automatically installed. However, these dependencies won't be listed in the `package.json`. As a result, directly importing the Network Helpers can be problematic for certain tools or IDEs. To address this issue, the Toolbox re-exports the Hardhat Network Helpers. You can use them like this: + +```ts +import helpers from "@nomicfoundation/hardhat-toolbox/network-helpers"; +``` diff --git a/packages/hardhat-toolbox-viem/package.json b/packages/hardhat-toolbox-viem/package.json new file mode 100644 index 0000000000..6ae9e4a03d --- /dev/null +++ b/packages/hardhat-toolbox-viem/package.json @@ -0,0 +1,97 @@ +{ + "name": "@nomicfoundation/hardhat-toolbox-viem", + "version": "3.0.0", + "description": "Nomic Foundation's recommended bundle of Hardhat plugins (viem based)", + "repository": "github:nomicfoundation/hardhat", + "homepage": "https://github.com/nomicfoundation/hardhat/tree/main/packages/hardhat-toolbox-viem", + "author": "Nomic Foundation", + "contributors": [ + "Nomic Foundation" + ], + "license": "MIT", + "main": "index.js", + "types": "index.d.ts", + "keywords": [ + "ethereum", + "smart-contracts", + "hardhat", + "hardhat-plugin", + "hardhat-viem" + ], + "scripts": { + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", + "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", + "prettier": "prettier \"**/*.{js,md,json}\"", + "pretest": "cd ../.. && pnpm build", + "test": "mocha --recursive \"test/**/*.ts\" --exit", + "build": "tsc --build .", + "prepublishOnly": "pnpm build", + "clean": "rimraf dist *.{d.ts,js}{,.map} build-test tsconfig.tsbuildinfo" + }, + "files": [ + "src/", + "internal/", + "*.d.ts", + "*.d.ts.map", + "*.js", + "*.js.map", + "LICENSE", + "README.md" + ], + "dependencies": { + "chai-as-promised": "^7.1.1" + }, + "devDependencies": { + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", + "@nomicfoundation/hardhat-ignition-viem": "workspace:^0.15.0", + "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", + "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", + "@nomicfoundation/hardhat-viem": "workspace:^2.0.0", + "@types/chai": "^4.2.0", + "@types/chai-as-promised": "^7.1.6", + "@types/mocha": ">=9.1.0", + "@types/node": "^18.0.0", + "@typescript-eslint/eslint-plugin": "5.61.0", + "@typescript-eslint/parser": "5.61.0", + "chai": "^4.2.0", + "eslint": "^8.44.0", + "eslint-config-prettier": "8.3.0", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-mocha": "10.4.1", + "eslint-plugin-prettier": "3.4.0", + "hardhat": "workspace:^2.11.0", + "hardhat-gas-reporter": "^1.0.8", + "mocha": "^10.0.0", + "prettier": "2.4.1", + "rimraf": "^3.0.2", + "solidity-coverage": "^0.8.1", + "ts-node": "^10.8.0", + "typescript": "~5.0.4", + "viem": "^2.7.6" + }, + "peerDependencies": { + "@nomicfoundation/hardhat-ignition-viem": "workspace:^0.15.0", + "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", + "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", + "@nomicfoundation/hardhat-viem": "workspace:^2.0.0", + "@types/chai": "^4.2.0", + "@types/chai-as-promised": "^7.1.6", + "@types/mocha": ">=9.1.0", + "@types/node": ">=18.0.0", + "chai": "^4.2.0", + "hardhat": "workspace:^2.11.0", + "hardhat-gas-reporter": "^1.0.8", + "solidity-coverage": "^0.8.1", + "ts-node": ">=8.0.0", + "typescript": "^5.0.4", + "viem": "^2.7.6" + }, + "bugs": { + "url": "https://github.com/nomicfoundation/hardhat/issues" + }, + "directories": { + "test": "test" + } +} diff --git a/packages/hardhat-toolbox-viem/src/index.ts b/packages/hardhat-toolbox-viem/src/index.ts new file mode 100644 index 0000000000..f166ee5e6c --- /dev/null +++ b/packages/hardhat-toolbox-viem/src/index.ts @@ -0,0 +1,39 @@ +import "@nomicfoundation/hardhat-verify"; +import "@nomicfoundation/hardhat-viem"; +import "@nomicfoundation/hardhat-ignition-viem"; +import "hardhat-gas-reporter"; +import "solidity-coverage"; +import "./internal/chai-setup"; + +/** + * If a new official plugin is added, make sure to update: + * - The tsconfig.json file + * - The hardhat-toolbox GitHub workflow + * - The parts of the documentation that install hardhat-toolbox with npm 6 or yarn + * - The list of dependencies that the sample projects install + * - The README + */ + +import { extendConfig } from "hardhat/config"; + +extendConfig((config, userConfig) => { + const configAsAny = config as any; + + // hardhat-gas-reporter doesn't use extendConfig, so + // the values of config.gasReporter and userConfig.gasReporter + // are the same. The userConfigVersion is frozen though, so we + // shouldn't use it. + const gasReporterConfig = + configAsAny.gasReporter as typeof userConfig.gasReporter; + + configAsAny.gasReporter = gasReporterConfig ?? {}; + + if (gasReporterConfig?.enabled === undefined) { + // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions + configAsAny.gasReporter.enabled = process.env.REPORT_GAS ? true : false; + } + + if (gasReporterConfig?.currency === undefined) { + configAsAny.gasReporter.currency = "USD"; + } +}); diff --git a/packages/hardhat-toolbox-viem/src/internal/chai-setup.ts b/packages/hardhat-toolbox-viem/src/internal/chai-setup.ts new file mode 100644 index 0000000000..c0c8e71856 --- /dev/null +++ b/packages/hardhat-toolbox-viem/src/internal/chai-setup.ts @@ -0,0 +1,4 @@ +import chai from "chai"; +import chaiAsPromised from "chai-as-promised"; + +chai.use(chaiAsPromised); diff --git a/packages/hardhat-toolbox-viem/src/network-helpers.ts b/packages/hardhat-toolbox-viem/src/network-helpers.ts new file mode 100644 index 0000000000..71747baddc --- /dev/null +++ b/packages/hardhat-toolbox-viem/src/network-helpers.ts @@ -0,0 +1 @@ +export * from "@nomicfoundation/hardhat-network-helpers"; diff --git a/packages/hardhat-toolbox-viem/src/tsconfig.json b/packages/hardhat-toolbox-viem/src/tsconfig.json new file mode 100644 index 0000000000..a703f8f42e --- /dev/null +++ b/packages/hardhat-toolbox-viem/src/tsconfig.json @@ -0,0 +1,24 @@ +{ + "extends": "../../../config/typescript/tsconfig.json", + "compilerOptions": { + "outDir": "../", + "rootDirs": ["."], + "composite": true + }, + "include": ["./**/*.ts"], + "exclude": [], + "references": [ + { + "path": "../../hardhat-core/src" + }, + { + "path": "../../hardhat-network-helpers" + }, + { + "path": "../../hardhat-verify/src" + }, + { + "path": "../../hardhat-viem/src" + } + ] +} diff --git a/packages/hardhat-toolbox-viem/test/.eslintrc.js b/packages/hardhat-toolbox-viem/test/.eslintrc.js new file mode 100644 index 0000000000..757fe8a3ca --- /dev/null +++ b/packages/hardhat-toolbox-viem/test/.eslintrc.js @@ -0,0 +1,15 @@ +module.exports = { + extends: [`${__dirname}/../.eslintrc.js`], + parserOptions: { + project: `${__dirname}/../tsconfig.json`, + sourceType: "module", + }, + rules: { + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: true, + }, + ], + }, +}; diff --git a/packages/hardhat-toolbox-viem/test/fixture-projects/only-toolbox/hardhat.config.js b/packages/hardhat-toolbox-viem/test/fixture-projects/only-toolbox/hardhat.config.js new file mode 100644 index 0000000000..dfbbe371ca --- /dev/null +++ b/packages/hardhat-toolbox-viem/test/fixture-projects/only-toolbox/hardhat.config.js @@ -0,0 +1 @@ +require("../../../"); diff --git a/packages/hardhat-toolbox-viem/test/fixture-projects/only-toolbox/script.js b/packages/hardhat-toolbox-viem/test/fixture-projects/only-toolbox/script.js new file mode 100644 index 0000000000..1247c84d46 --- /dev/null +++ b/packages/hardhat-toolbox-viem/test/fixture-projects/only-toolbox/script.js @@ -0,0 +1,27 @@ +const assert = require("assert"); +const chai = require("chai"); + +async function main() { + // check that viem exists + assert(viem !== undefined); + + // check that the expected tasks are there + const taskNames = Object.keys(tasks); + assert(taskNames.includes("verify")); + assert(taskNames.includes("coverage")); + + // check that the expected scopes are there + const scopeNames = Object.keys(scopes); + assert(scopeNames.includes("vars")); + assert(scopeNames.includes("ignition")); + + // assert that chai-as-promised is loaded + assert(chai.assert.eventually); +} + +main() + .then(() => process.exit(0)) + .catch((error) => { + console.error(error); + process.exit(1); + }); diff --git a/packages/hardhat-toolbox-viem/test/fixture-projects/with-gas-reporter-config/hardhat.config.js b/packages/hardhat-toolbox-viem/test/fixture-projects/with-gas-reporter-config/hardhat.config.js new file mode 100644 index 0000000000..77263c1734 --- /dev/null +++ b/packages/hardhat-toolbox-viem/test/fixture-projects/with-gas-reporter-config/hardhat.config.js @@ -0,0 +1,7 @@ +require("../../../"); + +module.exports = { + gasReporter: { + enabled: true, + }, +}; diff --git a/packages/hardhat-toolbox-viem/test/helpers.ts b/packages/hardhat-toolbox-viem/test/helpers.ts new file mode 100644 index 0000000000..4fc372b905 --- /dev/null +++ b/packages/hardhat-toolbox-viem/test/helpers.ts @@ -0,0 +1,24 @@ +// load the environment type extensions from the plugins +import type {} from "../src/index"; + +import { resetHardhatContext } from "hardhat/plugins-testing"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import path from "path"; + +declare module "mocha" { + interface Context { + env: HardhatRuntimeEnvironment; + } +} + +export function useEnvironment(fixtureProjectName: string) { + beforeEach("Loading hardhat environment", function () { + process.chdir(path.join(__dirname, "fixture-projects", fixtureProjectName)); + + this.env = require("hardhat"); + }); + + afterEach("Resetting hardhat", function () { + resetHardhatContext(); + }); +} diff --git a/packages/hardhat-toolbox-viem/test/test.ts b/packages/hardhat-toolbox-viem/test/test.ts new file mode 100644 index 0000000000..9bda13607e --- /dev/null +++ b/packages/hardhat-toolbox-viem/test/test.ts @@ -0,0 +1,26 @@ +import { assert } from "chai"; + +import { useEnvironment } from "./helpers"; + +describe("hardhat-toolbox-viem", function () { + describe("only-toolbox", function () { + useEnvironment("only-toolbox"); + + it("has all the expected things in the HRE", async function () { + await this.env.run("run", { + noCompile: true, + script: "script.js", + }); + + assert.equal(process.exitCode, 0); + }); + }); + + describe("hardhat-gas-reporter-config", function () { + useEnvironment("with-gas-reporter-config"); + + it("Should not crash while loading the HRE", async function () { + assert.isDefined(this.env, "The environment should be loaded"); + }); + }); +}); diff --git a/packages/hardhat-toolbox-viem/tsconfig.json b/packages/hardhat-toolbox-viem/tsconfig.json new file mode 100644 index 0000000000..65ecfc33b9 --- /dev/null +++ b/packages/hardhat-toolbox-viem/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../config/typescript/tsconfig.json", + "compilerOptions": { + "outDir": "./build-test", + "rootDirs": ["./test"], + "composite": true + }, + "include": ["./test/**/*.ts"], + "exclude": ["./node_modules", "./test/**/hardhat.config.ts"], + "references": [ + { + "path": "./src" + } + ] +} diff --git a/packages/hardhat-toolbox/.eslintrc.js b/packages/hardhat-toolbox/.eslintrc.js index 889740f226..44ed8ed6d5 100644 --- a/packages/hardhat-toolbox/.eslintrc.js +++ b/packages/hardhat-toolbox/.eslintrc.js @@ -1,7 +1,7 @@ module.exports = { extends: [`${__dirname}/../../config/eslint/eslintrc.js`], parserOptions: { - project: `${__dirname}/tsconfig.json`, + project: `${__dirname}/src/tsconfig.json`, sourceType: "module", }, }; diff --git a/packages/hardhat-toolbox/.gitignore b/packages/hardhat-toolbox/.gitignore index c00d7e7296..574f3e65a7 100644 --- a/packages/hardhat-toolbox/.gitignore +++ b/packages/hardhat-toolbox/.gitignore @@ -4,6 +4,10 @@ # Compilation output /build-test/ /dist +/*.js +/*.js.map +/*.d.ts +/*.d.ts.map # Code coverage artifacts /coverage @@ -15,10 +19,6 @@ # Logs logs *.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json @@ -57,21 +57,15 @@ jspm_packages/ # TypeScript v1 declaration files typings/ -# Optional npm cache directory -.npm - # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history -# Output of 'npm pack' +# Output of 'pnpm pack' *.tgz -# Yarn Integrity file -.yarn-integrity - # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/packages/hardhat-toolbox/.prettierignore b/packages/hardhat-toolbox/.prettierignore index 12cbe6bee7..eceda069d5 100644 --- a/packages/hardhat-toolbox/.prettierignore +++ b/packages/hardhat-toolbox/.prettierignore @@ -3,4 +3,10 @@ /test/fixture-projects/**/artifacts /test/fixture-projects/**/artifacts-dir /test/fixture-projects/**/cache +/*.d.ts +/*.d.ts.map +/*.js +/*.js.map +/build-test CHANGELOG.md +!.eslintrc.js diff --git a/packages/hardhat-toolbox/CHANGELOG.md b/packages/hardhat-toolbox/CHANGELOG.md index f0e56c3a1c..9d080ce46a 100644 --- a/packages/hardhat-toolbox/CHANGELOG.md +++ b/packages/hardhat-toolbox/CHANGELOG.md @@ -1,5 +1,27 @@ # @nomicfoundation/hardhat-toolbox +## 5.0.0 + +### Major Changes + +- 92d140f: Include Hardhat Ignition in the toolboxes. + +### Patch Changes + +- Updated dependencies [92d140f] + +## 4.0.0 + +### Major Changes + +- 23665f399: Upgraded typechain and hardhat-verify dependencies + +## 3.0.0 + +### Major Changes + +- 399347f40: The Toolbox and the plugins that it includes are now based on ethers v6 + ## 2.0.2 ### Patch Changes diff --git a/packages/hardhat-toolbox/LICENSE b/packages/hardhat-toolbox/LICENSE index d5cab88817..3b7e8c7eab 100644 --- a/packages/hardhat-toolbox/LICENSE +++ b/packages/hardhat-toolbox/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2022 Nomic Labs LLC +Copyright (c) 2023 Nomic Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/packages/hardhat-toolbox/README.md b/packages/hardhat-toolbox/README.md index 0ed50f6b6b..a3c8e86803 100644 --- a/packages/hardhat-toolbox/README.md +++ b/packages/hardhat-toolbox/README.md @@ -6,10 +6,11 @@ The `@nomicfoundation/hardhat-toolbox` plugin bundles all the commonly used pack When you use this plugin, you'll be able to: -- Deploy and interact with your contracts using [ethers.js](https://docs.ethers.io/v5/) and the [`hardhat-ethers`](https://hardhat.org/hardhat-runner/plugins/nomiclabs-hardhat-ethers) plugin. +- Interact with your contracts using [ethers.js](https://docs.ethers.org/v6/) and the [`hardhat-ethers`](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-ethers) plugin. - Test your contracts with [Mocha](https://mochajs.org/), [Chai](https://chaijs.com/) and our own [Hardhat Chai Matchers](https://hardhat.org/hardhat-chai-matchers) plugin. +- Deploy your contracts with [Hardhat Ignition](https://hardhat.org/ignition). - Interact with Hardhat Network with our [Hardhat Network Helpers](https://hardhat.org/hardhat-network-helpers). -- Verify the source code of your contracts with the [hardhat-etherscan](https://hardhat.org/hardhat-runner/plugins/nomiclabs-hardhat-etherscan) plugin. +- Verify the source code of your contracts with the [hardhat-verify](https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-verify) plugin. - Get metrics on the gas used by your contracts with the [hardhat-gas-reporter](https://github.com/cgewecke/hardhat-gas-reporter) plugin. - Measure your tests coverage with [solidity-coverage](https://github.com/sc-forks/solidity-coverage). - And, if you are using TypeScript, get type bindings for your contracts with [Typechain](https://github.com/dethcrypto/TypeChain/). @@ -19,3 +20,11 @@ When you use this plugin, you'll be able to: To create a new project that uses the Toolbox, check our [Setting up a project guide](https://hardhat.org/hardhat-runner/docs/guides/project-setup). If you want to migrate an existing Hardhat project to use the Toolbox, read [our migration guide](https://hardhat.org/hardhat-runner/docs/guides/migrating-from-hardhat-waffle). + +### Network Helpers + +When the Toolbox is installed using npm 7 or later, its peer dependencies are automatically installed. However, these dependencies won't be listed in the `package.json`. As a result, directly importing the Network Helpers can be problematic for certain tools or IDEs. To address this issue, the Toolbox re-exports the Hardhat Network Helpers. You can use them like this: + +```ts +import helpers from "@nomicfoundation/hardhat-toolbox/network-helpers"; +``` diff --git a/packages/hardhat-toolbox/package.json b/packages/hardhat-toolbox/package.json index 756773bb13..d4319bcf79 100644 --- a/packages/hardhat-toolbox/package.json +++ b/packages/hardhat-toolbox/package.json @@ -1,7 +1,7 @@ { "name": "@nomicfoundation/hardhat-toolbox", - "version": "2.0.2", - "description": "Nomic Foundation's recommended bundle of Hardhat plugins", + "version": "5.0.0", + "description": "Nomic Foundation's recommended bundle of Hardhat plugins (ethers based)", "repository": "github:nomicfoundation/hardhat", "homepage": "https://github.com/nomicfoundation/hardhat/tree/main/packages/hardhat-toolbox", "author": "Nomic Foundation", @@ -9,81 +9,85 @@ "Nomic Foundation" ], "license": "MIT", - "main": "dist/src/index.js", - "types": "dist/src/index.d.ts", + "main": "index.js", + "types": "index.d.ts", "keywords": [ "ethereum", "smart-contracts", "hardhat", - "hardhat-plugin" + "hardhat-plugin", + "hardhat-ethers" ], "scripts": { - "lint": "yarn prettier --check && yarn eslint", - "lint:fix": "yarn prettier --write && yarn eslint --fix", + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", "prettier": "prettier \"**/*.{js,md,json}\"", + "pretest": "cd ../.. && pnpm build", "test": "mocha --recursive \"test/**/*.ts\" --exit", "build": "tsc --build .", - "prepublishOnly": "yarn build", - "clean": "rimraf dist" + "prepublishOnly": "pnpm build", + "clean": "rimraf dist *.{d.ts,js}{,.map} build-test tsconfig.tsbuildinfo" }, "files": [ - "dist/src/", "src/", + "*.d.ts", + "*.d.ts.map", + "*.js", + "*.js.map", "LICENSE", "README.md" ], - "dependencies": {}, "devDependencies": { - "@ethersproject/abi": "^5.4.7", - "@ethersproject/providers": "^5.4.7", - "@nomicfoundation/hardhat-network-helpers": "^1.0.0", - "@nomicfoundation/hardhat-chai-matchers": "^1.0.0", - "@nomiclabs/hardhat-ethers": "^2.0.0", - "@nomiclabs/hardhat-etherscan": "^3.0.0", - "@typechain/ethers-v5": "^10.1.0", - "@typechain/hardhat": "^6.1.2", + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", + "@nomicfoundation/hardhat-chai-matchers": "workspace:^2.0.0", + "@nomicfoundation/hardhat-ethers": "workspace:^3.0.0", + "@nomicfoundation/hardhat-ignition-ethers": "workspace:^0.15.0", + "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", + "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", + "@typechain/ethers-v6": "^0.5.0", + "@typechain/hardhat": "^9.0.0", "@types/chai": "^4.2.0", "@types/mocha": ">=9.1.0", - "@types/node": "^14.0.0", - "@typescript-eslint/eslint-plugin": "4.29.2", - "@typescript-eslint/parser": "4.29.2", - "chai": "^4.2.0", - "eslint": "^7.29.0", + "@types/node": "^18.0.0", + "@typescript-eslint/eslint-plugin": "5.61.0", + "@typescript-eslint/parser": "5.61.0", + "chai": "^4.4.1", + "eslint": "^8.44.0", "eslint-config-prettier": "8.3.0", - "eslint-plugin-import": "2.24.1", - "eslint-plugin-no-only-tests": "3.0.0", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-mocha": "10.4.1", "eslint-plugin-prettier": "3.4.0", - "ethers": "^5.4.7", - "hardhat": "^2.11.0", + "ethers": "^6.4.0", + "hardhat": "workspace:^2.11.0", "hardhat-gas-reporter": "^1.0.8", "mocha": "^10.0.0", "prettier": "2.4.1", "rimraf": "^3.0.2", "solidity-coverage": "^0.8.1", "ts-node": "^10.8.0", - "typechain": "^8.1.0", - "typescript": "~4.7.4" + "typechain": "^8.3.1", + "typescript": "~5.0.0" }, "peerDependencies": { - "@ethersproject/abi": "^5.4.7", - "@ethersproject/providers": "^5.4.7", - "@nomicfoundation/hardhat-network-helpers": "^1.0.0", - "@nomicfoundation/hardhat-chai-matchers": "^1.0.0", - "@nomiclabs/hardhat-ethers": "^2.0.0", - "@nomiclabs/hardhat-etherscan": "^3.0.0", + "@nomicfoundation/hardhat-chai-matchers": "workspace:^2.0.0", + "@nomicfoundation/hardhat-ethers": "workspace:^3.0.0", + "@nomicfoundation/hardhat-ignition-ethers": "workspace:^0.15.0", + "@nomicfoundation/hardhat-network-helpers": "workspace:^1.0.0", + "@nomicfoundation/hardhat-verify": "workspace:^2.0.0", + "@typechain/ethers-v6": "^0.5.0", + "@typechain/hardhat": "^9.0.0", "@types/chai": "^4.2.0", "@types/mocha": ">=9.1.0", - "@types/node": ">=12.0.0", - "@typechain/ethers-v5": "^10.1.0", - "@typechain/hardhat": "^6.1.2", + "@types/node": ">=18.0.0", "chai": "^4.2.0", - "ethers": "^5.4.7", - "hardhat": "^2.11.0", + "ethers": "^6.4.0", + "hardhat": "workspace:^2.11.0", "hardhat-gas-reporter": "^1.0.8", "solidity-coverage": "^0.8.1", "ts-node": ">=8.0.0", - "typechain": "^8.1.0", + "typechain": "^8.3.0", "typescript": ">=4.5.0" }, "bugs": { diff --git a/packages/hardhat-toolbox/src/index.ts b/packages/hardhat-toolbox/src/index.ts index 8efa0d2902..df2c51973b 100644 --- a/packages/hardhat-toolbox/src/index.ts +++ b/packages/hardhat-toolbox/src/index.ts @@ -1,9 +1,11 @@ import "@nomicfoundation/hardhat-chai-matchers"; -import "@nomiclabs/hardhat-ethers"; -import "@nomiclabs/hardhat-etherscan"; +import "@nomicfoundation/hardhat-ethers"; +import "@nomicfoundation/hardhat-verify"; +import "@nomicfoundation/hardhat-ignition-ethers"; import "@typechain/hardhat"; import "hardhat-gas-reporter"; import "solidity-coverage"; + /** * If a new official plugin is added, make sure to update: * - The tsconfig.json file diff --git a/packages/hardhat-toolbox/src/network-helpers.ts b/packages/hardhat-toolbox/src/network-helpers.ts new file mode 100644 index 0000000000..71747baddc --- /dev/null +++ b/packages/hardhat-toolbox/src/network-helpers.ts @@ -0,0 +1 @@ +export * from "@nomicfoundation/hardhat-network-helpers"; diff --git a/packages/hardhat-toolbox/src/tsconfig.json b/packages/hardhat-toolbox/src/tsconfig.json new file mode 100644 index 0000000000..9f84761f8b --- /dev/null +++ b/packages/hardhat-toolbox/src/tsconfig.json @@ -0,0 +1,27 @@ +{ + "extends": "../../../config/typescript/tsconfig.json", + "compilerOptions": { + "outDir": "../", + "rootDirs": ["."], + "composite": true + }, + "include": ["./**/*.ts"], + "exclude": [], + "references": [ + { + "path": "../../hardhat-core/src" + }, + { + "path": "../../hardhat-chai-matchers" + }, + { + "path": "../../hardhat-network-helpers" + }, + { + "path": "../../hardhat-ethers/src" + }, + { + "path": "../../hardhat-verify/src" + } + ] +} diff --git a/packages/hardhat-toolbox/test/.eslintrc.js b/packages/hardhat-toolbox/test/.eslintrc.js new file mode 100644 index 0000000000..757fe8a3ca --- /dev/null +++ b/packages/hardhat-toolbox/test/.eslintrc.js @@ -0,0 +1,15 @@ +module.exports = { + extends: [`${__dirname}/../.eslintrc.js`], + parserOptions: { + project: `${__dirname}/../tsconfig.json`, + sourceType: "module", + }, + rules: { + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: true, + }, + ], + }, +}; diff --git a/packages/hardhat-toolbox/test/fixture-projects/only-toolbox/script.js b/packages/hardhat-toolbox/test/fixture-projects/only-toolbox/script.js index c0ebd4b5fa..8552eccb3b 100644 --- a/packages/hardhat-toolbox/test/fixture-projects/only-toolbox/script.js +++ b/packages/hardhat-toolbox/test/fixture-projects/only-toolbox/script.js @@ -6,9 +6,15 @@ async function main() { // check that the expected tasks are there const taskNames = Object.keys(tasks); + assert(taskNames.includes("verify")); assert(taskNames.includes("coverage")); assert(taskNames.includes("typechain")); + + // check that the expected scopes are there + const scopeNames = Object.keys(scopes); + assert(scopeNames.includes("vars")); + assert(scopeNames.includes("ignition")); } main() diff --git a/packages/hardhat-toolbox/test/helpers.ts b/packages/hardhat-toolbox/test/helpers.ts index e1b159efe3..4fc372b905 100644 --- a/packages/hardhat-toolbox/test/helpers.ts +++ b/packages/hardhat-toolbox/test/helpers.ts @@ -1,3 +1,6 @@ +// load the environment type extensions from the plugins +import type {} from "../src/index"; + import { resetHardhatContext } from "hardhat/plugins-testing"; import { HardhatRuntimeEnvironment } from "hardhat/types"; import path from "path"; diff --git a/packages/hardhat-toolbox/test/test.ts b/packages/hardhat-toolbox/test/test.ts index b977417f79..f2c16f4d4f 100644 --- a/packages/hardhat-toolbox/test/test.ts +++ b/packages/hardhat-toolbox/test/test.ts @@ -19,15 +19,20 @@ describe("hardhat-toolbox", function () { describe("hardhat-gas-reporter-config", function () { useEnvironment("with-gas-reporter-config"); - it("Should not crash while loading the HRE", async function () { - assert.isDefined(this.env); + it("Should not crash while loading the HRE", function () { + // TODO: bring back assert.isDefined + // asserts proxying is clashing, it seems to be version related + assert( + this.env !== undefined && this.env !== null, + "The environment should be loaded" + ); }); }); describe("typechain config", function () { useEnvironment("typechain-config"); - it("should disable typechain overrides for js projects", async function () { + it("should disable typechain overrides for js projects", function () { assert.isTrue(this.env.config.typechain.dontOverrideCompile); }); }); diff --git a/packages/hardhat-toolbox/tsconfig.json b/packages/hardhat-toolbox/tsconfig.json index fd844c410b..65ecfc33b9 100644 --- a/packages/hardhat-toolbox/tsconfig.json +++ b/packages/hardhat-toolbox/tsconfig.json @@ -1,24 +1,15 @@ { "extends": "../../config/typescript/tsconfig.json", "compilerOptions": { - "outDir": "./dist" + "outDir": "./build-test", + "rootDirs": ["./test"], + "composite": true }, - "exclude": ["./dist", "./node_modules", "./test/**/hardhat.config.ts"], + "include": ["./test/**/*.ts"], + "exclude": ["./node_modules", "./test/**/hardhat.config.ts"], "references": [ { - "path": "../hardhat-core/src" - }, - { - "path": "../hardhat-chai-matchers" - }, - { - "path": "../hardhat-network-helpers" - }, - { - "path": "../hardhat-ethers/src" - }, - { - "path": "../hardhat-verify" + "path": "./src" } ] } diff --git a/packages/hardhat-truffle4/.eslintrc.js b/packages/hardhat-truffle4/.eslintrc.js index 266b8d5f24..34b7ef64ea 100644 --- a/packages/hardhat-truffle4/.eslintrc.js +++ b/packages/hardhat-truffle4/.eslintrc.js @@ -1,3 +1,7 @@ +const { + slowImportsCommonIgnoredModules, +} = require("../../config/eslint/constants"); + module.exports = { extends: [`${__dirname}/../../config/eslint/eslintrc.js`], parserOptions: { @@ -15,4 +19,21 @@ module.exports = { }, ], }, + overrides: [ + { + files: ["src/index.ts"], + rules: { + "@nomicfoundation/slow-imports/no-top-level-external-import": [ + "error", + { + ignoreModules: [ + ...slowImportsCommonIgnoredModules, + "chai", + "@nomiclabs/hardhat-web3-legacy", + ], + }, + ], + }, + }, + ], }; diff --git a/packages/hardhat-truffle4/.gitignore b/packages/hardhat-truffle4/.gitignore index c00d7e7296..4aca21f18d 100644 --- a/packages/hardhat-truffle4/.gitignore +++ b/packages/hardhat-truffle4/.gitignore @@ -15,10 +15,6 @@ # Logs logs *.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json @@ -57,21 +53,15 @@ jspm_packages/ # TypeScript v1 declaration files typings/ -# Optional npm cache directory -.npm - # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history -# Output of 'npm pack' +# Output of 'pnpm pack' *.tgz -# Yarn Integrity file -.yarn-integrity - # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/packages/hardhat-truffle4/.mocharc.json b/packages/hardhat-truffle4/.mocharc.json index 775e35460d..68af7ce794 100644 --- a/packages/hardhat-truffle4/.mocharc.json +++ b/packages/hardhat-truffle4/.mocharc.json @@ -2,5 +2,5 @@ "require": "ts-node/register/files", "file": "../common/run-with-ganache", "ignore": ["test/fixture-projects/**/*"], - "timeout": 10000 + "timeout": 60000 } diff --git a/packages/hardhat-truffle4/LICENSE b/packages/hardhat-truffle4/LICENSE index 3b8858c555..3b7e8c7eab 100644 --- a/packages/hardhat-truffle4/LICENSE +++ b/packages/hardhat-truffle4/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Nomic Labs LLC +Copyright (c) 2023 Nomic Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/packages/hardhat-truffle4/README.md b/packages/hardhat-truffle4/README.md index d43c591812..a608fd5004 100644 --- a/packages/hardhat-truffle4/README.md +++ b/packages/hardhat-truffle4/README.md @@ -6,7 +6,7 @@ ## What -This plugin brings to Hardhat TruffleContracts from Truffle 4. With it you can call [`contract()` and `artifacts.require()`](https://truffleframework.com/docs/truffle/testing/writing-tests-in-javascript) like you normally would with Truffle. Interact with your contracts with a familiar API from tasks, scripts and tests. +This plugin brings to Hardhat TruffleContracts from Truffle 4. With it you can call [`contract()` and `artifacts.require()`](https://archive.trufflesuite.com/docs/truffle/how-to/debug-test/write-tests-in-javascript/) like you normally would with Truffle. Interact with your contracts with a familiar API from tasks, scripts and tests. Additionally, you can **migrate your contracts to Solidity 5 without needing to migrate your tests to Truffle 5**. diff --git a/packages/hardhat-truffle4/package.json b/packages/hardhat-truffle4/package.json index 64214a9985..2db5e1f9f5 100644 --- a/packages/hardhat-truffle4/package.json +++ b/packages/hardhat-truffle4/package.json @@ -17,13 +17,14 @@ "truffle-contract" ], "scripts": { - "lint": "yarn prettier --check && yarn eslint", - "lint:fix": "yarn prettier --write && yarn eslint --fix", + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", "prettier": "prettier \"**/*.{js,md,json}\"", + "pretest": "cd ../.. && pnpm build", "test": "mocha --recursive \"test/**/*.ts\" --exit", "build": "tsc --build .", - "prepublishOnly": "yarn build", + "prepublishOnly": "pnpm build", "clean": "rimraf dist" }, "files": [ @@ -40,30 +41,32 @@ "truffle-contract": "^3.0.7" }, "devDependencies": { - "@nomiclabs/hardhat-web3-legacy": "^2.0.0", + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", + "@nomiclabs/hardhat-web3-legacy": "workspace:^2.0.0", "@types/fs-extra": "^5.1.0", "@types/glob": "^7.1.1", "@types/mocha": ">=9.1.0", - "@types/node": "^14.0.0", - "@typescript-eslint/eslint-plugin": "5.53.0", - "@typescript-eslint/parser": "5.53.0", + "@types/node": "^18.0.0", + "@typescript-eslint/eslint-plugin": "5.61.0", + "@typescript-eslint/parser": "5.61.0", "chai": "^4.2.0", - "eslint": "^7.29.0", + "eslint": "^8.44.0", "eslint-config-prettier": "8.3.0", - "eslint-plugin-import": "2.24.1", - "eslint-plugin-no-only-tests": "3.0.0", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-mocha": "10.4.1", "eslint-plugin-prettier": "3.4.0", - "hardhat": "^2.6.4", + "hardhat": "workspace:^2.6.4", "mocha": "^10.0.0", "prettier": "2.4.1", "rimraf": "^3.0.2", "ts-node": "^10.8.0", - "typescript": "~4.7.4", + "typescript": "~5.0.0", "web3": "^0.20.0" }, "peerDependencies": { - "@nomiclabs/hardhat-web3-legacy": "^2.0.0", - "hardhat": "^2.6.4", + "@nomiclabs/hardhat-web3-legacy": "workspace:^2.0.0", + "hardhat": "workspace:^2.6.4", "web3": "^0.20.0" } } diff --git a/packages/hardhat-truffle4/src/artifacts.ts b/packages/hardhat-truffle4/src/artifacts.ts index c3d165ca23..be4b8be430 100644 --- a/packages/hardhat-truffle4/src/artifacts.ts +++ b/packages/hardhat-truffle4/src/artifacts.ts @@ -113,7 +113,7 @@ export class TruffleEnvironmentArtifacts { if (library !== undefined) { const firstLinkData = linksData[0]; - // link data is exressed in bytes, but the bytecode is hex encoded, so we + // link data is expressed in bytes, but the bytecode is hex encoded, so we // need to multiply everything by 2. const linkPlaceholder = destinationArtifact.bytecode.substr( firstLinkData.start * 2 + 2, // The + 2 is because of the 0x prefix diff --git a/packages/hardhat-truffle4/src/provisioner.ts b/packages/hardhat-truffle4/src/provisioner.ts index 84fc097445..b5f845ab5c 100644 --- a/packages/hardhat-truffle4/src/provisioner.ts +++ b/packages/hardhat-truffle4/src/provisioner.ts @@ -1,4 +1,4 @@ -import { wrapWithSolidityErrorsCorrection } from "hardhat/internal/hardhat-network/stack-traces/solidity-errors"; +import type { wrapWithSolidityErrorsCorrection as WrapWithSolidityErrorsCorrectionT } from "hardhat/internal/hardhat-network/stack-traces/solidity-errors"; import { NomicLabsHardhatPluginError } from "hardhat/plugins"; import { NetworkConfig } from "hardhat/types"; import util from "util"; @@ -67,6 +67,11 @@ export class LazyTruffleContractProvisioner { const originalNew = Contract.new; const originalAt = Contract.at; + const { wrapWithSolidityErrorsCorrection } = + require("hardhat/internal/hardhat-network/stack-traces/solidity-errors") as { + wrapWithSolidityErrorsCorrection: typeof WrapWithSolidityErrorsCorrectionT; + }; + Contract.new = async (...args: any[]) => { return wrapWithSolidityErrorsCorrection(async () => { args = await this._ensureTxParamsWithDefaults(args); @@ -175,6 +180,11 @@ export class LazyTruffleContractProvisioner { const originalSendTransaction = original.sendTransaction; const originalRequest = original.request; + const { wrapWithSolidityErrorsCorrection } = + require("hardhat/internal/hardhat-network/stack-traces/solidity-errors") as { + wrapWithSolidityErrorsCorrection: typeof WrapWithSolidityErrorsCorrectionT; + }; + instance[methodName] = async (...args: any[]) => { return wrapWithSolidityErrorsCorrection(async () => { args = await this._ensureTxParamsWithDefaults(args, !isConstant); diff --git a/packages/hardhat-truffle4/test/tests.ts b/packages/hardhat-truffle4/test/tests.ts index c084f25695..a1dca011d4 100644 --- a/packages/hardhat-truffle4/test/tests.ts +++ b/packages/hardhat-truffle4/test/tests.ts @@ -117,7 +117,7 @@ function testArtifactsFunctionality() { } }); - it("Should deploy linked contracts succesfully", async function () { + it("Should deploy linked contracts successfully", async function () { const Lib = this.env.artifacts.require("Lib"); const lib = await Lib.new(); assertIsContractInstance(lib, "addOne"); diff --git a/packages/hardhat-truffle5/.eslintrc.js b/packages/hardhat-truffle5/.eslintrc.js index 889740f226..acafebd7d2 100644 --- a/packages/hardhat-truffle5/.eslintrc.js +++ b/packages/hardhat-truffle5/.eslintrc.js @@ -1,7 +1,28 @@ +const { + slowImportsCommonIgnoredModules, +} = require("../../config/eslint/constants"); + module.exports = { extends: [`${__dirname}/../../config/eslint/eslintrc.js`], parserOptions: { project: `${__dirname}/tsconfig.json`, sourceType: "module", }, + overrides: [ + { + files: ["src/index.ts"], + rules: { + "@nomicfoundation/slow-imports/no-top-level-external-import": [ + "error", + { + ignoreModules: [ + ...slowImportsCommonIgnoredModules, + "chai", + "@nomiclabs/hardhat-web3", + ], + }, + ], + }, + }, + ], }; diff --git a/packages/hardhat-truffle5/.gitignore b/packages/hardhat-truffle5/.gitignore index c00d7e7296..4aca21f18d 100644 --- a/packages/hardhat-truffle5/.gitignore +++ b/packages/hardhat-truffle5/.gitignore @@ -15,10 +15,6 @@ # Logs logs *.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json @@ -57,21 +53,15 @@ jspm_packages/ # TypeScript v1 declaration files typings/ -# Optional npm cache directory -.npm - # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history -# Output of 'npm pack' +# Output of 'pnpm pack' *.tgz -# Yarn Integrity file -.yarn-integrity - # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/packages/hardhat-truffle5/LICENSE b/packages/hardhat-truffle5/LICENSE index 3b8858c555..3b7e8c7eab 100644 --- a/packages/hardhat-truffle5/LICENSE +++ b/packages/hardhat-truffle5/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Nomic Labs LLC +Copyright (c) 2023 Nomic Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/packages/hardhat-truffle5/README.md b/packages/hardhat-truffle5/README.md index f0ba4df798..34fe2b3db9 100644 --- a/packages/hardhat-truffle5/README.md +++ b/packages/hardhat-truffle5/README.md @@ -6,7 +6,7 @@ ## What -This plugin brings to Hardhat TruffleContracts from Truffle 5. With it you can call [`contract()` and `artifacts.require()`](https://truffleframework.com/docs/truffle/testing/writing-tests-in-javascript) like you normally would with Truffle. Interact with your contracts with a familiar API from tasks, scripts and tests. +This plugin brings to Hardhat TruffleContracts from Truffle 5. With it you can call [`contract()` and `artifacts.require()`](https://archive.trufflesuite.com/docs/truffle/how-to/debug-test/write-tests-in-javascript/) like you normally would with Truffle. Interact with your contracts with a familiar API from tasks, scripts and tests. ## Required plugins @@ -15,7 +15,7 @@ This plugin requires [hardhat-web3](https://github.com/nomiclabs/hardhat/tree/ma ## Installation ```bash -npm install --save-dev @nomiclabs/hardhat-truffle5 @nomiclabs/hardhat-web3 web3 +npm install --save-dev @nomiclabs/hardhat-truffle5 @nomiclabs/hardhat-web3 'web3@^1.0.0-beta.36' ``` And add the following statement to your `hardhat.config.js`: diff --git a/packages/hardhat-truffle5/package.json b/packages/hardhat-truffle5/package.json index cc577ed87c..bf479472fe 100644 --- a/packages/hardhat-truffle5/package.json +++ b/packages/hardhat-truffle5/package.json @@ -17,13 +17,14 @@ "truffle-contract" ], "scripts": { - "lint": "yarn prettier --check && yarn eslint", - "lint:fix": "yarn prettier --write && yarn eslint --fix", + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", "prettier": "prettier \"**/*.{js,md,json}\"", + "pretest": "cd ../.. && pnpm build", "test": "mocha --recursive \"test/**/*.ts\" --exit", "build": "tsc --build .", - "prepublishOnly": "yarn build", + "prepublishOnly": "pnpm build", "clean": "rimraf dist" }, "files": [ @@ -40,30 +41,34 @@ "fs-extra": "^7.0.1" }, "devDependencies": { - "@nomiclabs/hardhat-web3": "^2.0.0", + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", + "@nomiclabs/hardhat-web3": "workspace:^2.0.0", "@types/fs-extra": "^5.1.0", "@types/glob": "^7.1.1", "@types/mocha": ">=9.1.0", - "@types/node": "^14.0.0", - "@typescript-eslint/eslint-plugin": "5.53.0", - "@typescript-eslint/parser": "5.53.0", + "@types/node": "^18.0.0", + "@typescript-eslint/eslint-plugin": "5.61.0", + "@typescript-eslint/parser": "5.61.0", "chai": "^4.2.0", - "eslint": "^7.29.0", + "eslint": "^8.44.0", "eslint-config-prettier": "8.3.0", - "eslint-plugin-import": "2.24.1", - "eslint-plugin-no-only-tests": "3.0.0", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-mocha": "10.4.1", "eslint-plugin-prettier": "3.4.0", - "hardhat": "^2.6.4", + "hardhat": "workspace:^2.6.4", "mocha": "^10.0.0", "prettier": "2.4.1", "rimraf": "^3.0.2", "ts-node": "^10.8.0", - "typescript": "~4.7.4", - "web3": "^1.0.0-beta.36" + "typescript": "~5.0.0", + "web3": "^1.0.0-beta.36", + "web3-eth-abi": "1.10.4", + "web3-utils": "1.10.4" }, "peerDependencies": { - "@nomiclabs/hardhat-web3": "^2.0.0", - "hardhat": "^2.6.4", + "@nomiclabs/hardhat-web3": "workspace:^2.0.0", + "hardhat": "workspace:^2.6.4", "web3": "^1.0.0-beta.36" } } diff --git a/packages/hardhat-truffle5/src/artifacts.ts b/packages/hardhat-truffle5/src/artifacts.ts index d90f305127..6b1b542799 100644 --- a/packages/hardhat-truffle5/src/artifacts.ts +++ b/packages/hardhat-truffle5/src/artifacts.ts @@ -114,7 +114,7 @@ export class TruffleEnvironmentArtifacts { if (library !== undefined) { const firstLinkData = linksData[0]; - // link data is exressed in bytes, but the bytecode is hex encoded, so we + // link data is expressed in bytes, but the bytecode is hex encoded, so we // need to multiply everything by 2. const linkPlaceholder = destinationArtifact.bytecode.substr( firstLinkData.start * 2 + 2, // The + 2 is because of the 0x prefix diff --git a/packages/hardhat-truffle5/test/tests.ts b/packages/hardhat-truffle5/test/tests.ts index 74d4d43cc7..e9e3a8a5e3 100644 --- a/packages/hardhat-truffle5/test/tests.ts +++ b/packages/hardhat-truffle5/test/tests.ts @@ -110,7 +110,7 @@ function testArtifactsFunctionality() { } }); - it("Should deploy linked contracts succesfully", async function () { + it("Should deploy linked contracts successfully", async function () { const Lib = this.env.artifacts.require("Lib"); const lib = await Lib.new(); assertIsContractInstance(lib, "addOne"); diff --git a/packages/hardhat-verify/.eslintignore b/packages/hardhat-verify/.eslintignore new file mode 100644 index 0000000000..4110ca8786 --- /dev/null +++ b/packages/hardhat-verify/.eslintignore @@ -0,0 +1,8 @@ +.eslintrc.js + +*.d.ts +etherscan.js +index.js + +/build-test +/internal diff --git a/packages/hardhat-verify/.eslintrc.js b/packages/hardhat-verify/.eslintrc.js index 889740f226..13139c79c6 100644 --- a/packages/hardhat-verify/.eslintrc.js +++ b/packages/hardhat-verify/.eslintrc.js @@ -1,7 +1,24 @@ +const { + slowImportsCommonIgnoredModules, +} = require("../../config/eslint/constants"); + module.exports = { extends: [`${__dirname}/../../config/eslint/eslintrc.js`], parserOptions: { - project: `${__dirname}/tsconfig.json`, + project: `${__dirname}/src/tsconfig.json`, sourceType: "module", }, + overrides: [ + { + files: ["src/index.ts"], + rules: { + "@nomicfoundation/slow-imports/no-top-level-external-import": [ + "error", + { + ignoreModules: [...slowImportsCommonIgnoredModules], + }, + ], + }, + }, + ], }; diff --git a/packages/hardhat-verify/.gitignore b/packages/hardhat-verify/.gitignore index 230538feb0..de879e94f6 100644 --- a/packages/hardhat-verify/.gitignore +++ b/packages/hardhat-verify/.gitignore @@ -4,6 +4,11 @@ # Compilation output /build-test/ /dist +/internal +/*.js +/*.js.map +/*.d.ts +/*.d.ts.map # Code coverage artifacts /coverage @@ -15,10 +20,6 @@ # Logs logs *.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json @@ -57,21 +58,15 @@ jspm_packages/ # TypeScript v1 declaration files typings/ -# Optional npm cache directory -.npm - # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history -# Output of 'npm pack' +# Output of 'pnpm pack' *.tgz -# Yarn Integrity file -.yarn-integrity - # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/packages/hardhat-verify/.prettierignore b/packages/hardhat-verify/.prettierignore index 8b59d6f54c..606a44372c 100644 --- a/packages/hardhat-verify/.prettierignore +++ b/packages/hardhat-verify/.prettierignore @@ -1,5 +1,11 @@ /node_modules /dist +/internal +/*.d.ts +/*.d.ts.map +/*.js +/*.js.map +/build-test /test/fixture-projects/**/artifacts /test/fixture-projects/**/artifacts-dir /test/fixture-projects/**/cache diff --git a/packages/hardhat-verify/CHANGELOG.md b/packages/hardhat-verify/CHANGELOG.md new file mode 100644 index 0000000000..f554fae8c4 --- /dev/null +++ b/packages/hardhat-verify/CHANGELOG.md @@ -0,0 +1,127 @@ +# @nomicfoundation/hardhat-verify + +## 2.0.13 + +### Patch Changes + +- 0469eb2: Ink networks added + +## 2.0.12 + +### Patch Changes + +- f571670: Replace chalk with picocolors + +## 2.0.11 + +### Patch Changes + +- 913b5a1: Added Blockscout as a verification provider + +## 2.0.10 + +### Patch Changes + +- efa905d: Fix for corrupted Hardhat peer dependency version from pnpm. + +## 2.0.9 + +### Patch Changes + +- 88e57fa: Make the `--force` flag override the check of any existing verification, even in the presence of errors. + +## 2.0.8 + +### Patch Changes + +- 73d5bea: Improved validation of contructor arguments (thanks @fwx5618177!) + +## 2.0.7 + +### Patch Changes + +- f186e1a: Improved error handling and messaging for errors from the block explorer +- e7b12df: Added Polygon Amoy testnet (thanks @FournyP!) +- b9aada0: Added `--force` flag to allow verification of partially verified contracts (thanks @rimrakhimov!) + +## 2.0.6 + +### Patch Changes + +- 62d24cd: Added baseSepolia (thanks @hironate) + +## 2.0.5 + +### Patch Changes + +- 91d035e: Updated polygonZkEVMTestnet to point to cardona testnet + +## 2.0.4 + +### Patch Changes + +- fb673f2be: Added holesky and arbitrumSepolia, and removed arbitrumTestnet and arbitrumGoerli from hardhat-verify chains. +- 11043e96a: Added support for programmatic verification in Sourcify + +## 2.0.3 + +### Patch Changes + +- e77f1d8a0: Add apiUrl and browserUrl to Sourcify configuration. + +## 2.0.2 + +### Patch Changes + +- 5cab65fb7: Updated chiado urls to avoid redirect + +## 2.0.1 + +### Patch Changes + +- c2155fb26: Added polygonZkEVM and polygonZkEVMTestnet +- c7d87c41a: Fixed case-sensitive address comparison for detecting verified contracts + +## 2.0.0 + +### Major Changes + +- a32e68589: - Added Sourcify as a verification provider. + +## 1.1.1 + +### Patch Changes + +- 4ed196924: Added `base` mainnet + +## 1.1.0 + +### Minor Changes + +- e2fc27766: Exposed the Etherscan class as a public API for third-party consumers. + +## 1.0.4 + +### Patch Changes + +- 0f4411ce0: Added `baseGoerli` testnet. + +## 1.0.3 + +### Patch Changes + +- efe7824e0: Removed the `rinkeby`, `ropsten` and `kovan` deprecated test networks (thanks @pcaversaccio!) + +## 1.0.2 + +### Patch Changes + +- 4028c6e24: Fix URLs for the Aurora networks (thanks @zZoMROT and @ZumZoom!) +- 4028c6e24: Fixed a problem where the `--list-networks` flag wasn't working without passing an address (thanks @clauBv23!) +- 72162dcc7: Success messages are now more generic (thanks @clauBv23!). + +## 1.0.1 + +### Patch Changes + +- 40b371bca: Removed the compilation step from the verify task, and removed the noCompile flag diff --git a/packages/hardhat-verify/LICENSE b/packages/hardhat-verify/LICENSE index 3b8858c555..3b7e8c7eab 100644 --- a/packages/hardhat-verify/LICENSE +++ b/packages/hardhat-verify/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Nomic Labs LLC +Copyright (c) 2023 Nomic Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/packages/hardhat-verify/README.md b/packages/hardhat-verify/README.md index 350c3049d9..17f58efd83 100644 --- a/packages/hardhat-verify/README.md +++ b/packages/hardhat-verify/README.md @@ -6,7 +6,7 @@ ## What -This plugin helps you verify the source code for your Solidity contracts. At the moment, it supports [Etherscan](https://etherscan.io)-based explorers and explorers compatible with its API like [Blockscout](https://www.blockscout.com/). +This plugin helps you verify the source code for your Solidity contracts. At the moment, it supports [Etherscan](https://etherscan.io)-based explorers, explorers compatible with its API like [Blockscout](https://www.blockscout.com/) and [Sourcify](https://sourcify.dev/). It's smart and it tries to do as much as possible to facilitate the process: @@ -35,7 +35,7 @@ import "@nomicfoundation/hardhat-verify"; ## Tasks -This plugin provides the `verify` task, which allows you to verify contracts through Etherscan's service. +This plugin provides the `verify` task, which allows you to verify contracts through Sourcify and Etherscan's service. ## Environment extensions @@ -43,7 +43,7 @@ This plugin does not extend the environment. ## Usage -You need to add the following Etherscan config to your `hardhat.config.js` file: +You need to add the following Etherscan and Sourcify configs to your `hardhat.config.js` file: ```js module.exports = { @@ -54,6 +54,11 @@ module.exports = { // Your API key for Etherscan // Obtain one at https://etherscan.io/ apiKey: "YOUR_ETHERSCAN_API_KEY" + }, + sourcify: { + // Disabled by default + // Doesn't need an API key + enabled: true } }; ``` @@ -68,7 +73,7 @@ npx hardhat verify --network mainnet DEPLOYED_CONTRACT_ADDRESS "Constructor argu ### Complex arguments -When the constructor has a complex argument list, you'll need to write a javascript module that exports the argument list. The expected format is the same as a constructor list for an [ethers contract](https://docs.ethers.io/v5/api/contract/). For example, if you have a contract like this: +When the constructor has a complex argument list, you'll need to write a javascript module that exports the argument list. The expected format is the same as a constructor list for an [ethers contract](https://docs.ethers.org/v6/single-page/#api_contract__Contract). For example, if you have a contract like this: ```solidity struct Point { @@ -174,6 +179,36 @@ Keep in mind that the name you are giving to the network in `customChains` is th To see which custom chains are supported, run `npx hardhat verify --list-networks`. +### Verifying on Sourcify + +To verify a contract using Sourcify, you need to add to your Hardhat config: + +```js +sourcify: { + enabled: true, + // Optional: specify a different Sourcify server + apiUrl: "https://sourcify.dev/server", + // Optional: specify a different Sourcify repository + browserUrl: "https://repo.sourcify.dev", +} +``` + +and then run the `verify` task, passing the address of the contract and the network where it's deployed: + +```bash +npx hardhat verify --network mainnet DEPLOYED_CONTRACT_ADDRESS +``` + +**Note:** Constructor arguments are not required for Sourcify verification, but you'll need to provide them if you also have Etherscan verification enabled. + +To disable Sourcify verification and suppress related messages, set `enabled` to `false`: + +```js +sourcify: { + enabled: false, +} +``` + ### Using programmatically To call the verification task from within a Hardhat task or script, use the `"verify:verify"` subtask. Assuming the same contract as [above](#complex-arguments), you can run the subtask like this: @@ -208,6 +243,73 @@ hre.run("verify:verify", { } ``` +#### Advanced Usage: Using the Etherscan and Sourcify classes from another plugin + +Both Etherscan and Sourcify classes can be imported from the plugin for direct use. + +- **Etherscan Class Usage** + + ```js + import { Etherscan } from "@nomicfoundation/hardhat-verify/etherscan"; + + const instance = new Etherscan( + "abc123def123", // Etherscan API key + "https://api.etherscan.io/api", // Etherscan API URL + "https://etherscan.io" // Etherscan browser URL + ); + + if (!instance.isVerified("0x123abc...")) { + const { message: guid } = await instance.verify( + // Contract address + "0x123abc...", + // Contract source code + '{"language":"Solidity","sources":{"contracts/Sample.sol":{"content":"// SPDX-Lic..."}},"settings":{ ... }}', + // Contract name + "contracts/Sample.sol:MyContract", + // Compiler version + "v0.8.19+commit.7dd6d404", + // Encoded constructor arguments + "0000000000000000000000000000000000000000000000000000000000000032" + ); + + await sleep(1000); + const verificationStatus = await instance.getVerificationStatus(guid); + + if (verificationStatus.isSuccess()) { + const contractURL = instance.getContractUrl("0x123abc..."); + console.log( + `Successfully verified contract "MyContract" on Etherscan: ${contractURL}` + ); + } + } + ``` + +- **Sourcify Class Usage** + + ```js + import { Sourcify } from "@nomicfoundation/hardhat-verify/sourcify"; + + const instance = new Sourcify( + 1, + "https://sourcify.dev/server", + "https://repo.sourcify.dev" + ); // Set chainId + + if (!instance.isVerified("0x123abc...")) { + const sourcifyResponse = await instance.verify("0x123abc...", { + "metadata.json": "{...}", + "otherFile.sol": "...", + }); + if (sourcifyResponse.isOk()) { + const contractURL = instance.getContractUrl( + "0x123abc...", + sourcifyResponse.status + ); + console.log(`Successfully verified contract on Sourcify: ${contractURL}`); + } + } + ``` + ## How it works The plugin works by fetching the bytecode in the given address and using it to check which contract in your project corresponds to it. Besides that, some sanity checks are performed locally to make sure that the verification won't fail. diff --git a/packages/hardhat-verify/package.json b/packages/hardhat-verify/package.json index 029218e3e3..8f7871ea77 100644 --- a/packages/hardhat-verify/package.json +++ b/packages/hardhat-verify/package.json @@ -1,13 +1,7 @@ { "name": "@nomicfoundation/hardhat-verify", - "version": "1.0.0", + "version": "2.0.13", "description": "Hardhat plugin for verifying contracts", - "homepage": "https://github.com/nomicfoundation/hardhat/tree/main/packages/hardhat-verify", - "repository": "github:nomicfoundation/hardhat", - "author": "Nomic Foundation", - "license": "MIT", - "main": "dist/src/index.js", - "types": "dist/src/index.d.ts", "keywords": [ "ethereum", "smart-contracts", @@ -15,55 +9,70 @@ "hardhat-plugin", "etherscan" ], - "scripts": { - "lint": "yarn prettier --check && yarn eslint", - "lint:fix": "yarn prettier --write && yarn eslint --fix", - "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", - "prettier": "prettier \"**/*.{js,md,json}\"", - "test": "mocha --recursive \"test/**/*.ts\" --exit", - "coverage": "nyc yarn test -- --reporter min", - "build": "tsc --build .", - "prepublishOnly": "yarn build", - "clean": "rimraf dist" - }, + "homepage": "https://github.com/nomicfoundation/hardhat/tree/main/packages/hardhat-verify", + "repository": "github:nomicfoundation/hardhat", + "license": "MIT", + "author": "Nomic Foundation", + "main": "index.js", + "types": "index.d.ts", "files": [ "dist/src/", "src/", + "internal/", + "*.d.ts", + "*.d.ts.map", + "*.js", + "*.js.map", "LICENSE", "README.md" ], + "scripts": { + "build": "tsc --build .", + "clean": "rimraf dist internal *.{d.ts,js}{,.map} build-test tsconfig.tsbuildinfo", + "coverage": "nyc pnpm test -- --reporter min", + "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", + "prepublishOnly": "pnpm build", + "prettier": "prettier \"**/*.{js,md,json}\"", + "pretest": "cd ../.. && pnpm build", + "test": "mocha --recursive \"test/**/*.ts\" --exit" + }, "dependencies": { "@ethersproject/abi": "^5.1.2", "@ethersproject/address": "^5.0.2", "cbor": "^8.1.0", - "chalk": "^2.4.2", "debug": "^4.1.1", "lodash.clonedeep": "^4.5.0", + "picocolors": "^1.1.0", "semver": "^6.3.0", "table": "^6.8.0", "undici": "^5.14.0" }, "devDependencies": { - "@nomiclabs/hardhat-ethers": "^2.0.0", + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", + "@nomicfoundation/hardhat-ethers": "workspace:^3.0.0", "@types/chai": "^4.2.0", "@types/chai-as-promised": "^7.1.3", + "@types/debug": "^4.1.4", "@types/lodash.clonedeep": "^4.5.7", "@types/mocha": ">=9.1.0", - "@types/node": "^14.0.0", + "@types/node": "^18.0.0", "@types/semver": "^6.0.2", "@types/sinon": "^9.0.8", "@types/sinon-chai": "^3.2.9", - "@typescript-eslint/eslint-plugin": "5.53.0", - "@typescript-eslint/parser": "5.53.0", + "@typescript-eslint/eslint-plugin": "5.61.0", + "@typescript-eslint/parser": "5.61.0", "chai": "^4.2.0", "chai-as-promised": "^7.1.1", - "eslint": "^7.29.0", + "eslint": "^8.44.0", "eslint-config-prettier": "8.3.0", - "eslint-plugin-import": "2.24.1", - "eslint-plugin-no-only-tests": "3.0.0", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-mocha": "10.4.1", "eslint-plugin-prettier": "3.4.0", "ethers": "^5.0.0", - "hardhat": "^2.0.4", + "hardhat": "workspace:^2.0.4", "mocha": "^10.0.0", "nyc": "^15.1.0", "prettier": "2.4.1", @@ -71,9 +80,9 @@ "sinon": "^9.0.0", "sinon-chai": "^3.7.0", "ts-node": "^10.8.0", - "typescript": "~4.7.4" + "typescript": "~5.0.0" }, "peerDependencies": { - "hardhat": "^2.0.4" + "hardhat": "workspace:^2.0.4" } } diff --git a/packages/hardhat-verify/src/blockscout.ts b/packages/hardhat-verify/src/blockscout.ts new file mode 100644 index 0000000000..fe1d4fd392 --- /dev/null +++ b/packages/hardhat-verify/src/blockscout.ts @@ -0,0 +1 @@ +export { Blockscout } from "./internal/blockscout"; diff --git a/packages/hardhat-verify/src/chain-config.ts b/packages/hardhat-verify/src/chain-config.ts deleted file mode 100644 index 434b2a00ca..0000000000 --- a/packages/hardhat-verify/src/chain-config.ts +++ /dev/null @@ -1,292 +0,0 @@ -import type { Network } from "hardhat/types"; -import type { ChainConfig } from "./types"; - -import { HARDHAT_NETWORK_NAME } from "hardhat/plugins"; -import { ChainConfigNotFoundError, NetworkNotSupportedError } from "./errors"; - -export async function getCurrentChainConfig( - { name, provider }: Network, - customChains: ChainConfig[] -): Promise { - const currentChainId = parseInt(await provider.send("eth_chainId"), 16); - - const currentChainConfig = [ - // custom chains has higher precedence than builtin chains - ...[...customChains].reverse(), // the last entry has higher precedence - ...builtinChains, - ].find(({ chainId }) => chainId === currentChainId); - - if (currentChainConfig === undefined) { - if (name === HARDHAT_NETWORK_NAME) { - throw new NetworkNotSupportedError(name); - } - - throw new ChainConfigNotFoundError(currentChainId); - } - - return currentChainConfig; -} - -// See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md#list-of-chain-ids -export const builtinChains: ChainConfig[] = [ - { - network: "mainnet", - chainId: 1, - urls: { - apiURL: "https://api.etherscan.io/api", - browserURL: "https://etherscan.io", - }, - }, - { - network: "ropsten", - chainId: 3, - urls: { - apiURL: "https://api-ropsten.etherscan.io/api", - browserURL: "https://ropsten.etherscan.io", - }, - }, - { - network: "rinkeby", - chainId: 4, - urls: { - apiURL: "https://api-rinkeby.etherscan.io/api", - browserURL: "https://rinkeby.etherscan.io", - }, - }, - { - network: "goerli", - chainId: 5, - urls: { - apiURL: "https://api-goerli.etherscan.io/api", - browserURL: "https://goerli.etherscan.io", - }, - }, - { - network: "optimisticEthereum", - chainId: 10, - urls: { - apiURL: "https://api-optimistic.etherscan.io/api", - browserURL: "https://optimistic.etherscan.io/", - }, - }, - { - network: "kovan", - chainId: 42, - urls: { - apiURL: "https://api-kovan.etherscan.io/api", - browserURL: "https://kovan.etherscan.io", - }, - }, - { - network: "bsc", - chainId: 56, - urls: { - apiURL: "https://api.bscscan.com/api", - browserURL: "https://bscscan.com", - }, - }, - { - network: "sokol", - chainId: 77, - urls: { - apiURL: "https://blockscout.com/poa/sokol/api", - browserURL: "https://blockscout.com/poa/sokol", - }, - }, - { - network: "bscTestnet", - chainId: 97, - urls: { - apiURL: "https://api-testnet.bscscan.com/api", - browserURL: "https://testnet.bscscan.com", - }, - }, - { - network: "xdai", - chainId: 100, - urls: { - apiURL: "https://api.gnosisscan.io/api", - browserURL: "https://gnosisscan.io", - }, - }, - { - network: "gnosis", - chainId: 100, - urls: { - apiURL: "https://api.gnosisscan.io/api", - browserURL: "https://gnosisscan.io", - }, - }, - { - network: "heco", - chainId: 128, - urls: { - apiURL: "https://api.hecoinfo.com/api", - browserURL: "https://hecoinfo.com", - }, - }, - { - network: "polygon", - chainId: 137, - urls: { - apiURL: "https://api.polygonscan.com/api", - browserURL: "https://polygonscan.com", - }, - }, - { - network: "opera", - chainId: 250, - urls: { - apiURL: "https://api.ftmscan.com/api", - browserURL: "https://ftmscan.com", - }, - }, - { - network: "hecoTestnet", - chainId: 256, - urls: { - apiURL: "https://api-testnet.hecoinfo.com/api", - browserURL: "https://testnet.hecoinfo.com", - }, - }, - { - network: "optimisticGoerli", - chainId: 420, - urls: { - apiURL: "https://api-goerli-optimism.etherscan.io/api", - browserURL: "https://goerli-optimism.etherscan.io/", - }, - }, - { - network: "moonbeam", - chainId: 1284, - urls: { - apiURL: "https://api-moonbeam.moonscan.io/api", - browserURL: "https://moonbeam.moonscan.io", - }, - }, - { - network: "moonriver", - chainId: 1285, - urls: { - apiURL: "https://api-moonriver.moonscan.io/api", - browserURL: "https://moonriver.moonscan.io", - }, - }, - { - network: "moonbaseAlpha", - chainId: 1287, - urls: { - apiURL: "https://api-moonbase.moonscan.io/api", - browserURL: "https://moonbase.moonscan.io/", - }, - }, - { - network: "ftmTestnet", - chainId: 4002, - urls: { - apiURL: "https://api-testnet.ftmscan.com/api", - browserURL: "https://testnet.ftmscan.com", - }, - }, - { - network: "chiado", - chainId: 10200, - urls: { - apiURL: "https://blockscout.chiadochain.net/api", - browserURL: "https://blockscout.chiadochain.net", - }, - }, - { - network: "arbitrumOne", - chainId: 42161, - urls: { - apiURL: "https://api.arbiscan.io/api", - browserURL: "https://arbiscan.io/", - }, - }, - { - network: "avalancheFujiTestnet", - chainId: 43113, - urls: { - apiURL: "https://api-testnet.snowtrace.io/api", - browserURL: "https://testnet.snowtrace.io/", - }, - }, - { - network: "avalanche", - chainId: 43114, - urls: { - apiURL: "https://api.snowtrace.io/api", - browserURL: "https://snowtrace.io/", - }, - }, - { - network: "polygonMumbai", - chainId: 80001, - urls: { - apiURL: "https://api-testnet.polygonscan.com/api", - browserURL: "https://mumbai.polygonscan.com/", - }, - }, - { - network: "arbitrumTestnet", - chainId: 421611, - urls: { - apiURL: "https://api-testnet.arbiscan.io/api", - browserURL: "https://testnet.arbiscan.io/", - }, - }, - { - network: "arbitrumGoerli", - chainId: 421613, - urls: { - apiURL: "https://api-goerli.arbiscan.io/api", - browserURL: "https://goerli.arbiscan.io/", - }, - }, - { - network: "sepolia", - chainId: 11155111, - urls: { - apiURL: "https://api-sepolia.etherscan.io/api", - browserURL: "https://sepolia.etherscan.io", - }, - }, - { - network: "aurora", - chainId: 1313161554, - urls: { - apiURL: "https://explorer.mainnet.aurora.dev/api", - browserURL: "https://aurorascan.dev/", - }, - }, - { - network: "auroraTestnet", - chainId: 1313161555, - urls: { - apiURL: "https://explorer.testnet.aurora.dev/api", - browserURL: "https://testnet.aurorascan.dev", - }, - }, - { - network: "harmony", - chainId: 1666600000, - urls: { - apiURL: "https://ctrver.t.hmny.io/verify", - browserURL: "https://explorer.harmony.one", - }, - }, - { - network: "harmonyTest", - chainId: 1666700000, - urls: { - apiURL: "https://ctrver.t.hmny.io/verify?network=testnet", - browserURL: "https://explorer.pops.one", - }, - }, -]; - -// We are not adding new networks to the core of hardhat-etherscan anymore. -// Please read this to learn how to manually add support for custom networks: -// https://github.com/NomicFoundation/hardhat/tree/main/packages/hardhat-etherscan#adding-support-for-other-networks diff --git a/packages/hardhat-verify/src/config.ts b/packages/hardhat-verify/src/config.ts deleted file mode 100644 index a39bf3187d..0000000000 --- a/packages/hardhat-verify/src/config.ts +++ /dev/null @@ -1,33 +0,0 @@ -import type LodashCloneDeepT from "lodash.clonedeep"; -import chalk from "chalk"; -import { HardhatConfig, HardhatUserConfig } from "hardhat/types"; -import { EtherscanConfig } from "./types"; - -export function etherscanConfigExtender( - config: HardhatConfig, - userConfig: Readonly -): void { - const defaultConfig: EtherscanConfig = { - apiKey: "", - customChains: [], - }; - - if (userConfig.etherscan !== undefined) { - const cloneDeep = require("lodash.clonedeep") as typeof LodashCloneDeepT; - const customConfig = cloneDeep(userConfig.etherscan); - - config.etherscan = { ...defaultConfig, ...customConfig }; - } else { - config.etherscan = defaultConfig; - - // check that there is no etherscan entry in the networks object, since - // this is a common mistake made by users - if (config.networks?.etherscan !== undefined) { - console.warn( - chalk.yellow( - "WARNING: you have an 'etherscan' entry in your networks configuration. This is likely a mistake. The etherscan configuration should be at the root of the configuration, not within the networks object." - ) - ); - } - } -} diff --git a/packages/hardhat-verify/src/errors.ts b/packages/hardhat-verify/src/errors.ts deleted file mode 100644 index 54c0cd7fed..0000000000 --- a/packages/hardhat-verify/src/errors.ts +++ /dev/null @@ -1,475 +0,0 @@ -import { NomicLabsHardhatPluginError } from "hardhat/plugins"; -import { - ABIArgumentLengthErrorType, - ABIArgumentOverflowErrorType, - ABIArgumentTypeErrorType, -} from "./abi-validation-extras"; -import { TASK_VERIFY_VERIFY } from "./task-names"; - -export class HardhatEtherscanError extends NomicLabsHardhatPluginError { - constructor(message: string, parent?: Error) { - super("@nomicfoundation/hardhat-verify", message, parent); - } -} - -export class MissingAddressError extends HardhatEtherscanError { - constructor() { - super( - "You didn’t provide any address. Please re-run the 'verify' task with the address of the contract you want to verify." - ); - } -} - -export class InvalidAddressError extends HardhatEtherscanError { - constructor(address: string) { - super(`${address} is an invalid address.`); - } -} - -export class InvalidContractNameError extends HardhatEtherscanError { - constructor(contractName: string) { - super(`A valid fully qualified name was expected. Fully qualified names look like this: "contracts/AContract.sol:TheContract" -Instead, this name was received: ${contractName}`); - } -} - -export class MissingApiKeyError extends HardhatEtherscanError { - constructor(network: string) { - super(`You are trying to verify a contract in '${network}', but no API token was found for this network. Please provide one in your hardhat config. For example: - -{ - ... - etherscan: { - apiKey: { - ${network}: 'your API key' - } - } -} - -See https://etherscan.io/apis`); - } -} - -export class InvalidConstructorArgumentsError extends HardhatEtherscanError { - constructor() { - super(`The constructorArguments parameter should be an array. -If your constructor has no arguments pass an empty array. E.g: - - await run("${TASK_VERIFY_VERIFY}", { - , - constructorArguments: [] - };`); - } -} - -export class ExclusiveConstructorArgumentsError extends HardhatEtherscanError { - constructor() { - super( - "The parameters constructorArgsParams and constructorArgsModule are exclusive. Please provide only one of them." - ); - } -} - -export class InvalidConstructorArgumentsModuleError extends HardhatEtherscanError { - constructor(constructorArgsModulePath: string) { - super(`The module ${constructorArgsModulePath} doesn't export a list. The module should look like this: - -module.exports = [ arg1, arg2, ... ];`); - } -} - -export class InvalidLibrariesError extends HardhatEtherscanError { - constructor() { - super(`The libraries parameter should be a dictionary. -If your contract does not have undetectable libraries pass an empty object or omit the argument. E.g: - - await run("${TASK_VERIFY_VERIFY}", { - , - libraries: {} - };`); - } -} - -export class InvalidLibrariesModuleError extends HardhatEtherscanError { - constructor(librariesModulePath: string) { - super(`The module ${librariesModulePath} doesn't export a dictionary. The module should look like this: - -module.exports = { lib1: "0x...", lib2: "0x...", ... };`); - } -} - -export class ImportingModuleError extends HardhatEtherscanError { - constructor(module: string, parent: Error) { - super( - `Importing the module for the ${module} failed. -Reason: ${parent.message}`, - parent - ); - } -} - -export class NetworkNotSupportedError extends HardhatEtherscanError { - constructor(network: string) { - super( - `The selected network is ${network}. Please select a network supported by Etherscan.` - ); - } -} - -export class ChainConfigNotFoundError extends HardhatEtherscanError { - constructor(chainId: number) { - super(`Trying to verify a contract in a network with chain id ${chainId}, but the plugin doesn't recognize it as a supported chain. - -You can manually add support for it by following these instructions: https://hardhat.org/verify-custom-networks - -To see the list of supported networks, run this command: - - npx hardhat verify --list-networks`); - } -} - -export class ContractVerificationRequestError extends HardhatEtherscanError { - constructor(url: string, parent: Error) { - super( - `Failed to send contract verification request. -Endpoint URL: ${url} -Reason: ${parent.message}`, - parent - ); - } -} - -export class ContractVerificationInvalidStatusCodeError extends HardhatEtherscanError { - constructor(url: string, statusCode: number, responseText: string) { - super(`Failed to send contract verification request. -Endpoint URL: ${url} -The HTTP server response is not ok. Status code: ${statusCode} Response text: ${responseText}`); - } -} - -export class ContractVerificationMissingBytecodeError extends HardhatEtherscanError { - constructor(url: string, contractAddress: string) { - super(`Failed to send contract verification request. -Endpoint URL: ${url} -Reason: The Etherscan API responded that the address ${contractAddress} does not have bytecode. -This can happen if the contract was recently deployed and this fact hasn't propagated to the backend yet. -Try waiting for a minute before verifying your contract. If you are invoking this from a script, -try to wait for five confirmations of your contract deployment transaction before running the verification subtask.`); - } -} - -export class ContractStatusPollingError extends HardhatEtherscanError { - constructor(url: string, parent: Error) { - super( - `Failure during etherscan status polling. The verification may still succeed but -should be checked manually. -Endpoint URL: ${url} -Reason: ${parent.message}`, - parent - ); - } -} - -export class ContractStatusPollingInvalidStatusCodeError extends HardhatEtherscanError { - constructor(statusCode: number, responseText: string) { - super( - `The HTTP server response is not ok. Status code: ${statusCode} Response text: ${responseText}` - ); - } -} - -export class ContractStatusPollingResponseNotOkError extends HardhatEtherscanError { - constructor(message: string) { - super(`The Etherscan API responded with a failure status. -The verification may still succeed but should be checked manually. -Reason: ${message}`); - } -} - -export class EtherscanVersionNotSupportedError extends HardhatEtherscanError { - constructor() { - super(`Etherscan only supports compiler versions 0.4.11 and higher. -See https://etherscan.io/solcversions for more information.`); - } -} - -export class DeployedBytecodeNotFoundError extends HardhatEtherscanError { - constructor(address: string, network: string) { - super(`The address ${address} has no bytecode. Is the contract deployed to this network? -The selected network is ${network}.`); - } -} - -export class CompilerVersionsMismatchError extends HardhatEtherscanError { - constructor( - configCompilerVersions: string[], - inferredCompilerVersion: string, - network: string - ) { - const versionDetails = - configCompilerVersions.length > 1 - ? `versions are: ${configCompilerVersions.join(", ")}` - : `version is: ${configCompilerVersions[0]}`; - - super(`The contract you want to verify was compiled with solidity ${inferredCompilerVersion}, but your configured compiler ${versionDetails}. - -Possible causes are: -- You are not in the same commit that was used to deploy the contract. -- Wrong compiler version selected in hardhat config. -- The given address is wrong. -- The selected network (${network}) is wrong.`); - } -} - -export class ContractNotFoundError extends HardhatEtherscanError { - constructor(contractFQN: string) { - super(`The contract ${contractFQN} is not present in your project.`); - } -} - -export class BuildInfoNotFoundError extends HardhatEtherscanError { - constructor(contractFQN: string) { - super(`The contract ${contractFQN} is present in your project, but we couldn't find its sources. -Please make sure that it has been compiled by Hardhat and that it is written in Solidity.`); - } -} - -export class BuildInfoCompilerVersionMismatchError extends HardhatEtherscanError { - constructor( - contractFQN: string, - compilerVersion: string, - isVersionRange: boolean, - buildInfoCompilerVersion: string, - network: string - ) { - const versionDetails = isVersionRange - ? `a solidity version in the range ${compilerVersion}` - : `the solidity version ${compilerVersion}`; - - super(`The contract ${contractFQN} is being compiled with ${buildInfoCompilerVersion}. -However, the contract found in the address provided as argument has its bytecode marked with ${versionDetails}. - -Possible causes are: -- Solidity compiler version settings were modified after the deployment was executed. -- The given address is wrong. -- The selected network (${network}) is wrong.`); - } -} - -export class DeployedBytecodeMismatchError extends HardhatEtherscanError { - constructor(network: string) { - super(`The address provided as argument contains a contract, but its bytecode doesn't match any of your local contracts. - -Possible causes are: - - Contract code changed after the deployment was executed. This includes code for seemingly unrelated contracts. - - A solidity file was added, moved, deleted or renamed after the deployment was executed. This includes files for seemingly unrelated contracts. - - Solidity compiler settings were modified after the deployment was executed (like the optimizer, target EVM, etc.). - - The given address is wrong. - - The selected network (${network}) is wrong.`); - } -} - -export class DeployedBytecodeMultipleMatchesError extends HardhatEtherscanError { - constructor(fqnMatches: string[]) { - super(`More than one contract was found to match the deployed bytecode. -Please use the contract parameter with one of the following contracts: -${fqnMatches.map((x) => ` * ${x}`).join("\n")} - -For example: - -hardhat verify --contract contracts/Example.sol:ExampleContract - -If you are running the verify subtask from within Hardhat instead: - -await run("${TASK_VERIFY_VERIFY}", { -, -contract: "contracts/Example.sol:ExampleContract" -};`); - } -} - -export class DeployedBytecodeDoesNotMatchFQNError extends HardhatEtherscanError { - constructor(contractFQN: string, network: string) { - super(`The address provided as argument contains a contract, but its bytecode doesn't match the contract ${contractFQN}. - -Possible causes are: - - Contract code changed after the deployment was executed. This includes code for seemingly unrelated contracts. - - A solidity file was added, moved, deleted or renamed after the deployment was executed. This includes files for seemingly unrelated contracts. - - Solidity compiler settings were modified after the deployment was executed (like the optimizer, target EVM, etc.). - - The given address is wrong. - - The selected network (${network}) is wrong.`); - } -} - -export class InvalidLibraryAddressError extends HardhatEtherscanError { - constructor( - contractName: string, - libraryName: string, - libraryAddress: string - ) { - super( - `You gave a link for the contract ${contractName} with the library ${libraryName}, but provided this invalid address: ${libraryAddress}` - ); - } -} - -export class DuplicatedLibraryError extends HardhatEtherscanError { - constructor(libraryName: string, libraryFQN: string) { - super( - `The library names ${libraryName} and ${libraryFQN} refer to the same library and were given as two entries in the libraries dictionary. -Remove one of them and review your libraries dictionary before proceeding.` - ); - } -} - -export class LibraryNotFoundError extends HardhatEtherscanError { - constructor( - contractName: string, - libraryName: string, - allLibraries: string[], - detectableLibraries: string[], - undetectableLibraries: string[] - ) { - const contractLibrariesDetails = `This contract uses the following external libraries: -${undetectableLibraries.map((x) => ` * ${x}`).join("\n")} -${detectableLibraries.map((x) => ` * ${x} (optional)`).join("\n")} -${ - detectableLibraries.length > 0 - ? "Libraries marked as optional don't need to be specified since their addresses are autodetected by the plugin." - : "" -}`; - - super(`You gave an address for the library ${libraryName} in the libraries dictionary, which is not one of the libraries of contract ${contractName}. -${ - allLibraries.length > 0 - ? contractLibrariesDetails - : "This contract doesn't use any external libraries." -}`); - } -} - -export class LibraryMultipleMatchesError extends HardhatEtherscanError { - constructor(contractName: string, libraryName: string, fqnMatches: string[]) { - super(`The library name ${libraryName} is ambiguous for the contract ${contractName}. -It may resolve to one of the following libraries: -${fqnMatches.map((x) => ` * ${x}`).join("\n")} - -To fix this, choose one of these fully qualified library names and replace it in your libraries dictionary.`); - } -} - -export class MissingLibrariesError extends HardhatEtherscanError { - constructor( - contractName: string, - allLibraries: string[], - mergedLibraries: string[], - undetectableLibraries: string[] - ) { - const missingLibraries = allLibraries.filter( - (lib) => !mergedLibraries.some((mergedLib) => lib === mergedLib) - ); - - super(`The contract ${contractName} has one or more library addresses that cannot be detected from deployed bytecode. -This can occur if the library is only called in the contract constructor. The missing libraries are: -${missingLibraries.map((x) => ` * ${x}`).join("\n")} - -${ - missingLibraries.length === undetectableLibraries.length - ? "Visit https://hardhat.org/hardhat-runner/plugins/nomiclabs-hardhat-etherscan#libraries-with-undetectable-addresses to learn how to solve this." - : "To solve this, you can add them to your --libraries dictionary with their corresponding addresses." -}`); - } -} - -export class LibraryAddressesMismatchError extends HardhatEtherscanError { - constructor( - conflicts: Array<{ - library: string; - detectedAddress: string; - inputAddress: string; - }> - ) { - super(`The following detected library addresses are different from the ones provided: -${conflicts - .map( - ({ library, inputAddress, detectedAddress }) => - ` * ${library} -given address: ${inputAddress} -detected address: ${detectedAddress}` - ) - .join("\n")} - -You can either fix these addresses in your libraries dictionary or simply remove them to let the plugin autodetect them.`); - } -} - -export class UnexpectedNumberOfFilesError extends HardhatEtherscanError { - constructor() { - super( - "The plugin found an unexpected number of files for this contract. Please report this issue to the Hardhat team." - ); - } -} - -export class ABIArgumentLengthError extends HardhatEtherscanError { - constructor( - sourceName: string, - contractName: string, - error: ABIArgumentLengthErrorType - ) { - const { types: requiredArgs, values: providedArgs } = error.count; - super( - `The constructor for ${sourceName}:${contractName} has ${requiredArgs} parameters -but ${providedArgs} arguments were provided instead.`, - error - ); - } -} - -export class ABIArgumentTypeError extends HardhatEtherscanError { - constructor(error: ABIArgumentTypeErrorType) { - const { value: argValue, argument: argName, reason } = error; - super( - `Value ${argValue} cannot be encoded for the parameter ${argName}. -Encoder error reason: ${reason}`, - error - ); - } -} - -export class ABIArgumentOverflowError extends HardhatEtherscanError { - constructor(error: ABIArgumentOverflowErrorType) { - const { value: argValue, fault: reason, operation } = error; - super( - `Value ${argValue} is not a safe integer and cannot be encoded. -Use a string instead of a plain number. -Encoder error reason: ${reason} fault in ${operation}`, - error - ); - } -} - -export class VerificationAPIUnexpectedMessageError extends HardhatEtherscanError { - constructor(message: string) { - super(`The API responded with an unexpected message. -Please report this issue to the Hardhat team. -Contract verification may have succeeded and should be checked manually. -Message: ${message}`); - } -} - -export class ContractVerificationFailedError extends HardhatEtherscanError { - constructor(message: string, undetectableLibraries: string[]) { - super(`The contract verification failed. -Reason: ${message} -${ - undetectableLibraries.length > 0 - ? ` -This contract makes use of libraries whose addresses are undetectable by the plugin. -Keep in mind that this verification failure may be due to passing in the wrong -address for one of these libraries: -${undetectableLibraries.map((x) => ` * ${x}`).join("\n")}` - : "" -}`); - } -} diff --git a/packages/hardhat-verify/src/etherscan.ts b/packages/hardhat-verify/src/etherscan.ts index 17cdd8b1c5..c021bc1a93 100644 --- a/packages/hardhat-verify/src/etherscan.ts +++ b/packages/hardhat-verify/src/etherscan.ts @@ -1,219 +1 @@ -import type { Dispatcher } from "undici"; - -import { - ContractStatusPollingError, - ContractStatusPollingInvalidStatusCodeError, - ContractVerificationRequestError, - ContractVerificationMissingBytecodeError, - ContractVerificationInvalidStatusCodeError, - HardhatEtherscanError, - MissingApiKeyError, - ContractStatusPollingResponseNotOkError, -} from "./errors"; -import { sendGetRequest, sendPostRequest } from "./undici"; - -import { ChainConfig, ApiKey } from "./types"; -import { sleep } from "./utilities"; - -interface EtherscanVerifyRequestParams { - address: string; - sourceCode: string; - sourceName: string; - contractName: string; - compilerVersion: string; - encodedConstructorArguments: string; -} - -// Used for polling the result of the contract verification. -const VERIFICATION_STATUS_POLLING_TIME = 3000; - -export class Etherscan { - private _apiKey: string; - private _apiUrl: string; - private _browserUrl: string; - - constructor(apiKey: ApiKey | undefined, chainConfig: ChainConfig) { - this._apiKey = resolveApiKey(apiKey, chainConfig.network); - this._apiUrl = chainConfig.urls.apiURL; - this._browserUrl = chainConfig.urls.browserURL.trim().replace(/\/$/, ""); - } - - // https://docs.etherscan.io/api-endpoints/contracts#get-contract-source-code-for-verified-contract-source-codes - public async isVerified(address: string) { - const parameters = new URLSearchParams({ - apikey: this._apiKey, - module: "contract", - action: "getsourcecode", - address, - }); - - const url = new URL(this._apiUrl); - url.search = parameters.toString(); - - const response = await sendGetRequest(url); - const json = await response.body.json(); - - if (json.message !== "OK") { - return false; - } - - const sourceCode = json?.result?.[0]?.SourceCode; - return sourceCode !== undefined && sourceCode !== ""; - } - - // https://docs.etherscan.io/api-endpoints/contracts#verify-source-code - public async verify({ - address, - sourceCode, - sourceName, - contractName, - compilerVersion, - encodedConstructorArguments, - }: EtherscanVerifyRequestParams): Promise { - const parameters = new URLSearchParams({ - apikey: this._apiKey, - module: "contract", - action: "verifysourcecode", - contractaddress: address, - sourceCode, - codeformat: "solidity-standard-json-input", - contractname: `${sourceName}:${contractName}`, - compilerversion: `v${compilerVersion}`, - constructorArguements: encodedConstructorArguments, - }); - - let response: Dispatcher.ResponseData; - try { - response = await sendPostRequest( - new URL(this._apiUrl), - parameters.toString() - ); - } catch (error: any) { - throw new ContractVerificationRequestError(this._apiUrl, error); - } - - if (!(response.statusCode >= 200 && response.statusCode <= 299)) { - // This could be always interpreted as JSON if there were any such guarantee in the Etherscan API. - const responseText = await response.body.text(); - throw new ContractVerificationInvalidStatusCodeError( - this._apiUrl, - response.statusCode, - responseText - ); - } - - const etherscanResponse = new EtherscanResponse(await response.body.json()); - - if (etherscanResponse.isBytecodeMissingInNetworkError()) { - throw new ContractVerificationMissingBytecodeError(this._apiUrl, address); - } - - if (!etherscanResponse.isOk()) { - throw new HardhatEtherscanError(etherscanResponse.message); - } - - return etherscanResponse; - } - - // https://docs.etherscan.io/api-endpoints/contracts#check-source-code-verification-submission-status - public async getVerificationStatus(guid: string): Promise { - const parameters = new URLSearchParams({ - apikey: this._apiKey, - module: "contract", - action: "checkverifystatus", - guid, - }); - const url = new URL(this._apiUrl); - url.search = parameters.toString(); - - let response; - try { - response = await sendGetRequest(url); - } catch (error: any) { - throw new ContractStatusPollingError(url.toString(), error); - } - - if (!(response.statusCode >= 200 && response.statusCode <= 299)) { - // This could be always interpreted as JSON if there were any such guarantee in the Etherscan API. - const responseText = await response.body.text(); - - throw new ContractStatusPollingInvalidStatusCodeError( - response.statusCode, - responseText - ); - } - - const etherscanResponse = new EtherscanResponse(await response.body.json()); - - if (etherscanResponse.isPending()) { - await sleep(VERIFICATION_STATUS_POLLING_TIME); - - return this.getVerificationStatus(guid); - } - - if (etherscanResponse.isFailure()) { - return etherscanResponse; - } - - if (!etherscanResponse.isOk()) { - throw new ContractStatusPollingResponseNotOkError( - etherscanResponse.message - ); - } - - return etherscanResponse; - } - - public getContractUrl(address: string) { - return `${this._browserUrl}/address/${address}#code`; - } -} - -class EtherscanResponse { - public readonly status: number; - - public readonly message: string; - - constructor(response: any) { - this.status = parseInt(response.status, 10); - this.message = response.result; - } - - public isPending() { - return this.message === "Pending in queue"; - } - - public isFailure() { - return this.message === "Fail - Unable to verify"; - } - - public isSuccess() { - return this.message === "Pass - Verified"; - } - - public isBytecodeMissingInNetworkError() { - return this.message.startsWith("Unable to locate ContractCode at"); - } - - public isOk() { - return this.status === 1; - } -} - -function resolveApiKey(apiKey: ApiKey | undefined, network: string) { - if (apiKey === undefined || apiKey === "") { - throw new MissingApiKeyError(network); - } - - if (typeof apiKey === "string") { - return apiKey; - } - - const key = apiKey[network]; - - if (key === undefined || key === "") { - throw new MissingApiKeyError(network); - } - - return key; -} +export { Etherscan } from "./internal/etherscan"; diff --git a/packages/hardhat-verify/src/index.ts b/packages/hardhat-verify/src/index.ts index 5c78cb59ca..30cdae4e6f 100644 --- a/packages/hardhat-verify/src/index.ts +++ b/packages/hardhat-verify/src/index.ts @@ -1,75 +1,62 @@ -import type LodashCloneDeepT from "lodash.clonedeep"; import type { - CompilationJob, - CompilerInput, - DependencyGraph, -} from "hardhat/types"; + ContractInformation, + ExtendedContractInformation, + LibraryToAddress, +} from "./internal/solc/artifacts"; +import type { Bytecode } from "./internal/solc/bytecode"; +import picocolors from "picocolors"; import { extendConfig, subtask, task, types } from "hardhat/config"; -import { isFullyQualifiedName } from "hardhat/utils/contract-names"; -import { - TASK_COMPILE, - TASK_COMPILE_SOLIDITY_GET_COMPILATION_JOB_FOR_FILE, - TASK_COMPILE_SOLIDITY_GET_COMPILER_INPUT, - TASK_COMPILE_SOLIDITY_GET_DEPENDENCY_GRAPH, -} from "hardhat/builtin-tasks/task-names"; + import { TASK_VERIFY, - TASK_VERIFY_ETHERSCAN_ATTEMPT_VERIFICATION, - TASK_VERIFY_ETHERSCAN_GET_CONTRACT_INFORMATION, - TASK_VERIFY_ETHERSCAN_GET_MINIMAL_INPUT, TASK_VERIFY_GET_VERIFICATION_SUBTASKS, - TASK_VERIFY_RESOLVE_ARGUMENTS, TASK_VERIFY_VERIFY, TASK_VERIFY_ETHERSCAN, -} from "./task-names"; -import { getCurrentChainConfig } from "./chain-config"; -import { etherscanConfigExtender } from "./config"; + TASK_VERIFY_PRINT_SUPPORTED_NETWORKS, + TASK_VERIFY_SOURCIFY, + TASK_VERIFY_SOURCIFY_DISABLED_WARNING, + TASK_VERIFY_GET_CONTRACT_INFORMATION, + TASK_VERIFY_BLOCKSCOUT, +} from "./internal/task-names"; +import { + etherscanConfigExtender, + sourcifyConfigExtender, + blockscoutConfigExtender, +} from "./internal/config"; import { - MissingAddressError, - InvalidAddressError, - InvalidContractNameError, InvalidConstructorArgumentsError, InvalidLibrariesError, - CompilerVersionsMismatchError, + HardhatVerifyError, ContractNotFoundError, BuildInfoNotFoundError, BuildInfoCompilerVersionMismatchError, - DeployedBytecodeDoesNotMatchFQNError, - UnexpectedNumberOfFilesError, - VerificationAPIUnexpectedMessageError, - ContractVerificationFailedError, -} from "./errors"; + DeployedBytecodeMismatchError, +} from "./internal/errors"; import { - sleep, - encodeArguments, - getCompilerVersions, printSupportedNetworks, - resolveConstructorArguments, - resolveLibraries, -} from "./utilities"; -import { Etherscan } from "./etherscan"; -import { Bytecode } from "./solc/bytecode"; + printVerificationErrors, +} from "./internal/utilities"; import { - ContractInformation, - ExtendedContractInformation, - extractInferredContractInformation, extractMatchingContractInformation, + extractInferredContractInformation, getLibraryInformation, - LibraryToAddress, -} from "./solc/artifacts"; +} from "./internal/solc/artifacts"; -import "./type-extensions"; +import "./internal/type-extensions"; +import "./internal/tasks/etherscan"; +import "./internal/tasks/sourcify"; +import "./internal/tasks/blockscout"; // Main task args -interface VerifyTaskArgs { +export interface VerifyTaskArgs { address?: string; constructorArgsParams: string[]; constructorArgs?: string; libraries?: string; contract?: string; + force: boolean; listNetworks: boolean; - noCompile: boolean; } // verify:verify subtask args @@ -78,17 +65,12 @@ interface VerifySubtaskArgs { constructorArguments: string[]; libraries: LibraryToAddress; contract?: string; - noCompile: boolean; + force?: boolean; } -// parsed verification args -interface VerificationArgs { - address: string; - constructorArgs: string[]; - libraries: LibraryToAddress; - contractFQN?: string; - listNetworks: boolean; - noCompile: boolean; +export interface VerificationResponse { + success: boolean; + message: string; } interface GetContractInformationArgs { @@ -98,32 +80,22 @@ interface GetContractInformationArgs { libraries: LibraryToAddress; } -interface GetMinimalInputArgs { - sourceName: string; -} - -interface AttemptVerificationArgs { - address: string; - compilerInput: CompilerInput; - contractInformation: ExtendedContractInformation; - verificationInterface: Etherscan; - encodedConstructorArguments: string; -} - -interface VerificationResponse { - success: boolean; - message: string; +export interface VerificationSubtask { + label: string; + subtaskName: string; } extendConfig(etherscanConfigExtender); +extendConfig(sourcifyConfigExtender); +extendConfig(blockscoutConfigExtender); /** * Main verification task. * * This is a meta-task that gets all the verification tasks and runs them. - * Right now there's only a "verify-etherscan" task. + * It supports Etherscan and Sourcify. */ -task(TASK_VERIFY, "Verifies a contract on Etherscan") +task(TASK_VERIFY, "Verifies a contract on Etherscan or Sourcify") .addOptionalPositionalParam("address", "Address of the contract to verify") .addOptionalVariadicPositionalParam( "constructorArgsParams", @@ -149,218 +121,93 @@ task(TASK_VERIFY, "Verifies a contract on Etherscan") "Fully qualified name of the contract to verify. Skips automatic detection of the contract. " + "Use if the deployed bytecode matches more than one contract in your project" ) + .addFlag( + "force", + "Enforce contract verification even if the contract is already verified. " + + "Use to re-verify partially verified contracts on Blockscout" + ) .addFlag("listNetworks", "Print the list of supported networks") - .addFlag("noCompile", "Don't compile before running the task") .setAction(async (taskArgs: VerifyTaskArgs, { run }) => { - const verificationArgs: VerificationArgs = await run( - TASK_VERIFY_RESOLVE_ARGUMENTS, - taskArgs - ); + if (taskArgs.listNetworks) { + await run(TASK_VERIFY_PRINT_SUPPORTED_NETWORKS); + return; + } - const verificationSubtasks: string[] = await run( + const verificationSubtasks: VerificationSubtask[] = await run( TASK_VERIFY_GET_VERIFICATION_SUBTASKS ); - for (const verificationSubtask of verificationSubtasks) { - await run(verificationSubtask, verificationArgs); - } - }); - -subtask(TASK_VERIFY_RESOLVE_ARGUMENTS) - .addOptionalParam("address") - .addOptionalParam("constructorArgsParams", undefined, [], types.any) - .addOptionalParam("constructorArgs", undefined, undefined, types.inputFile) - .addOptionalParam("libraries", undefined, undefined, types.inputFile) - .addOptionalParam("contract") - .addFlag("listNetworks") - .addFlag("noCompile") - .setAction( - async ({ - address, - constructorArgsParams, - constructorArgs: constructorArgsModule, - contract, - libraries: librariesModule, - listNetworks, - noCompile, - }: VerifyTaskArgs): Promise => { - if (address === undefined) { - throw new MissingAddressError(); - } - - const { isAddress } = await import("@ethersproject/address"); - if (!isAddress(address)) { - throw new InvalidAddressError(address); - } - - if (contract !== undefined && !isFullyQualifiedName(contract)) { - throw new InvalidContractNameError(contract); + const errors: Record = {}; + for (const { label, subtaskName } of verificationSubtasks) { + try { + await run(subtaskName, taskArgs); + } catch (error) { + errors[label] = error as HardhatVerifyError; } + } - const constructorArgs = await resolveConstructorArguments( - constructorArgsParams, - constructorArgsModule - ); - - const libraries = await resolveLibraries(librariesModule); - - return { - address, - constructorArgs, - libraries, - contractFQN: contract, - listNetworks, - noCompile, - }; + const hasErrors = Object.keys(errors).length > 0; + if (hasErrors) { + printVerificationErrors(errors); + process.exit(1); } - ); + }); -/** - * Returns a list of verification subtasks. - */ -subtask(TASK_VERIFY_GET_VERIFICATION_SUBTASKS, async (): Promise => { - return [TASK_VERIFY_ETHERSCAN]; +subtask( + TASK_VERIFY_PRINT_SUPPORTED_NETWORKS, + "Prints the supported networks list" +).setAction(async ({}, { config }) => { + await printSupportedNetworks(config.etherscan.customChains); }); -/** - * Main Etherscan verification subtask. - * - * Verifies a contract in Etherscan by coordinating various subtasks related - * to contract verification. - */ -subtask(TASK_VERIFY_ETHERSCAN) - .addParam("address") - .addParam("constructorArgs", undefined, undefined, types.any) - .addParam("libraries", undefined, undefined, types.any) - .addOptionalParam("contractFQN") - .addFlag("listNetworks") - .addFlag("noCompile") - .setAction( - async ( - { - address, - constructorArgs, - libraries, - contractFQN, - listNetworks, - noCompile, - }: VerificationArgs, - { config, network, run } - ) => { - if (listNetworks) { - await printSupportedNetworks(config.etherscan.customChains); - return; - } - - const chainConfig = await getCurrentChainConfig( - network, - config.etherscan.customChains - ); - - const etherscan = new Etherscan(config.etherscan.apiKey, chainConfig); - - const isVerified = await etherscan.isVerified(address); - if (isVerified) { - const contractURL = etherscan.getContractUrl(address); - console.log(`The contract ${address} has already been verified. -${contractURL}`); - return; - } - - const configCompilerVersions = await getCompilerVersions(config.solidity); - - const deployedBytecode = await Bytecode.getDeployedContractBytecode( - address, - network.provider, - network.name - ); - - const matchingCompilerVersions = - await deployedBytecode.getMatchingVersions(configCompilerVersions); - // don't error if the bytecode appears to be OVM bytecode, because we can't infer a specific OVM solc version from the bytecode - if (matchingCompilerVersions.length === 0 && !deployedBytecode.isOvm()) { - throw new CompilerVersionsMismatchError( - configCompilerVersions, - deployedBytecode.getVersion(), - network.name - ); - } - - // Make sure that contract artifacts are up-to-date - if (!noCompile) { - await run(TASK_COMPILE, { quiet: true }); - } - - const contractInformation: ExtendedContractInformation = await run( - TASK_VERIFY_ETHERSCAN_GET_CONTRACT_INFORMATION, - { - contractFQN, - deployedBytecode, - matchingCompilerVersions, - libraries, - } - ); - - const minimalInput: CompilerInput = await run( - TASK_VERIFY_ETHERSCAN_GET_MINIMAL_INPUT, - { - sourceName: contractInformation.sourceName, - } - ); - - const encodedConstructorArguments = await encodeArguments( - contractInformation.contractOutput.abi, - contractInformation.sourceName, - contractInformation.contractName, - constructorArgs - ); - - // First, try to verify the contract using the minimal input - const { success: minimalInputVerificationSuccess }: VerificationResponse = - await run(TASK_VERIFY_ETHERSCAN_ATTEMPT_VERIFICATION, { - address, - compilerInput: minimalInput, - contractInformation, - verificationInterface: etherscan, - encodedConstructorArguments, - }); +subtask( + TASK_VERIFY_GET_VERIFICATION_SUBTASKS, + async (_, { config, userConfig }): Promise => { + const verificationSubtasks: VerificationSubtask[] = []; - if (minimalInputVerificationSuccess) { - return; - } + if (config.etherscan.enabled) { + verificationSubtasks.push({ + label: "Etherscan", + subtaskName: TASK_VERIFY_ETHERSCAN, + }); + } - console.log(`We tried verifying your contract ${contractInformation.contractName} without including any unrelated one, but it failed. -Trying again with the full solc input used to compile and deploy it. -This means that unrelated contracts may be displayed on Etherscan... -`); - - // If verifying with the minimal input failed, try again with the full compiler input - const { - success: fullCompilerInputVerificationSuccess, - message: verificationMessage, - }: VerificationResponse = await run( - TASK_VERIFY_ETHERSCAN_ATTEMPT_VERIFICATION, - { - address, - compilerInput: contractInformation.compilerInput, - contractInformation, - verificationInterface: etherscan, - encodedConstructorArguments, - } - ); + if (config.sourcify.enabled) { + verificationSubtasks.push({ + label: "Sourcify", + subtaskName: TASK_VERIFY_SOURCIFY, + }); + } else if (userConfig.sourcify?.enabled === undefined) { + verificationSubtasks.unshift({ + label: "Common", + subtaskName: TASK_VERIFY_SOURCIFY_DISABLED_WARNING, + }); + } - if (fullCompilerInputVerificationSuccess) { - return; - } + if (config.blockscout.enabled) { + verificationSubtasks.push({ + label: "Blockscout", + subtaskName: TASK_VERIFY_BLOCKSCOUT, + }); + } - throw new ContractVerificationFailedError( - verificationMessage, - contractInformation.undetectableLibraries + if ( + !config.etherscan.enabled && + !config.sourcify.enabled && + !config.blockscout.enabled + ) { + console.warn( + picocolors.yellow( + `[WARNING] No verification services are enabled. Please enable at least one verification service in your configuration.` + ) ); } - ); -subtask(TASK_VERIFY_ETHERSCAN_GET_CONTRACT_INFORMATION) + return verificationSubtasks; + } +); + +subtask(TASK_VERIFY_GET_CONTRACT_INFORMATION) .addParam("deployedBytecode", undefined, undefined, types.any) .addParam("matchingCompilerVersions", undefined, undefined, types.any) .addParam("libraries", undefined, undefined, types.any) @@ -378,12 +225,7 @@ subtask(TASK_VERIFY_ETHERSCAN_GET_CONTRACT_INFORMATION) let contractInformation: ContractInformation | null; if (contractFQN !== undefined) { - let artifactExists; - try { - artifactExists = await artifacts.artifactExists(contractFQN); - } catch (error) { - artifactExists = false; - } + const artifactExists = await artifacts.artifactExists(contractFQN); if (!artifactExists) { throw new ContractNotFoundError(contractFQN); @@ -414,10 +256,7 @@ subtask(TASK_VERIFY_ETHERSCAN_GET_CONTRACT_INFORMATION) ); if (contractInformation === null) { - throw new DeployedBytecodeDoesNotMatchFQNError( - contractFQN, - network.name - ); + throw new DeployedBytecodeMismatchError(network.name, contractFQN); } } else { contractInformation = await extractInferredContractInformation( @@ -441,108 +280,15 @@ subtask(TASK_VERIFY_ETHERSCAN_GET_CONTRACT_INFORMATION) } ); -subtask(TASK_VERIFY_ETHERSCAN_GET_MINIMAL_INPUT) - .addParam("sourceName") - .setAction(async ({ sourceName }: GetMinimalInputArgs, { run }) => { - const cloneDeep = require("lodash.clonedeep") as typeof LodashCloneDeepT; - const dependencyGraph: DependencyGraph = await run( - TASK_COMPILE_SOLIDITY_GET_DEPENDENCY_GRAPH, - { sourceNames: [sourceName] } - ); - - const resolvedFiles = dependencyGraph - .getResolvedFiles() - .filter((resolvedFile) => resolvedFile.sourceName === sourceName); - - if (resolvedFiles.length !== 1) { - throw new UnexpectedNumberOfFilesError(); - } - - const compilationJob: CompilationJob = await run( - TASK_COMPILE_SOLIDITY_GET_COMPILATION_JOB_FOR_FILE, - { - dependencyGraph, - file: resolvedFiles[0], - } - ); - - const minimalInput: CompilerInput = await run( - TASK_COMPILE_SOLIDITY_GET_COMPILER_INPUT, - { - compilationJob, - } - ); - - return cloneDeep(minimalInput); - }); - -subtask(TASK_VERIFY_ETHERSCAN_ATTEMPT_VERIFICATION) - .addParam("address") - .addParam("compilerInput", undefined, undefined, types.any) - .addParam("contractInformation", undefined, undefined, types.any) - .addParam("verificationInterface", undefined, undefined, types.any) - .addParam("encodedConstructorArguments") - .setAction( - async ({ - address, - compilerInput, - contractInformation, - verificationInterface, - encodedConstructorArguments, - }: AttemptVerificationArgs): Promise => { - // Ensure the linking information is present in the compiler input; - compilerInput.settings.libraries = contractInformation.libraries; - - const { message: guid } = await verificationInterface.verify({ - address, - sourceCode: JSON.stringify(compilerInput), - sourceName: contractInformation.sourceName, - contractName: contractInformation.contractName, - compilerVersion: contractInformation.solcLongVersion, - encodedConstructorArguments, - }); - - console.log(`Successfully submitted source code for contract -${contractInformation.sourceName}:${contractInformation.contractName} at ${address} -for verification on the block explorer. Waiting for verification result... -`); - - // Compilation is bound to take some time so there's no sense in requesting status immediately. - await sleep(700); - const verificationStatus = - await verificationInterface.getVerificationStatus(guid); - - if (!(verificationStatus.isFailure() || verificationStatus.isSuccess())) { - // Reaching this point shouldn't be possible unless the API is behaving in a new way. - throw new VerificationAPIUnexpectedMessageError( - verificationStatus.message - ); - } - - if (verificationStatus.isSuccess()) { - const contractURL = verificationInterface.getContractUrl(address); - console.log(`Successfully verified contract ${contractInformation.contractName} on Etherscan. -${contractURL}`); - } - - return { - success: verificationStatus.isSuccess(), - message: verificationStatus.message, - }; - } - ); - /** - * This subtask is used for backwards compatibility. - * It validates the parameters as it is done in TASK_VERIFY_RESOLVE_ARGUMENTS - * and calls TASK_VERIFY_ETHERSCAN directly. + * This subtask is used to programmatically verify a contract on Etherscan or Sourcify. */ subtask(TASK_VERIFY_VERIFY) .addOptionalParam("address") .addOptionalParam("constructorArguments", undefined, [], types.any) .addOptionalParam("libraries", undefined, {}, types.any) .addOptionalParam("contract") - .addFlag("noCompile") + .addFlag("force") .setAction( async ( { @@ -550,23 +296,10 @@ subtask(TASK_VERIFY_VERIFY) constructorArguments, libraries, contract, - noCompile, + force, }: VerifySubtaskArgs, - { run } + { run, config } ) => { - if (address === undefined) { - throw new MissingAddressError(); - } - - const { isAddress } = await import("@ethersproject/address"); - if (!isAddress(address)) { - throw new InvalidAddressError(address); - } - - if (contract !== undefined && !isFullyQualifiedName(contract)) { - throw new InvalidContractNameError(contract); - } - // This can only happen if the subtask is invoked from within Hardhat by a user script or another task. if (!Array.isArray(constructorArguments)) { throw new InvalidConstructorArgumentsError(); @@ -576,12 +309,22 @@ subtask(TASK_VERIFY_VERIFY) throw new InvalidLibrariesError(); } - await run(TASK_VERIFY_ETHERSCAN, { - address, - constructorArgs: constructorArguments, - libraries, - contractFQN: contract, - noCompile, - }); + if (config.etherscan.enabled) { + await run(TASK_VERIFY_ETHERSCAN, { + address, + constructorArgsParams: constructorArguments, + libraries, + contract, + force, + }); + } + + if (config.sourcify.enabled) { + await run(TASK_VERIFY_SOURCIFY, { + address, + libraries, + contract, + }); + } } ); diff --git a/packages/hardhat-verify/src/abi-validation-extras.ts b/packages/hardhat-verify/src/internal/abi-validation-extras.ts similarity index 100% rename from packages/hardhat-verify/src/abi-validation-extras.ts rename to packages/hardhat-verify/src/internal/abi-validation-extras.ts diff --git a/packages/hardhat-verify/src/internal/blockscout.chain-config.ts b/packages/hardhat-verify/src/internal/blockscout.chain-config.ts new file mode 100644 index 0000000000..f72250c6cc --- /dev/null +++ b/packages/hardhat-verify/src/internal/blockscout.chain-config.ts @@ -0,0 +1,21 @@ +import type { ChainConfig } from "../types"; + +// See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md#list-of-chain-ids +export const builtinChains: ChainConfig[] = [ + { + network: "mainnet", + chainId: 1, + urls: { + apiURL: "https://eth.blockscout.com/api", + browserURL: "https://eth.blockscout.com/", + }, + }, + { + network: "sepolia", + chainId: 11155111, + urls: { + apiURL: "https://eth-sepolia.blockscout.com/api", + browserURL: "https://eth-sepolia.blockscout.com/", + }, + }, +]; diff --git a/packages/hardhat-verify/src/internal/blockscout.ts b/packages/hardhat-verify/src/internal/blockscout.ts new file mode 100644 index 0000000000..9380e7b0e9 --- /dev/null +++ b/packages/hardhat-verify/src/internal/blockscout.ts @@ -0,0 +1,175 @@ +import type { EthereumProvider } from "hardhat/types"; +import type { ChainConfig } from "../types"; + +import { HARDHAT_NETWORK_NAME } from "hardhat/plugins"; + +import { + ChainConfigNotFoundError, + HardhatNetworkNotSupportedError, +} from "./errors"; +import { ValidationResponse } from "./utilities"; +import { builtinChains } from "./blockscout.chain-config"; + +import { Etherscan } from "./etherscan"; + +/** + * Blockscout verification provider for verifying smart contracts. + */ +export class Blockscout { + private _etherscan: Etherscan; + + /** + * Create a new instance of the Blockscout verification provider. + * @param apiUrl - The Blockscout API URL, e.g. https://eth.blockscout.com/api. + * @param browserUrl - The Blockscout browser URL, e.g. https://eth.blockscout.com. + */ + constructor(public apiUrl: string, public browserUrl: string) { + this._etherscan = new Etherscan("api_key", apiUrl, browserUrl); + } + + public static async getCurrentChainConfig( + networkName: string, + ethereumProvider: EthereumProvider, + customChains: ChainConfig[] + ): Promise { + const currentChainId = parseInt( + await ethereumProvider.send("eth_chainId"), + 16 + ); + + const currentChainConfig = [ + // custom chains has higher precedence than builtin chains + ...[...customChains].reverse(), // the last entry has higher precedence + ...builtinChains, + ].find(({ chainId }) => chainId === currentChainId); + + if (currentChainConfig === undefined) { + if (networkName === HARDHAT_NETWORK_NAME) { + throw new HardhatNetworkNotSupportedError(); + } + + throw new ChainConfigNotFoundError(currentChainId); + } + + return currentChainConfig; + } + + public static fromChainConfig(chainConfig: ChainConfig): Blockscout { + const apiUrl = chainConfig.urls.apiURL; + const browserUrl = chainConfig.urls.browserURL.trim().replace(/\/$/, ""); + + return new Blockscout(apiUrl, browserUrl); + } + + /** + * Check if a smart contract is verified on Blockscout. + * @link https://docs.blockscout.com/for-users/api/rpc-endpoints/contract#get-contract-source-code-for-a-verified-contract + * @param address - The address of the smart contract. + * @returns True if the contract is verified, false otherwise. + * @throws {NetworkRequestError} if there is an error on the request. + * @throws {ContractVerificationInvalidStatusCodeError} if the API returns an invalid status code. + */ + public async isVerified(address: string): Promise { + return this._etherscan.isVerified(address); + } + + /** + * Verify a smart contract on Blockscout. + * @link https://docs.blockscout.com/for-users/api/rpc-endpoints/contract#verify-a-contract-with-standard-input-json-file + * @param contractAddress - The address of the smart contract to verify. + * @param sourceCode - The source code of the smart contract. + * @param contractName - The name of the smart contract, e.g. "contracts/Sample.sol:MyContract" + * @param compilerVersion - The version of the Solidity compiler used, e.g. `v0.8.19+commit.7dd6d404` + * @returns A promise that resolves to an `BlockscoutResponse` object. + * @throws {NetworkRequestError} if there is an error on the request. + * @throws {ContractVerificationInvalidStatusCodeError} if the API returns an invalid status code. + * @throws {ContractVerificationMissingBytecodeError} if the bytecode is not found on the block explorer. + * @throws {ContractAlreadyVerifiedError} if the contract is already verified. + * @throws {HardhatVerifyError} if the response status is not OK. + */ + public async verify( + contractAddress: string, + sourceCode: string, + contractName: string, + compilerVersion: string + ): Promise { + const etherscanResponse = await this._etherscan.verify( + contractAddress, + sourceCode, + contractName, + compilerVersion, + "" + ); + + return new BlockscoutResponse( + etherscanResponse.status, + etherscanResponse.message + ); + } + + /** + * Get the verification status of a smart contract from Blockscout. + * This method performs polling of the verification status if it's pending. + * @link https://docs.blockscout.com/for-users/api/rpc-endpoints/contract#return-status-of-a-verification-attempt + * @param guid - The verification GUID to check. + * @returns A promise that resolves to an `BlockscoutResponse` object. + * @throws {NetworkRequestError} if there is an error on the request. + * @throws {ContractStatusPollingInvalidStatusCodeError} if the API returns an invalid status code. + * @throws {ContractStatusPollingResponseNotOkError} if the response status is not OK. + */ + public async getVerificationStatus( + guid: string + ): Promise { + const etherscanResponse = await this._etherscan.getVerificationStatus(guid); + + return new BlockscoutResponse( + etherscanResponse.status, + etherscanResponse.message + ); + } + + /** + * Get the Blockscout URL for viewing a contract's details. + * @param address - The address of the smart contract. + * @returns The URL to view the contract on Blockscout's website. + */ + public getContractUrl(address: string): string { + return `${this.browserUrl}/address/${address}#code`; + } +} + +class BlockscoutResponse implements ValidationResponse { + public readonly status: number; + public readonly message: string; + + constructor(status: number, message: string) { + this.status = status; + this.message = message; + } + + public isPending() { + return this.message === "Pending in queue"; + } + + public isFailure() { + return this.message === "Fail - Unable to verify"; + } + + public isSuccess() { + return this.message === "Pass - Verified"; + } + + public isAlreadyVerified() { + return ( + // returned by blockscout + this.message.startsWith("Smart-contract already verified") || + // returned by etherscan + this.message.startsWith("Contract source code already verified") || + this.message.startsWith("Already Verified") + ); + } + + public isOk() { + return this.status === 1; + } +} diff --git a/packages/hardhat-verify/src/internal/chain-config.ts b/packages/hardhat-verify/src/internal/chain-config.ts new file mode 100644 index 0000000000..b483fe9a65 --- /dev/null +++ b/packages/hardhat-verify/src/internal/chain-config.ts @@ -0,0 +1,304 @@ +import type { ChainConfig } from "../types"; + +// See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-155.md#list-of-chain-ids +export const builtinChains: ChainConfig[] = [ + { + network: "mainnet", + chainId: 1, + urls: { + apiURL: "https://api.etherscan.io/api", + browserURL: "https://etherscan.io", + }, + }, + { + network: "goerli", + chainId: 5, + urls: { + apiURL: "https://api-goerli.etherscan.io/api", + browserURL: "https://goerli.etherscan.io", + }, + }, + { + network: "optimisticEthereum", + chainId: 10, + urls: { + apiURL: "https://api-optimistic.etherscan.io/api", + browserURL: "https://optimistic.etherscan.io/", + }, + }, + { + network: "bsc", + chainId: 56, + urls: { + apiURL: "https://api.bscscan.com/api", + browserURL: "https://bscscan.com", + }, + }, + { + network: "sokol", + chainId: 77, + urls: { + apiURL: "https://blockscout.com/poa/sokol/api", + browserURL: "https://blockscout.com/poa/sokol", + }, + }, + { + network: "bscTestnet", + chainId: 97, + urls: { + apiURL: "https://api-testnet.bscscan.com/api", + browserURL: "https://testnet.bscscan.com", + }, + }, + { + network: "xdai", + chainId: 100, + urls: { + apiURL: "https://api.gnosisscan.io/api", + browserURL: "https://gnosisscan.io", + }, + }, + { + network: "gnosis", + chainId: 100, + urls: { + apiURL: "https://api.gnosisscan.io/api", + browserURL: "https://gnosisscan.io", + }, + }, + { + network: "heco", + chainId: 128, + urls: { + apiURL: "https://api.hecoinfo.com/api", + browserURL: "https://hecoinfo.com", + }, + }, + { + network: "polygon", + chainId: 137, + urls: { + apiURL: "https://api.polygonscan.com/api", + browserURL: "https://polygonscan.com", + }, + }, + { + network: "opera", + chainId: 250, + urls: { + apiURL: "https://api.ftmscan.com/api", + browserURL: "https://ftmscan.com", + }, + }, + { + network: "hecoTestnet", + chainId: 256, + urls: { + apiURL: "https://api-testnet.hecoinfo.com/api", + browserURL: "https://testnet.hecoinfo.com", + }, + }, + { + network: "optimisticGoerli", + chainId: 420, + urls: { + apiURL: "https://api-goerli-optimism.etherscan.io/api", + browserURL: "https://goerli-optimism.etherscan.io/", + }, + }, + { + network: "polygonZkEVM", + chainId: 1101, + urls: { + apiURL: "https://api-zkevm.polygonscan.com/api", + browserURL: "https://zkevm.polygonscan.com", + }, + }, + { + network: "moonbeam", + chainId: 1284, + urls: { + apiURL: "https://api-moonbeam.moonscan.io/api", + browserURL: "https://moonbeam.moonscan.io", + }, + }, + { + network: "moonriver", + chainId: 1285, + urls: { + apiURL: "https://api-moonriver.moonscan.io/api", + browserURL: "https://moonriver.moonscan.io", + }, + }, + { + network: "moonbaseAlpha", + chainId: 1287, + urls: { + apiURL: "https://api-moonbase.moonscan.io/api", + browserURL: "https://moonbase.moonscan.io/", + }, + }, + { + network: "polygonZkEVMTestnet", + chainId: 2442, + urls: { + apiURL: "https://api-cardona-zkevm.polygonscan.com/api", + browserURL: "https://cardona-zkevm.polygonscan.com", + }, + }, + { + network: "ftmTestnet", + chainId: 4002, + urls: { + apiURL: "https://api-testnet.ftmscan.com/api", + browserURL: "https://testnet.ftmscan.com", + }, + }, + { + network: "base", + chainId: 8453, + urls: { + apiURL: "https://api.basescan.org/api", + browserURL: "https://basescan.org/", + }, + }, + { + network: "chiado", + chainId: 10200, + urls: { + apiURL: "https://gnosis-chiado.blockscout.com/api", + browserURL: "https://gnosis-chiado.blockscout.com", + }, + }, + { + network: "holesky", + chainId: 17000, + urls: { + apiURL: "https://api-holesky.etherscan.io/api", + browserURL: "https://holesky.etherscan.io", + }, + }, + { + network: "arbitrumOne", + chainId: 42161, + urls: { + apiURL: "https://api.arbiscan.io/api", + browserURL: "https://arbiscan.io/", + }, + }, + { + network: "avalancheFujiTestnet", + chainId: 43113, + urls: { + apiURL: "https://api-testnet.snowtrace.io/api", + browserURL: "https://testnet.snowtrace.io/", + }, + }, + { + network: "avalanche", + chainId: 43114, + urls: { + apiURL: "https://api.snowtrace.io/api", + browserURL: "https://snowtrace.io/", + }, + }, + { + network: "ink", + chainId: 57073, + urls: { + apiURL: "https://explorer.inkonchain.com/api/v2", + browserURL: "https://explorer.inkonchain.com/", + }, + }, + { + network: "polygonMumbai", + chainId: 80001, + urls: { + apiURL: "https://api-testnet.polygonscan.com/api", + browserURL: "https://mumbai.polygonscan.com/", + }, + }, + { + network: "polygonAmoy", + chainId: 80002, + urls: { + apiURL: "https://api-amoy.polygonscan.com/api", + browserURL: "https://amoy.polygonscan.com/", + }, + }, + { + network: "baseGoerli", + chainId: 84531, + urls: { + apiURL: "https://api-goerli.basescan.org/api", + browserURL: "https://goerli.basescan.org/", + }, + }, + { + network: "baseSepolia", + chainId: 84532, + urls: { + apiURL: "https://api-sepolia.basescan.org/api", + browserURL: "https://sepolia.basescan.org/", + }, + }, + { + network: "arbitrumSepolia", + chainId: 421614, + urls: { + apiURL: "https://api-sepolia.arbiscan.io/api", + browserURL: "https://sepolia.arbiscan.io/", + }, + }, + { + network: "inkSepolia", + chainId: 763373, + urls: { + apiURL: "https://explorer-sepolia.inkonchain.com/api/v2", + browserURL: "https://explorer-sepolia.inkonchain.com/", + }, + }, + { + network: "sepolia", + chainId: 11155111, + urls: { + apiURL: "https://api-sepolia.etherscan.io/api", + browserURL: "https://sepolia.etherscan.io", + }, + }, + { + network: "aurora", + chainId: 1313161554, + urls: { + apiURL: "https://explorer.mainnet.aurora.dev/api", + browserURL: "https://explorer.mainnet.aurora.dev", + }, + }, + { + network: "auroraTestnet", + chainId: 1313161555, + urls: { + apiURL: "https://explorer.testnet.aurora.dev/api", + browserURL: "https://explorer.testnet.aurora.dev", + }, + }, + { + network: "harmony", + chainId: 1666600000, + urls: { + apiURL: "https://ctrver.t.hmny.io/verify", + browserURL: "https://explorer.harmony.one", + }, + }, + { + network: "harmonyTest", + chainId: 1666700000, + urls: { + apiURL: "https://ctrver.t.hmny.io/verify?network=testnet", + browserURL: "https://explorer.pops.one", + }, + }, + // We are not adding new networks to the core of hardhat-verify anymore. + // Please read this to learn how to manually add support for custom networks: + // https://github.com/NomicFoundation/hardhat/tree/main/packages/hardhat-verify#adding-support-for-other-networks +]; diff --git a/packages/hardhat-verify/src/internal/config.ts b/packages/hardhat-verify/src/internal/config.ts new file mode 100644 index 0000000000..21f0b7cd93 --- /dev/null +++ b/packages/hardhat-verify/src/internal/config.ts @@ -0,0 +1,63 @@ +import type LodashCloneDeepT from "lodash.clonedeep"; +import type { HardhatConfig, HardhatUserConfig } from "hardhat/types"; +import type { + EtherscanConfig, + SourcifyConfig, + BlockscoutConfig, +} from "../types"; + +import picocolors from "picocolors"; + +export function etherscanConfigExtender( + config: HardhatConfig, + userConfig: Readonly +): void { + const defaultEtherscanConfig: EtherscanConfig = { + apiKey: "", + customChains: [], + enabled: true, + }; + const cloneDeep = require("lodash.clonedeep") as typeof LodashCloneDeepT; + const userEtherscanConfig = cloneDeep(userConfig.etherscan); + config.etherscan = { ...defaultEtherscanConfig, ...userEtherscanConfig }; + + // check that there is no etherscan entry in the networks object, since + // this is a common mistake made by users + if ( + userConfig.etherscan === undefined && + config.networks?.etherscan !== undefined + ) { + console.warn( + picocolors.yellow( + "WARNING: you have an 'etherscan' entry in your networks configuration. This is likely a mistake. The etherscan configuration should be at the root of the configuration, not within the networks object." + ) + ); + } +} + +export function sourcifyConfigExtender( + config: HardhatConfig, + userConfig: Readonly +): void { + const defaultSourcifyConfig: SourcifyConfig = { + enabled: false, + apiUrl: "https://sourcify.dev/server", + browserUrl: "https://repo.sourcify.dev", + }; + const cloneDeep = require("lodash.clonedeep") as typeof LodashCloneDeepT; + const userSourcifyConfig = cloneDeep(userConfig.sourcify); + config.sourcify = { ...defaultSourcifyConfig, ...userSourcifyConfig }; +} + +export function blockscoutConfigExtender( + config: HardhatConfig, + userConfig: Readonly +): void { + const defaultBlockscoutConfig: BlockscoutConfig = { + enabled: false, + customChains: [], + }; + const cloneDeep = require("lodash.clonedeep") as typeof LodashCloneDeepT; + const userBlockscoutConfig = cloneDeep(userConfig.blockscout); + config.blockscout = { ...defaultBlockscoutConfig, ...userBlockscoutConfig }; +} diff --git a/packages/hardhat-verify/src/internal/errors.ts b/packages/hardhat-verify/src/internal/errors.ts new file mode 100644 index 0000000000..66a3b2fb5a --- /dev/null +++ b/packages/hardhat-verify/src/internal/errors.ts @@ -0,0 +1,467 @@ +import { NomicLabsHardhatPluginError } from "hardhat/plugins"; +import { + ABIArgumentLengthErrorType, + ABIArgumentOverflowErrorType, + ABIArgumentTypeErrorType, +} from "./abi-validation-extras"; +import { TASK_VERIFY_VERIFY } from "./task-names"; + +export class HardhatVerifyError extends NomicLabsHardhatPluginError { + constructor(message: string, parent?: Error) { + super("@nomicfoundation/hardhat-verify", message, parent); + Object.setPrototypeOf(this, this.constructor.prototype); + } +} + +export class MissingAddressError extends HardhatVerifyError { + constructor() { + super( + "You didn’t provide any address. Please re-run the 'verify' task with the address of the contract you want to verify." + ); + } +} + +export class InvalidAddressError extends HardhatVerifyError { + constructor(address: string) { + super(`${address} is an invalid address.`); + } +} + +export class InvalidContractNameError extends HardhatVerifyError { + constructor(contractName: string) { + super(`A valid fully qualified name was expected. Fully qualified names look like this: "contracts/AContract.sol:TheContract" +Instead, this name was received: ${contractName}`); + } +} + +export class MissingApiKeyError extends HardhatVerifyError { + constructor(network: string) { + super(`You are trying to verify a contract in '${network}', but no API token was found for this network. Please provide one in your hardhat config. For example: + +{ + ... + etherscan: { + apiKey: { + ${network}: 'your API key' + } + } +} + +See https://etherscan.io/apis`); + } +} + +export class InvalidConstructorArgumentsError extends HardhatVerifyError { + constructor() { + super(`The constructorArguments parameter should be an array. +If your constructor has no arguments pass an empty array. E.g: + + await run("${TASK_VERIFY_VERIFY}", { + , + constructorArguments: [] + };`); + } +} + +export class ExclusiveConstructorArgumentsError extends HardhatVerifyError { + constructor() { + super( + "The parameters constructorArgsParams and constructorArgsModule are exclusive. Please provide only one of them." + ); + } +} + +export class InvalidConstructorArgumentsModuleError extends HardhatVerifyError { + constructor(constructorArgsModulePath: string) { + super(`The module ${constructorArgsModulePath} doesn't export a list. The module should look like this: + +module.exports = [ arg1, arg2, ... ];`); + } +} + +export class InvalidLibrariesError extends HardhatVerifyError { + constructor() { + super(`The libraries parameter should be a dictionary. +If your contract does not have undetectable libraries pass an empty object or omit the argument. E.g: + + await run("${TASK_VERIFY_VERIFY}", { + , + libraries: {} + };`); + } +} + +export class InvalidLibrariesModuleError extends HardhatVerifyError { + constructor(librariesModulePath: string) { + super(`The module ${librariesModulePath} doesn't export a dictionary. The module should look like this: + +module.exports = { lib1: "0x...", lib2: "0x...", ... };`); + } +} + +export class ImportingModuleError extends HardhatVerifyError { + constructor(module: string, parent: Error) { + super( + `Importing the module for the ${module} failed. +Reason: ${parent.message}`, + parent + ); + } +} + +export class HardhatNetworkNotSupportedError extends HardhatVerifyError { + constructor() { + super( + `The selected network is "hardhat", which is not supported for contract verification. + +If you intended to use a different network, ensure that you provide the --network parameter when running the command. + +For example: npx hardhat verify --network ` + ); + } +} + +export class ChainConfigNotFoundError extends HardhatVerifyError { + constructor(chainId: number) { + super(`Trying to verify a contract in a network with chain id ${chainId}, but the plugin doesn't recognize it as a supported chain. + +You can manually add support for it by following these instructions: https://hardhat.org/verify-custom-networks + +To see the list of supported networks, run this command: + + npx hardhat verify --list-networks`); + } +} + +export class ContractVerificationInvalidStatusCodeError extends HardhatVerifyError { + constructor(url: string, statusCode: number, responseText: string) { + super(`Failed to send contract verification request. +Endpoint URL: ${url} +The HTTP server response is not ok. Status code: ${statusCode} Response text: ${responseText}`); + } +} + +export class ContractVerificationMissingBytecodeError extends HardhatVerifyError { + constructor(url: string, contractAddress: string) { + super(`Failed to send contract verification request. +Endpoint URL: ${url} +Reason: The Etherscan API responded that the address ${contractAddress} does not have bytecode. +This can happen if the contract was recently deployed and this fact hasn't propagated to the backend yet. +Try waiting for a minute before verifying your contract. If you are invoking this from a script, +try to wait for five confirmations of your contract deployment transaction before running the verification subtask.`); + } +} + +export class ContractStatusPollingInvalidStatusCodeError extends HardhatVerifyError { + constructor(statusCode: number, responseText: string) { + super( + `The HTTP server response is not ok. Status code: ${statusCode} Response text: ${responseText}` + ); + } +} + +export class ContractStatusPollingResponseNotOkError extends HardhatVerifyError { + constructor(message: string) { + super(`The Etherscan API responded with a failure status. +The verification may still succeed but should be checked manually. +Reason: ${message}`); + } +} + +export class EtherscanVersionNotSupportedError extends HardhatVerifyError { + constructor() { + super(`Etherscan only supports compiler versions 0.4.11 and higher. +See https://etherscan.io/solcversions for more information.`); + } +} + +export class DeployedBytecodeNotFoundError extends HardhatVerifyError { + constructor(address: string, network: string) { + super(`The address ${address} has no bytecode. Is the contract deployed to this network? +The selected network is ${network}.`); + } +} + +export class CompilerVersionsMismatchError extends HardhatVerifyError { + constructor( + configCompilerVersions: string[], + inferredCompilerVersion: string, + network: string + ) { + const versionDetails = + configCompilerVersions.length > 1 + ? `versions are: ${configCompilerVersions.join(", ")}` + : `version is: ${configCompilerVersions[0]}`; + + super(`The contract you want to verify was compiled with solidity ${inferredCompilerVersion}, but your configured compiler ${versionDetails}. + +Possible causes are: +- You are not in the same commit that was used to deploy the contract. +- Wrong compiler version selected in hardhat config. +- The given address is wrong. +- The selected network (${network}) is wrong.`); + } +} + +export class ContractNotFoundError extends HardhatVerifyError { + constructor(contractFQN: string) { + super(`The contract ${contractFQN} is not present in your project.`); + } +} + +export class BuildInfoNotFoundError extends HardhatVerifyError { + constructor(contractFQN: string) { + super(`The contract ${contractFQN} is present in your project, but we couldn't find its sources. +Please make sure that it has been compiled by Hardhat and that it is written in Solidity.`); + } +} + +export class BuildInfoCompilerVersionMismatchError extends HardhatVerifyError { + constructor( + contractFQN: string, + compilerVersion: string, + isVersionRange: boolean, + buildInfoCompilerVersion: string, + network: string + ) { + const versionDetails = isVersionRange + ? `a solidity version in the range ${compilerVersion}` + : `the solidity version ${compilerVersion}`; + + super(`The contract ${contractFQN} is being compiled with ${buildInfoCompilerVersion}. +However, the contract found in the address provided as argument has its bytecode marked with ${versionDetails}. + +Possible causes are: +- Solidity compiler version settings were modified after the deployment was executed. +- The given address is wrong. +- The selected network (${network}) is wrong.`); + } +} + +export class DeployedBytecodeMismatchError extends HardhatVerifyError { + constructor(network: string, contractFQN?: string) { + const contractDetails = + typeof contractFQN === "string" + ? `the contract ${contractFQN}.` + : `any of your local contracts.`; + super(`The address provided as argument contains a contract, but its bytecode doesn't match ${contractDetails} + +Possible causes are: + - The artifact for that contract is outdated or missing. You can try compiling the project again with the --force flag before re-running the verification. + - The contract's code changed after the deployment was executed. Sometimes this happens by changes in seemingly unrelated contracts. + - The solidity compiler settings were modified after the deployment was executed (like the optimizer, target EVM, etc.) + - The given address is wrong. + - The selected network (${network}) is wrong.`); + } +} + +export class DeployedBytecodeMultipleMatchesError extends HardhatVerifyError { + constructor(fqnMatches: string[]) { + super(`More than one contract was found to match the deployed bytecode. +Please use the contract parameter with one of the following contracts: +${fqnMatches.map((x) => ` * ${x}`).join("\n")} + +For example: + +hardhat verify --contract contracts/Example.sol:ExampleContract + +If you are running the verify subtask from within Hardhat instead: + +await run("${TASK_VERIFY_VERIFY}", { +, +contract: "contracts/Example.sol:ExampleContract" +};`); + } +} + +export class InvalidLibraryAddressError extends HardhatVerifyError { + constructor( + contractName: string, + libraryName: string, + libraryAddress: string + ) { + super( + `You gave a link for the contract ${contractName} with the library ${libraryName}, but provided this invalid address: ${libraryAddress}` + ); + } +} + +export class DuplicatedLibraryError extends HardhatVerifyError { + constructor(libraryName: string, libraryFQN: string) { + super( + `The library names ${libraryName} and ${libraryFQN} refer to the same library and were given as two entries in the libraries dictionary. +Remove one of them and review your libraries dictionary before proceeding.` + ); + } +} + +export class LibraryNotFoundError extends HardhatVerifyError { + constructor( + contractName: string, + libraryName: string, + allLibraries: string[], + detectableLibraries: string[], + undetectableLibraries: string[] + ) { + const contractLibrariesDetails = `This contract uses the following external libraries: +${undetectableLibraries.map((x) => ` * ${x}`).join("\n")} +${detectableLibraries.map((x) => ` * ${x} (optional)`).join("\n")} +${ + detectableLibraries.length > 0 + ? "Libraries marked as optional don't need to be specified since their addresses are autodetected by the plugin." + : "" +}`; + + super(`You gave an address for the library ${libraryName} in the libraries dictionary, which is not one of the libraries of contract ${contractName}. +${ + allLibraries.length > 0 + ? contractLibrariesDetails + : "This contract doesn't use any external libraries." +}`); + } +} + +export class LibraryMultipleMatchesError extends HardhatVerifyError { + constructor(contractName: string, libraryName: string, fqnMatches: string[]) { + super(`The library name ${libraryName} is ambiguous for the contract ${contractName}. +It may resolve to one of the following libraries: +${fqnMatches.map((x) => ` * ${x}`).join("\n")} + +To fix this, choose one of these fully qualified library names and replace it in your libraries dictionary.`); + } +} + +export class MissingLibrariesError extends HardhatVerifyError { + constructor( + contractName: string, + allLibraries: string[], + mergedLibraries: string[], + undetectableLibraries: string[] + ) { + const missingLibraries = allLibraries.filter( + (lib) => !mergedLibraries.some((mergedLib) => lib === mergedLib) + ); + + super(`The contract ${contractName} has one or more library addresses that cannot be detected from deployed bytecode. +This can occur if the library is only called in the contract constructor. The missing libraries are: +${missingLibraries.map((x) => ` * ${x}`).join("\n")} + +${ + missingLibraries.length === undetectableLibraries.length + ? "Visit https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-verify#libraries-with-undetectable-addresses to learn how to solve this." + : "To solve this, you can add them to your --libraries dictionary with their corresponding addresses." +}`); + } +} + +export class LibraryAddressesMismatchError extends HardhatVerifyError { + constructor( + conflicts: Array<{ + library: string; + detectedAddress: string; + inputAddress: string; + }> + ) { + super(`The following detected library addresses are different from the ones provided: +${conflicts + .map( + ({ library, inputAddress, detectedAddress }) => + ` * ${library} +given address: ${inputAddress} +detected address: ${detectedAddress}` + ) + .join("\n")} + +You can either fix these addresses in your libraries dictionary or simply remove them to let the plugin autodetect them.`); + } +} + +export class UnexpectedNumberOfFilesError extends HardhatVerifyError { + constructor() { + super( + "The plugin found an unexpected number of files for this contract. Please report this issue to the Hardhat team." + ); + } +} + +export class ABIArgumentLengthError extends HardhatVerifyError { + constructor( + sourceName: string, + contractName: string, + error: ABIArgumentLengthErrorType + ) { + const { types: requiredArgs, values: providedArgs } = error.count; + super( + `The constructor for ${sourceName}:${contractName} has ${requiredArgs} parameters +but ${providedArgs} arguments were provided instead.`, + error + ); + } +} + +export class ABIArgumentTypeError extends HardhatVerifyError { + constructor(error: ABIArgumentTypeErrorType) { + const { value: argValue, argument: argName, reason } = error; + super( + `Value ${argValue} cannot be encoded for the parameter ${argName}. +Encoder error reason: ${reason}`, + error + ); + } +} + +export class ABIArgumentOverflowError extends HardhatVerifyError { + constructor(error: ABIArgumentOverflowErrorType) { + const { value: argValue, fault: reason, operation } = error; + super( + `Value ${argValue} is not a safe integer and cannot be encoded. +Use a string instead of a plain number. +Encoder error reason: ${reason} fault in ${operation}`, + error + ); + } +} + +/** + * `VerificationAPIUnexpectedMessageError` is thrown when the block explorer API + * does not behave as expected, such as when it returns an unexpected response message. + */ +export class VerificationAPIUnexpectedMessageError extends HardhatVerifyError { + constructor(message: string) { + super(`The API responded with an unexpected message. +Contract verification may have succeeded and should be checked manually. +Message: ${message}`); + } +} + +export class NetworkRequestError extends HardhatVerifyError { + constructor(e: Error) { + super( + `A network request failed. This is an error from the block explorer, not Hardhat. Error: ${e.message}` + ); + } +} + +export class ContractVerificationFailedError extends HardhatVerifyError { + constructor(message: string, undetectableLibraries: string[]) { + super(`The contract verification failed. +Reason: ${message} +${ + undetectableLibraries.length > 0 + ? ` +This contract makes use of libraries whose addresses are undetectable by the plugin. +Keep in mind that this verification failure may be due to passing in the wrong +address for one of these libraries: +${undetectableLibraries.map((x) => ` * ${x}`).join("\n")}` + : "" +}`); + } +} + +export class ContractAlreadyVerifiedError extends HardhatVerifyError { + constructor(contractFQN: string, contractAddress: string) { + super(`The block explorer's API responded that the contract ${contractFQN} at ${contractAddress} is already verified. +This can happen if you used the '--force' flag. However, re-verification of contracts might not be supported +by the explorer (e.g., Etherscan), or the contract may have already been verified with a full match.`); + } +} diff --git a/packages/hardhat-verify/src/internal/etherscan.ts b/packages/hardhat-verify/src/internal/etherscan.ts new file mode 100644 index 0000000000..45cf7b1ca0 --- /dev/null +++ b/packages/hardhat-verify/src/internal/etherscan.ts @@ -0,0 +1,330 @@ +import type { Dispatcher } from "undici/types"; +import type { EthereumProvider } from "hardhat/types"; +import type { ChainConfig, ApiKey } from "../types"; +import type { + EtherscanGetSourceCodeResponse, + EtherscanVerifyResponse, +} from "./etherscan.types"; + +import { HARDHAT_NETWORK_NAME } from "hardhat/plugins"; + +import { + ContractStatusPollingInvalidStatusCodeError, + ContractVerificationMissingBytecodeError, + ContractVerificationInvalidStatusCodeError, + ContractAlreadyVerifiedError, + HardhatVerifyError, + MissingApiKeyError, + ContractStatusPollingResponseNotOkError, + ChainConfigNotFoundError, + HardhatNetworkNotSupportedError, + NetworkRequestError, +} from "./errors"; +import { isSuccessStatusCode, sendGetRequest, sendPostRequest } from "./undici"; +import { ValidationResponse, sleep } from "./utilities"; +import { builtinChains } from "./chain-config"; + +// Used for polling the result of the contract verification. +const VERIFICATION_STATUS_POLLING_TIME = 3000; + +/** + * Etherscan verification provider for verifying smart contracts. + * It should work with other verification providers as long as the interface + * is compatible with Etherscan's. + */ +export class Etherscan { + /** + * Create a new instance of the Etherscan verification provider. + * @param apiKey - The Etherscan API key. + * @param apiUrl - The Etherscan API URL, e.g. https://api.etherscan.io/api. + * @param browserUrl - The Etherscan browser URL, e.g. https://etherscan.io. + */ + constructor( + public apiKey: string, + public apiUrl: string, + public browserUrl: string + ) {} + + public static async getCurrentChainConfig( + networkName: string, + ethereumProvider: EthereumProvider, + customChains: ChainConfig[] + ): Promise { + const currentChainId = parseInt( + await ethereumProvider.send("eth_chainId"), + 16 + ); + + const currentChainConfig = [ + // custom chains has higher precedence than builtin chains + ...[...customChains].reverse(), // the last entry has higher precedence + ...builtinChains, + ].find(({ chainId }) => chainId === currentChainId); + + if (currentChainConfig === undefined) { + if (networkName === HARDHAT_NETWORK_NAME) { + throw new HardhatNetworkNotSupportedError(); + } + + throw new ChainConfigNotFoundError(currentChainId); + } + + return currentChainConfig; + } + + public static fromChainConfig( + apiKey: ApiKey | undefined, + chainConfig: ChainConfig + ) { + const resolvedApiKey = resolveApiKey(apiKey, chainConfig.network); + const apiUrl = chainConfig.urls.apiURL; + const browserUrl = chainConfig.urls.browserURL.trim().replace(/\/$/, ""); + + return new Etherscan(resolvedApiKey, apiUrl, browserUrl); + } + + /** + * Check if a smart contract is verified on Etherscan. + * @link https://docs.etherscan.io/api-endpoints/contracts#get-contract-source-code-for-verified-contract-source-codes + * @param address - The address of the smart contract. + * @returns True if the contract is verified, false otherwise. + * @throws {NetworkRequestError} if there is an error on the request. + * @throws {ContractVerificationInvalidStatusCodeError} if the API returns an invalid status code. + */ + public async isVerified(address: string) { + const parameters = new URLSearchParams({ + apikey: this.apiKey, + module: "contract", + action: "getsourcecode", + address, + }); + + const url = new URL(this.apiUrl); + url.search = parameters.toString(); + + let response: Dispatcher.ResponseData | undefined; + let json: EtherscanGetSourceCodeResponse | undefined; + try { + response = await sendGetRequest(url); + json = (await response.body.json()) as EtherscanGetSourceCodeResponse; + } catch (e: any) { + throw new NetworkRequestError(e); + } + + if (!isSuccessStatusCode(response.statusCode)) { + throw new ContractVerificationInvalidStatusCodeError( + url.toString(), + response.statusCode, + JSON.stringify(json) + ); + } + + if (json.message !== "OK") { + return false; + } + + const sourceCode = json.result[0]?.SourceCode; + return sourceCode !== undefined && sourceCode !== null && sourceCode !== ""; + } + + /** + * Verify a smart contract on Etherscan. + * @link https://docs.etherscan.io/api-endpoints/contracts#verify-source-code + * @param contractAddress - The address of the smart contract to verify. + * @param sourceCode - The source code of the smart contract. + * @param contractName - The name of the smart contract, e.g. "contracts/Sample.sol:MyContract" + * @param compilerVersion - The version of the Solidity compiler used, e.g. `v0.8.19+commit.7dd6d404` + * @param constructorArguments - The encoded constructor arguments of the smart contract. + * @returns A promise that resolves to an `EtherscanResponse` object. + * @throws {NetworkRequestError} if there is an error on the request. + * @throws {ContractVerificationInvalidStatusCodeError} if the API returns an invalid status code. + * @throws {ContractVerificationMissingBytecodeError} if the bytecode is not found on the block explorer. + * @throws {ContractAlreadyVerifiedError} if the contract is already verified. + * @throws {HardhatVerifyError} if the response status is not OK. + */ + public async verify( + contractAddress: string, + sourceCode: string, + contractName: string, + compilerVersion: string, + constructorArguments: string + ): Promise { + const parameters = new URLSearchParams({ + apikey: this.apiKey, + module: "contract", + action: "verifysourcecode", + contractaddress: contractAddress, + sourceCode, + codeformat: "solidity-standard-json-input", + contractname: contractName, + compilerversion: compilerVersion, + constructorArguements: constructorArguments, + }); + + const url = new URL(this.apiUrl); + let response: Dispatcher.ResponseData | undefined; + let json: EtherscanVerifyResponse | undefined; + try { + response = await sendPostRequest(url, parameters.toString(), { + "Content-Type": "application/x-www-form-urlencoded", + }); + json = (await response.body.json()) as EtherscanVerifyResponse; + } catch (e: any) { + throw new NetworkRequestError(e); + } + + if (!isSuccessStatusCode(response.statusCode)) { + throw new ContractVerificationInvalidStatusCodeError( + url.toString(), + response.statusCode, + JSON.stringify(json) + ); + } + + const etherscanResponse = new EtherscanResponse(json); + + if (etherscanResponse.isBytecodeMissingInNetworkError()) { + throw new ContractVerificationMissingBytecodeError( + this.apiUrl, + contractAddress + ); + } + + if (etherscanResponse.isAlreadyVerified()) { + throw new ContractAlreadyVerifiedError(contractName, contractAddress); + } + + if (!etherscanResponse.isOk()) { + throw new HardhatVerifyError(etherscanResponse.message); + } + + return etherscanResponse; + } + + /** + * Get the verification status of a smart contract from Etherscan. + * This method performs polling of the verification status if it's pending. + * @link https://docs.etherscan.io/api-endpoints/contracts#check-source-code-verification-submission-status + * @param guid - The verification GUID to check. + * @returns A promise that resolves to an `EtherscanResponse` object. + * @throws {NetworkRequestError} if there is an error on the request. + * @throws {ContractStatusPollingInvalidStatusCodeError} if the API returns an invalid status code. + * @throws {ContractStatusPollingResponseNotOkError} if the response status is not OK. + */ + public async getVerificationStatus(guid: string): Promise { + const parameters = new URLSearchParams({ + apikey: this.apiKey, + module: "contract", + action: "checkverifystatus", + guid, + }); + const url = new URL(this.apiUrl); + url.search = parameters.toString(); + + let response: Dispatcher.ResponseData | undefined; + let json: EtherscanVerifyResponse | undefined; + try { + response = await sendGetRequest(url); + json = (await response.body.json()) as EtherscanVerifyResponse; + } catch (e: any) { + throw new NetworkRequestError(e); + } + + if (!isSuccessStatusCode(response.statusCode)) { + throw new ContractStatusPollingInvalidStatusCodeError( + response.statusCode, + JSON.stringify(json) + ); + } + + const etherscanResponse = new EtherscanResponse(json); + + if (etherscanResponse.isPending()) { + await sleep(VERIFICATION_STATUS_POLLING_TIME); + + return this.getVerificationStatus(guid); + } + + if ( + etherscanResponse.isFailure() || + etherscanResponse.isAlreadyVerified() + ) { + return etherscanResponse; + } + + if (!etherscanResponse.isOk()) { + throw new ContractStatusPollingResponseNotOkError( + etherscanResponse.message + ); + } + + return etherscanResponse; + } + + /** + * Get the Etherscan URL for viewing a contract's details. + * @param address - The address of the smart contract. + * @returns The URL to view the contract on Etherscan's website. + */ + public getContractUrl(address: string) { + return `${this.browserUrl}/address/${address}#code`; + } +} + +class EtherscanResponse implements ValidationResponse { + public readonly status: number; + public readonly message: string; + + constructor(response: EtherscanVerifyResponse) { + this.status = parseInt(response.status, 10); + this.message = response.result; + } + + public isPending() { + return this.message === "Pending in queue"; + } + + public isFailure() { + return this.message === "Fail - Unable to verify"; + } + + public isSuccess() { + return this.message === "Pass - Verified"; + } + + public isBytecodeMissingInNetworkError() { + return this.message.startsWith("Unable to locate ContractCode at"); + } + + public isAlreadyVerified() { + return ( + // returned by blockscout + this.message.startsWith("Smart-contract already verified") || + // returned by etherscan + this.message.startsWith("Contract source code already verified") || + this.message.startsWith("Already Verified") + ); + } + + public isOk() { + return this.status === 1; + } +} + +function resolveApiKey(apiKey: ApiKey | undefined, network: string) { + if (apiKey === undefined || apiKey === "") { + throw new MissingApiKeyError(network); + } + + if (typeof apiKey === "string") { + return apiKey; + } + + const key = apiKey[network]; + + if (key === undefined || key === "") { + throw new MissingApiKeyError(network); + } + + return key; +} diff --git a/packages/hardhat-verify/src/internal/etherscan.types.ts b/packages/hardhat-verify/src/internal/etherscan.types.ts new file mode 100644 index 0000000000..b9268f02bb --- /dev/null +++ b/packages/hardhat-verify/src/internal/etherscan.types.ts @@ -0,0 +1,47 @@ +interface EtherscanGetSourceCodeNotOkResponse { + status: "0"; + message: "NOTOK"; + result: string; +} + +interface EtherscanGetSourceCodeOkResponse { + status: "1"; + message: "OK"; + result: EtherscanContract[]; +} + +interface EtherscanContract { + SourceCode: string; + ABI: string; + ContractName: string; + CompilerVersion: string; + OptimizationUsed: string; + Runs: string; + ConstructorArguments: string; + EVMVersion: string; + Library: string; + LicenseType: string; + Proxy: string; + Implementation: string; + SwarmSource: string; +} + +export type EtherscanGetSourceCodeResponse = + | EtherscanGetSourceCodeNotOkResponse + | EtherscanGetSourceCodeOkResponse; + +interface EtherscanVerifyNotOkResponse { + status: "0"; + message: "NOTOK"; + result: string; +} + +interface EtherscanVerifyOkResponse { + status: "1"; + message: "OK"; + result: string; +} + +export type EtherscanVerifyResponse = + | EtherscanVerifyNotOkResponse + | EtherscanVerifyOkResponse; diff --git a/packages/hardhat-verify/src/solc/artifacts.ts b/packages/hardhat-verify/src/internal/solc/artifacts.ts similarity index 99% rename from packages/hardhat-verify/src/solc/artifacts.ts rename to packages/hardhat-verify/src/internal/solc/artifacts.ts index be3cdac7e5..5e6df0225d 100644 --- a/packages/hardhat-verify/src/solc/artifacts.ts +++ b/packages/hardhat-verify/src/internal/solc/artifacts.ts @@ -1,5 +1,4 @@ -import { parseFullyQualifiedName } from "hardhat/utils/contract-names"; -import { +import type { Artifacts, BuildInfo, CompilerInput, @@ -7,6 +6,8 @@ import { CompilerOutputContract, Network, } from "hardhat/types"; + +import { parseFullyQualifiedName } from "hardhat/utils/contract-names"; import { DeployedBytecodeMismatchError, DeployedBytecodeMultipleMatchesError, @@ -367,7 +368,7 @@ function mergeLibraries( ) { const detectedAddress = detectedLibraries[sourceName][libraryName]; // Our detection logic encodes bytes into lowercase hex. - if (libraryAddress.toLowerCase() !== detectedAddress) { + if (libraryAddress.toLowerCase() !== detectedAddress.toLowerCase()) { conflicts.push({ library: `${sourceName}:${libraryName}`, detectedAddress, diff --git a/packages/hardhat-verify/src/internal/solc/bytecode.ts b/packages/hardhat-verify/src/internal/solc/bytecode.ts new file mode 100644 index 0000000000..6e68faaf35 --- /dev/null +++ b/packages/hardhat-verify/src/internal/solc/bytecode.ts @@ -0,0 +1,214 @@ +import type { CompilerOutputBytecode, EthereumProvider } from "hardhat/types"; + +import { DeployedBytecodeNotFoundError } from "../errors"; +import { + getMetadataSectionLength, + inferCompilerVersion, + METADATA_LENGTH, + MISSING_METADATA_VERSION_RANGE, + SOLC_NOT_FOUND_IN_METADATA_VERSION_RANGE, +} from "./metadata"; +import { + ByteOffset, + getCallProtectionOffsets, + getImmutableOffsets, + getLibraryOffsets, +} from "./artifacts"; + +// If the compiler output bytecode is OVM bytecode, we need to make a fix to account for a bug in some versions of +// the OVM compiler. The artifact’s deployedBytecode is incorrect, but because its bytecode (initcode) is correct, when we +// actually deploy contracts, the code that ends up getting stored on chain is also correct. During verification, +// Etherscan will compile the source code, pull out the artifact’s deployedBytecode, and then perform the +// below find and replace, then check that resulting output against the code retrieved on chain from eth_getCode. +// We define the strings for that find and replace here, and use them later so we can know if the bytecode matches +// before it gets to Etherscan. +// Source: https://github.com/ethereum-optimism/optimism/blob/8d67991aba584c1703692ea46273ea8a1ef45f56/packages/contracts/src/contract-dumps.ts#L195-L204 +const OVM_FIND_OPCODES = + "336000905af158601d01573d60011458600c01573d6000803e3d621234565260ea61109c52"; +const OVM_REPLACE_OPCODES = + "336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b"; + +export class Bytecode { + private _bytecode: string; + private _version: string; + private _executableSection: ByteOffset; + private _isOvm: boolean; + + constructor(bytecode: string) { + this._bytecode = bytecode; + + const bytecodeBuffer = Buffer.from(bytecode, "hex"); + this._version = inferCompilerVersion(bytecodeBuffer); + this._executableSection = { + start: 0, + length: bytecode.length - getMetadataSectionLength(bytecodeBuffer) * 2, + }; + + // Check if this is OVM bytecode by looking for the concatenation of the two opcodes defined here: + // https://github.com/ethereum-optimism/optimism/blob/33cb9025f5e463525d6abe67c8457f81a87c5a24/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyChecker.sol#L143 + // - This check would only fail if the EVM solidity compiler didn't use any of the following opcodes: https://github.com/ethereum-optimism/optimism/blob/c42fc0df2790a5319027393cb8fa34e4f7bb520f/packages/contracts/contracts/optimistic-ethereum/iOVM/execution/iOVM_ExecutionManager.sol#L94-L175 + // This is the list of opcodes that calls the OVM execution manager. But the current solidity + // compiler seems to add REVERT in all cases, meaning it currently won't happen and this check + // will always be correct. + // - It is possible, though very unlikely, that this string appears in the bytecode of an EVM + // contract. As a result result, this _isOvm flag should only be used after trying to infer + // the solc version + // - We need this check because OVM bytecode has no metadata, so when verifying + // OVM bytecode the check in `inferSolcVersion` will always return `MISSING_METADATA_VERSION_RANGE`. + this._isOvm = bytecode.includes(OVM_REPLACE_OPCODES); + } + + public static async getDeployedContractBytecode( + address: string, + provider: EthereumProvider, + network: string + ): Promise { + const response: string = await provider.send("eth_getCode", [ + address, + "latest", + ]); + const deployedBytecode = response.replace(/^0x/, ""); + + if (deployedBytecode === "") { + throw new DeployedBytecodeNotFoundError(address, network); + } + + return new Bytecode(deployedBytecode); + } + + public stringify() { + return this._bytecode; + } + + public getVersion() { + return this._version; + } + + public isOvm() { + return this._isOvm; + } + + public hasVersionRange(): boolean { + return ( + this._version === MISSING_METADATA_VERSION_RANGE || + this._version === SOLC_NOT_FOUND_IN_METADATA_VERSION_RANGE + ); + } + + public async getMatchingVersions(versions: string[]): Promise { + const semver = await import("semver"); + + const matchingCompilerVersions = versions.filter((version) => + semver.satisfies(version, this._version) + ); + + return matchingCompilerVersions; + } + + /** + * Compare the bytecode against a compiler's output bytecode, ignoring metadata. + */ + public compare( + compilerOutputDeployedBytecode: CompilerOutputBytecode + ): boolean { + // Ignore metadata since Etherscan performs a partial match. + // See: https://ethereum.org/es/developers/docs/smart-contracts/verifying/#etherscan + const executableSection = this._getExecutableSection(); + let referenceExecutableSection = inferExecutableSection( + compilerOutputDeployedBytecode.object + ); + + // If this is OVM bytecode, do the required find and replace (see above comments for more info) + if (this._isOvm) { + referenceExecutableSection = referenceExecutableSection + .split(OVM_FIND_OPCODES) + .join(OVM_REPLACE_OPCODES); + } + + if ( + executableSection.length !== referenceExecutableSection.length && + // OVM bytecode has no metadata so we ignore this comparison if operating on OVM bytecode + !this._isOvm + ) { + return false; + } + + const normalizedBytecode = nullifyBytecodeOffsets( + executableSection, + compilerOutputDeployedBytecode + ); + + // Library hash placeholders are embedded into the bytes where the library addresses are linked. + // We need to zero them out to compare them. + const normalizedReferenceBytecode = nullifyBytecodeOffsets( + referenceExecutableSection, + compilerOutputDeployedBytecode + ); + + if (normalizedBytecode === normalizedReferenceBytecode) { + return true; + } + + return false; + } + + private _getExecutableSection(): string { + const { start, length } = this._executableSection; + return this._bytecode.slice(start, length); + } +} + +function nullifyBytecodeOffsets( + bytecode: string, + { + object: referenceBytecode, + linkReferences, + immutableReferences, + }: CompilerOutputBytecode +): string { + const offsets = [ + ...getLibraryOffsets(linkReferences), + ...getImmutableOffsets(immutableReferences), + ...getCallProtectionOffsets(bytecode, referenceBytecode), + ]; + + for (const { start, length } of offsets) { + bytecode = [ + bytecode.slice(0, start * 2), + "0".repeat(length * 2), + bytecode.slice((start + length) * 2), + ].join(""); + } + + return bytecode; +} + +/** + * This function returns the executable section without actually + * decoding the whole bytecode string. + * + * This is useful because the runtime object emitted by the compiler + * may contain nonhexadecimal characters due to link placeholders. + */ +function inferExecutableSection(bytecode: string): string { + if (bytecode.startsWith("0x")) { + bytecode = bytecode.slice(2); + } + + // `Buffer.from` will return a buffer that contains bytes up until the last decodable byte. + // To work around this we'll just slice the relevant part of the bytecode. + const metadataLengthSlice = Buffer.from( + bytecode.slice(-METADATA_LENGTH * 2), + "hex" + ); + + // If, for whatever reason, the bytecode is so small that we can't even read two bytes off it, + // return the size of the entire bytecode. + if (metadataLengthSlice.length !== METADATA_LENGTH) { + return bytecode; + } + + const metadataSectionLength = getMetadataSectionLength(metadataLengthSlice); + + return bytecode.slice(0, bytecode.length - metadataSectionLength * 2); +} diff --git a/packages/hardhat-verify/src/solc/metadata.ts b/packages/hardhat-verify/src/internal/solc/metadata.ts similarity index 98% rename from packages/hardhat-verify/src/solc/metadata.ts rename to packages/hardhat-verify/src/internal/solc/metadata.ts index 9bacd33234..445bd096da 100644 --- a/packages/hardhat-verify/src/solc/metadata.ts +++ b/packages/hardhat-verify/src/internal/solc/metadata.ts @@ -7,7 +7,7 @@ export const METADATA_LENGTH = 2; export const SOLC_NOT_FOUND_IN_METADATA_VERSION_RANGE = "0.4.7 - 0.5.8"; export const MISSING_METADATA_VERSION_RANGE = "<0.4.7"; -const log = debug("hardhat:hardhat-etherscan:metadata"); +const log = debug("hardhat:hardhat-verify:metadata"); /** * Try to infer the Solidity compiler version from the bytecode metadata. diff --git a/packages/hardhat-verify/src/internal/sourcify.ts b/packages/hardhat-verify/src/internal/sourcify.ts new file mode 100644 index 0000000000..d04fd5fe84 --- /dev/null +++ b/packages/hardhat-verify/src/internal/sourcify.ts @@ -0,0 +1,179 @@ +import type { Dispatcher } from "undici/types"; +import type { + SourcifyIsVerifiedResponse, + SourcifyVerifyResponse, +} from "./sourcify.types"; + +import { + ContractVerificationInvalidStatusCodeError, + NetworkRequestError, + VerificationAPIUnexpectedMessageError, +} from "./errors"; +import { isSuccessStatusCode, sendGetRequest, sendPostRequest } from "./undici"; +import { ContractStatus } from "./sourcify.types"; +import { ValidationResponse } from "./utilities"; + +export class Sourcify { + constructor( + public chainId: number, + public apiUrl: string, + public browserUrl: string + ) {} + + // https://sourcify.dev/server/api-docs/#/Repository/get_check_all_by_addresses + public async isVerified(address: string) { + const parameters = new URLSearchParams({ + addresses: address, + chainIds: `${this.chainId}`, + }); + + const url = new URL(`${this.apiUrl}/check-all-by-addresses`); + url.search = parameters.toString(); + + let response: Dispatcher.ResponseData | undefined; + let json: SourcifyIsVerifiedResponse[] | undefined; + try { + response = await sendGetRequest(url); + json = (await response.body.json()) as SourcifyIsVerifiedResponse[]; + } catch (e: any) { + throw new NetworkRequestError(e); + } + + if (!isSuccessStatusCode(response.statusCode)) { + throw new ContractVerificationInvalidStatusCodeError( + url.toString(), + response.statusCode, + JSON.stringify(json) + ); + } + + if (!Array.isArray(json)) { + throw new VerificationAPIUnexpectedMessageError( + `Unexpected response body: ${JSON.stringify(json)}` + ); + } + + const contract = json.find( + (match) => match.address.toLowerCase() === address.toLowerCase() + ); + if (contract === undefined) { + return false; + } + + if ("status" in contract && contract.status === ContractStatus.NOT_FOUND) { + return false; + } + + if ("chainIds" in contract && contract.chainIds.length === 1) { + const { status } = contract.chainIds[0]; + if ( + status === ContractStatus.PERFECT || + status === ContractStatus.PARTIAL + ) { + return status; + } + } + + throw new VerificationAPIUnexpectedMessageError( + `Unexpected response body: ${JSON.stringify(json)}` + ); + } + + // https://sourcify.dev/server/api-docs/#/Stateless%20Verification/post_verify + public async verify( + address: string, + files: Record, + chosenContract?: number + ): Promise { + const parameters: any = { + address, + files, + chain: `${this.chainId}`, + }; + + if (chosenContract !== undefined) { + parameters.chosenContract = `${chosenContract}`; + } + + const url = new URL(this.apiUrl); + + let response: Dispatcher.ResponseData | undefined; + let json: SourcifyVerifyResponse | undefined; + try { + response = await sendPostRequest(url, JSON.stringify(parameters), { + "Content-Type": "application/json", + }); + json = (await response.body.json()) as SourcifyVerifyResponse; + } catch (e: any) { + throw new NetworkRequestError(e); + } + + if (!isSuccessStatusCode(response.statusCode)) { + throw new ContractVerificationInvalidStatusCodeError( + url.toString(), + response.statusCode, + JSON.stringify(json) + ); + } + + const sourcifyResponse = new SourcifyResponse(json); + + if (!sourcifyResponse.isOk()) { + throw new VerificationAPIUnexpectedMessageError( + `Verify response is not ok: ${JSON.stringify(json)}` + ); + } + + return sourcifyResponse; + } + + public getContractUrl( + address: string, + contractStatus: ContractStatus.PERFECT | ContractStatus.PARTIAL + ) { + const matchType = + contractStatus === ContractStatus.PERFECT + ? "full_match" + : "partial_match"; + return `${this.browserUrl}/contracts/${matchType}/${this.chainId}/${address}/`; + } +} + +class SourcifyResponse implements ValidationResponse { + public readonly error: string | undefined; + public readonly status: + | ContractStatus.PERFECT + | ContractStatus.PARTIAL + | undefined; + + constructor(response: SourcifyVerifyResponse) { + if ("error" in response) { + this.error = response.error; + } else if (response.result[0].status === ContractStatus.PERFECT) { + this.status = ContractStatus.PERFECT; + } else if (response.result[0].status === ContractStatus.PARTIAL) { + this.status = ContractStatus.PARTIAL; + } + } + + public isPending() { + return false; + } + + public isFailure() { + return this.error !== undefined; + } + + public isSuccess() { + return this.error === undefined; + } + + public isOk(): this is { + status: ContractStatus.PERFECT | ContractStatus.PARTIAL; + } { + return ( + this.status === ContractStatus.PERFECT || + this.status === ContractStatus.PARTIAL + ); + } +} diff --git a/packages/hardhat-verify/src/internal/sourcify.types.ts b/packages/hardhat-verify/src/internal/sourcify.types.ts new file mode 100644 index 0000000000..acf09387b3 --- /dev/null +++ b/packages/hardhat-verify/src/internal/sourcify.types.ts @@ -0,0 +1,40 @@ +export enum ContractStatus { + PERFECT = "perfect", + PARTIAL = "partial", + NOT_FOUND = "false", +} + +interface SourcifyIsVerifiedNotOkResponse { + address: string; + status: ContractStatus.NOT_FOUND; +} + +interface SourcifyIsVerifiedOkResponse { + address: string; + chainIds: Array<{ + chainId: string; + status: ContractStatus.PERFECT | ContractStatus.PARTIAL; + }>; +} + +export type SourcifyIsVerifiedResponse = + | SourcifyIsVerifiedNotOkResponse + | SourcifyIsVerifiedOkResponse; + +interface SourcifyVerifyNotOkResponse { + error: string; +} + +interface SourcifyVerifyOkResponse { + result: Array<{ + address: string; + chainId: string; + status: string; + message?: string; + libraryMap?: Record; + }>; +} + +export type SourcifyVerifyResponse = + | SourcifyVerifyNotOkResponse + | SourcifyVerifyOkResponse; diff --git a/packages/hardhat-verify/src/internal/task-names.ts b/packages/hardhat-verify/src/internal/task-names.ts new file mode 100644 index 0000000000..fdeadb94cb --- /dev/null +++ b/packages/hardhat-verify/src/internal/task-names.ts @@ -0,0 +1,33 @@ +export const TASK_VERIFY = "verify"; +export const TASK_VERIFY_GET_VERIFICATION_SUBTASKS = + "verify:get-verification-subtasks"; +export const TASK_VERIFY_VERIFY = "verify:verify"; +export const TASK_VERIFY_PRINT_SUPPORTED_NETWORKS = + "verify:print-supported-networks"; +export const TASK_VERIFY_GET_CONTRACT_INFORMATION = + "verify:get-contract-information"; + +// Etherscan +export const TASK_VERIFY_ETHERSCAN = "verify:etherscan"; +export const TASK_VERIFY_ETHERSCAN_RESOLVE_ARGUMENTS = + "verify:etherscan-resolve-arguments"; +export const TASK_VERIFY_ETHERSCAN_GET_MINIMAL_INPUT = + "verify:etherscan-get-minimal-input"; +export const TASK_VERIFY_ETHERSCAN_ATTEMPT_VERIFICATION = + "verify:etherscan-attempt-verification"; + +// Sourcify +export const TASK_VERIFY_SOURCIFY = "verify:sourcify"; +export const TASK_VERIFY_SOURCIFY_RESOLVE_ARGUMENTS = + "verify:sourcify-resolve-arguments"; +export const TASK_VERIFY_SOURCIFY_ATTEMPT_VERIFICATION = + "verify:sourcify-attempt-verification"; +export const TASK_VERIFY_SOURCIFY_DISABLED_WARNING = + "verify:sourcify-disabled-warning"; + +// Blockscout +export const TASK_VERIFY_BLOCKSCOUT = "verify:blockscout"; +export const TASK_VERIFY_BLOCKSCOUT_RESOLVE_ARGUMENTS = + "verify:blockscout-resolve-arguments"; +export const TASK_VERIFY_BLOCKSCOUT_ATTEMPT_VERIFICATION = + "verify:blockscout-attempt-verification"; diff --git a/packages/hardhat-verify/src/internal/tasks/blockscout.ts b/packages/hardhat-verify/src/internal/tasks/blockscout.ts new file mode 100644 index 0000000000..57296594df --- /dev/null +++ b/packages/hardhat-verify/src/internal/tasks/blockscout.ts @@ -0,0 +1,224 @@ +import type { CompilerInput } from "hardhat/types"; +import type { VerificationResponse, VerifyTaskArgs } from "../.."; +import type { + LibraryToAddress, + ExtendedContractInformation, +} from "../solc/artifacts"; + +import { subtask, types } from "hardhat/config"; +import { isFullyQualifiedName } from "hardhat/utils/contract-names"; + +import { + CompilerVersionsMismatchError, + ContractVerificationFailedError, + InvalidAddressError, + InvalidContractNameError, + MissingAddressError, +} from "../errors"; +import { Blockscout } from "../blockscout"; +import { Bytecode } from "../solc/bytecode"; +import { + TASK_VERIFY_BLOCKSCOUT, + TASK_VERIFY_BLOCKSCOUT_ATTEMPT_VERIFICATION, + TASK_VERIFY_BLOCKSCOUT_RESOLVE_ARGUMENTS, + TASK_VERIFY_ETHERSCAN_ATTEMPT_VERIFICATION, + TASK_VERIFY_ETHERSCAN_GET_MINIMAL_INPUT, + TASK_VERIFY_GET_CONTRACT_INFORMATION, +} from "../task-names"; +import { getCompilerVersions, resolveLibraries } from "../utilities"; + +// parsed verification args +interface VerificationArgs { + address: string; + libraries: LibraryToAddress; + contractFQN?: string; + force: boolean; +} + +interface AttemptVerificationArgs { + address: string; + compilerInput: CompilerInput; + contractInformation: ExtendedContractInformation; + verificationInterface: Blockscout; +} + +/** + * Main Blockscout verification subtask. + * + * Verifies a contract in Blockscout by coordinating various subtasks related + * to contract verification. + */ +subtask(TASK_VERIFY_BLOCKSCOUT) + .addParam("address") + .addOptionalParam("libraries", undefined, undefined, types.any) + .addOptionalParam("contract") + .addFlag("force") + .setAction( + async ( + taskArgs: VerifyTaskArgs, + { config: config, network: network, run } + ) => { + const { address, libraries, contractFQN, force }: VerificationArgs = + await run(TASK_VERIFY_BLOCKSCOUT_RESOLVE_ARGUMENTS, taskArgs); + + const chainConfig = await Blockscout.getCurrentChainConfig( + network.name, + network.provider, + config.blockscout.customChains + ); + + const blockscout = Blockscout.fromChainConfig(chainConfig); + + const isVerified = await blockscout.isVerified(address); + if (!force && isVerified) { + const contractURL = blockscout.getContractUrl(address); + console.log(`The contract ${address} has already been verified on the block explorer. If you're trying to verify a partially verified contract, please use the --force flag. +${contractURL} +`); + return; + } + + const configCompilerVersions = await getCompilerVersions(config.solidity); + + const deployedBytecode = await Bytecode.getDeployedContractBytecode( + address, + network.provider, + network.name + ); + + const matchingCompilerVersions = + await deployedBytecode.getMatchingVersions(configCompilerVersions); + // don't error if the bytecode appears to be OVM bytecode, because we can't infer a specific OVM solc version from the bytecode + if (matchingCompilerVersions.length === 0 && !deployedBytecode.isOvm()) { + throw new CompilerVersionsMismatchError( + configCompilerVersions, + deployedBytecode.getVersion(), + network.name + ); + } + + const contractInformation: ExtendedContractInformation = await run( + TASK_VERIFY_GET_CONTRACT_INFORMATION, + { + contractFQN, + deployedBytecode, + matchingCompilerVersions, + libraries, + } + ); + + const minimalInput: CompilerInput = await run( + TASK_VERIFY_ETHERSCAN_GET_MINIMAL_INPUT, + { + sourceName: contractInformation.sourceName, + } + ); + + // First, try to verify the contract using the minimal input + const { success: minimalInputVerificationSuccess }: VerificationResponse = + await run(TASK_VERIFY_BLOCKSCOUT_ATTEMPT_VERIFICATION, { + address, + compilerInput: minimalInput, + contractInformation, + verificationInterface: blockscout, + }); + + if (minimalInputVerificationSuccess) { + return; + } + + console.log(`We tried verifying your contract ${contractInformation.contractName} without including any unrelated one, but it failed. +Trying again with the full solc input used to compile and deploy it. +This means that unrelated contracts may be displayed on Blockscout... +`); + + // If verifying with the minimal input failed, try again with the full compiler input + const { + success: fullCompilerInputVerificationSuccess, + message: verificationMessage, + }: VerificationResponse = await run( + TASK_VERIFY_BLOCKSCOUT_ATTEMPT_VERIFICATION, + { + address, + compilerInput: contractInformation.compilerInput, + contractInformation, + verificationInterface: blockscout, + } + ); + + if (fullCompilerInputVerificationSuccess) { + return; + } + + throw new ContractVerificationFailedError( + verificationMessage, + contractInformation.undetectableLibraries + ); + } + ); + +subtask(TASK_VERIFY_BLOCKSCOUT_RESOLVE_ARGUMENTS) + .addOptionalParam("address") + .addOptionalParam("libraries", undefined, undefined, types.any) + .addOptionalParam("contract") + .addFlag("force") + .setAction( + async ({ + address, + contract, + libraries: librariesModule, + force, + }: VerifyTaskArgs): Promise => { + if (address === undefined) { + throw new MissingAddressError(); + } + + const { isAddress } = await import("@ethersproject/address"); + if (!isAddress(address)) { + throw new InvalidAddressError(address); + } + + if (contract !== undefined && !isFullyQualifiedName(contract)) { + throw new InvalidContractNameError(contract); + } + + let libraries; + if (typeof librariesModule === "object") { + libraries = librariesModule; + } else { + libraries = await resolveLibraries(librariesModule); + } + + return { + address, + libraries, + contractFQN: contract, + force, + }; + } + ); + +subtask(TASK_VERIFY_BLOCKSCOUT_ATTEMPT_VERIFICATION) + .addParam("address") + .addParam("compilerInput", undefined, undefined, types.any) + .addParam("contractInformation", undefined, undefined, types.any) + .addParam("verificationInterface", undefined, undefined, types.any) + .setAction( + async ( + { + address, + compilerInput, + contractInformation, + verificationInterface, + }: AttemptVerificationArgs, + { run } + ): Promise => { + return run(TASK_VERIFY_ETHERSCAN_ATTEMPT_VERIFICATION, { + address, + compilerInput, + contractInformation, + verificationInterface, + encodedConstructorArguments: "", + }); + } + ); diff --git a/packages/hardhat-verify/src/internal/tasks/etherscan.ts b/packages/hardhat-verify/src/internal/tasks/etherscan.ts new file mode 100644 index 0000000000..98f7a7dc18 --- /dev/null +++ b/packages/hardhat-verify/src/internal/tasks/etherscan.ts @@ -0,0 +1,357 @@ +import type LodashCloneDeepT from "lodash.clonedeep"; +import type { + CompilerInput, + DependencyGraph, + CompilationJob, +} from "hardhat/types"; +import type { VerificationResponse, VerifyTaskArgs } from "../.."; +import type { + LibraryToAddress, + ExtendedContractInformation, +} from "../solc/artifacts"; + +import { subtask, types } from "hardhat/config"; +import { + TASK_COMPILE_SOLIDITY_GET_DEPENDENCY_GRAPH, + TASK_COMPILE_SOLIDITY_GET_COMPILATION_JOB_FOR_FILE, + TASK_COMPILE_SOLIDITY_GET_COMPILER_INPUT, +} from "hardhat/builtin-tasks/task-names"; +import { isFullyQualifiedName } from "hardhat/utils/contract-names"; + +import { + CompilerVersionsMismatchError, + ContractVerificationFailedError, + MissingAddressError, + InvalidAddressError, + InvalidContractNameError, + UnexpectedNumberOfFilesError, + VerificationAPIUnexpectedMessageError, + ContractAlreadyVerifiedError, + NetworkRequestError, +} from "../errors"; +import { Etherscan } from "../etherscan"; +import { Bytecode } from "../solc/bytecode"; +import { + TASK_VERIFY_ETHERSCAN, + TASK_VERIFY_ETHERSCAN_RESOLVE_ARGUMENTS, + TASK_VERIFY_ETHERSCAN_GET_MINIMAL_INPUT, + TASK_VERIFY_ETHERSCAN_ATTEMPT_VERIFICATION, + TASK_VERIFY_GET_CONTRACT_INFORMATION, +} from "../task-names"; +import { + getCompilerVersions, + encodeArguments, + resolveConstructorArguments, + resolveLibraries, + sleep, +} from "../utilities"; + +// parsed verification args +interface VerificationArgs { + address: string; + constructorArgs: string[]; + libraries: LibraryToAddress; + contractFQN?: string; + force: boolean; +} + +interface GetMinimalInputArgs { + sourceName: string; +} + +interface AttemptVerificationArgs { + address: string; + compilerInput: CompilerInput; + contractInformation: ExtendedContractInformation; + verificationInterface: Etherscan; + encodedConstructorArguments: string; +} + +/** + * Main Etherscan verification subtask. + * + * Verifies a contract in Etherscan by coordinating various subtasks related + * to contract verification. + */ +subtask(TASK_VERIFY_ETHERSCAN) + .addParam("address") + .addOptionalParam("constructorArgsParams", undefined, undefined, types.any) + .addOptionalParam("constructorArgs") + .addOptionalParam("libraries", undefined, undefined, types.any) + .addOptionalParam("contract") + .addFlag("force") + .setAction(async (taskArgs: VerifyTaskArgs, { config, network, run }) => { + const { + address, + constructorArgs, + libraries, + contractFQN, + force, + }: VerificationArgs = await run( + TASK_VERIFY_ETHERSCAN_RESOLVE_ARGUMENTS, + taskArgs + ); + + const chainConfig = await Etherscan.getCurrentChainConfig( + network.name, + network.provider, + config.etherscan.customChains + ); + + const etherscan = Etherscan.fromChainConfig( + config.etherscan.apiKey, + chainConfig + ); + + let isVerified = false; + try { + isVerified = await etherscan.isVerified(address); + } catch (err) { + if (!force || err instanceof NetworkRequestError) { + throw err; + } + // https://github.com/blockscout/blockscout/issues/9001 + } + if (!force && isVerified) { + const contractURL = etherscan.getContractUrl(address); + console.log(`The contract ${address} has already been verified on the block explorer. If you're trying to verify a partially verified contract, please use the --force flag. +${contractURL} +`); + return; + } + + const configCompilerVersions = await getCompilerVersions(config.solidity); + + const deployedBytecode = await Bytecode.getDeployedContractBytecode( + address, + network.provider, + network.name + ); + + const matchingCompilerVersions = await deployedBytecode.getMatchingVersions( + configCompilerVersions + ); + // don't error if the bytecode appears to be OVM bytecode, because we can't infer a specific OVM solc version from the bytecode + if (matchingCompilerVersions.length === 0 && !deployedBytecode.isOvm()) { + throw new CompilerVersionsMismatchError( + configCompilerVersions, + deployedBytecode.getVersion(), + network.name + ); + } + + const contractInformation: ExtendedContractInformation = await run( + TASK_VERIFY_GET_CONTRACT_INFORMATION, + { + contractFQN, + deployedBytecode, + matchingCompilerVersions, + libraries, + } + ); + + const minimalInput: CompilerInput = await run( + TASK_VERIFY_ETHERSCAN_GET_MINIMAL_INPUT, + { + sourceName: contractInformation.sourceName, + } + ); + + const encodedConstructorArguments = await encodeArguments( + contractInformation.contractOutput.abi, + contractInformation.sourceName, + contractInformation.contractName, + constructorArgs + ); + + // First, try to verify the contract using the minimal input + const { success: minimalInputVerificationSuccess }: VerificationResponse = + await run(TASK_VERIFY_ETHERSCAN_ATTEMPT_VERIFICATION, { + address, + compilerInput: minimalInput, + contractInformation, + verificationInterface: etherscan, + encodedConstructorArguments, + }); + + if (minimalInputVerificationSuccess) { + return; + } + + console.log(`We tried verifying your contract ${contractInformation.contractName} without including any unrelated one, but it failed. +Trying again with the full solc input used to compile and deploy it. +This means that unrelated contracts may be displayed on Etherscan... +`); + + // If verifying with the minimal input failed, try again with the full compiler input + const { + success: fullCompilerInputVerificationSuccess, + message: verificationMessage, + }: VerificationResponse = await run( + TASK_VERIFY_ETHERSCAN_ATTEMPT_VERIFICATION, + { + address, + compilerInput: contractInformation.compilerInput, + contractInformation, + verificationInterface: etherscan, + encodedConstructorArguments, + } + ); + + if (fullCompilerInputVerificationSuccess) { + return; + } + + throw new ContractVerificationFailedError( + verificationMessage, + contractInformation.undetectableLibraries + ); + }); + +subtask(TASK_VERIFY_ETHERSCAN_RESOLVE_ARGUMENTS) + .addOptionalParam("address") + .addOptionalParam("constructorArgsParams", undefined, [], types.any) + .addOptionalParam("constructorArgs", undefined, undefined, types.inputFile) + .addOptionalParam("libraries", undefined, undefined, types.any) + .addOptionalParam("contract") + .addFlag("force") + .setAction( + async ({ + address, + constructorArgsParams, + constructorArgs: constructorArgsModule, + contract, + libraries: librariesModule, + force, + }: VerifyTaskArgs): Promise => { + if (address === undefined) { + throw new MissingAddressError(); + } + + const { isAddress } = await import("@ethersproject/address"); + if (!isAddress(address)) { + throw new InvalidAddressError(address); + } + + if (contract !== undefined && !isFullyQualifiedName(contract)) { + throw new InvalidContractNameError(contract); + } + + const constructorArgs = await resolveConstructorArguments( + constructorArgsParams, + constructorArgsModule + ); + + let libraries; + if (typeof librariesModule === "object") { + libraries = librariesModule; + } else { + libraries = await resolveLibraries(librariesModule); + } + + return { + address, + constructorArgs, + libraries, + contractFQN: contract, + force, + }; + } + ); + +subtask(TASK_VERIFY_ETHERSCAN_GET_MINIMAL_INPUT) + .addParam("sourceName") + .setAction(async ({ sourceName }: GetMinimalInputArgs, { run }) => { + const cloneDeep = require("lodash.clonedeep") as typeof LodashCloneDeepT; + const dependencyGraph: DependencyGraph = await run( + TASK_COMPILE_SOLIDITY_GET_DEPENDENCY_GRAPH, + { sourceNames: [sourceName] } + ); + + const resolvedFiles = dependencyGraph + .getResolvedFiles() + .filter((resolvedFile) => resolvedFile.sourceName === sourceName); + + if (resolvedFiles.length !== 1) { + throw new UnexpectedNumberOfFilesError(); + } + + const compilationJob: CompilationJob = await run( + TASK_COMPILE_SOLIDITY_GET_COMPILATION_JOB_FOR_FILE, + { + dependencyGraph, + file: resolvedFiles[0], + } + ); + + const minimalInput: CompilerInput = await run( + TASK_COMPILE_SOLIDITY_GET_COMPILER_INPUT, + { + compilationJob, + } + ); + + return cloneDeep(minimalInput); + }); + +subtask(TASK_VERIFY_ETHERSCAN_ATTEMPT_VERIFICATION) + .addParam("address") + .addParam("compilerInput", undefined, undefined, types.any) + .addParam("contractInformation", undefined, undefined, types.any) + .addParam("verificationInterface", undefined, undefined, types.any) + .addParam("encodedConstructorArguments") + .setAction( + async ({ + address, + compilerInput, + contractInformation, + verificationInterface, + encodedConstructorArguments, + }: AttemptVerificationArgs): Promise => { + // Ensure the linking information is present in the compiler input; + compilerInput.settings.libraries = contractInformation.libraries; + + const contractFQN = `${contractInformation.sourceName}:${contractInformation.contractName}`; + const { message: guid } = await verificationInterface.verify( + address, + JSON.stringify(compilerInput), + contractFQN, + `v${contractInformation.solcLongVersion}`, + encodedConstructorArguments + ); + + console.log(`Successfully submitted source code for contract +${contractFQN} at ${address} +for verification on the block explorer. Waiting for verification result... +`); + + // Compilation is bound to take some time so there's no sense in requesting status immediately. + await sleep(700); + const verificationStatus = + await verificationInterface.getVerificationStatus(guid); + + // Etherscan answers with already verified message only when checking returned guid + if (verificationStatus.isAlreadyVerified()) { + throw new ContractAlreadyVerifiedError(contractFQN, address); + } + + if (!(verificationStatus.isFailure() || verificationStatus.isSuccess())) { + // Reaching this point shouldn't be possible unless the API is behaving in a new way. + throw new VerificationAPIUnexpectedMessageError( + verificationStatus.message + ); + } + + if (verificationStatus.isSuccess()) { + const contractURL = verificationInterface.getContractUrl(address); + console.log(`Successfully verified contract ${contractInformation.contractName} on the block explorer. +${contractURL} +`); + } + + return { + success: verificationStatus.isSuccess(), + message: verificationStatus.message, + }; + } + ); diff --git a/packages/hardhat-verify/src/internal/tasks/sourcify.ts b/packages/hardhat-verify/src/internal/tasks/sourcify.ts new file mode 100644 index 0000000000..3407d662f3 --- /dev/null +++ b/packages/hardhat-verify/src/internal/tasks/sourcify.ts @@ -0,0 +1,239 @@ +import type { VerificationResponse, VerifyTaskArgs } from "../.."; +import type { + ExtendedContractInformation, + LibraryToAddress, +} from "../solc/artifacts"; + +import picocolors from "picocolors"; +import { subtask, types } from "hardhat/config"; +import { isFullyQualifiedName } from "hardhat/utils/contract-names"; +import { HARDHAT_NETWORK_NAME } from "hardhat/plugins"; + +import { Sourcify } from "../sourcify"; +import { + CompilerVersionsMismatchError, + ContractVerificationFailedError, + HardhatNetworkNotSupportedError, + HardhatVerifyError, + InvalidAddressError, + InvalidContractNameError, + MissingAddressError, +} from "../errors"; +import { + TASK_VERIFY_SOURCIFY, + TASK_VERIFY_SOURCIFY_RESOLVE_ARGUMENTS, + TASK_VERIFY_GET_CONTRACT_INFORMATION, + TASK_VERIFY_SOURCIFY_ATTEMPT_VERIFICATION, + TASK_VERIFY_SOURCIFY_DISABLED_WARNING, +} from "../task-names"; +import { getCompilerVersions, resolveLibraries } from "../utilities"; +import { Bytecode } from "../solc/bytecode"; + +// parsed verification args +interface VerificationArgs { + address: string; + libraries: LibraryToAddress; + contractFQN?: string; +} + +interface AttemptVerificationArgs { + address: string; + verificationInterface: Sourcify; + contractInformation: ExtendedContractInformation; +} + +/** + * Main Sourcify verification subtask. + * + * Verifies a contract in Sourcify by coordinating various subtasks related + * to contract verification. + */ +subtask(TASK_VERIFY_SOURCIFY) + .addParam("address") + .addOptionalParam("contract") + .addOptionalParam("libraries", undefined, undefined, types.any) + .setAction(async (taskArgs: VerifyTaskArgs, { config, network, run }) => { + const { address, libraries, contractFQN }: VerificationArgs = await run( + TASK_VERIFY_SOURCIFY_RESOLVE_ARGUMENTS, + taskArgs + ); + + if (network.name === HARDHAT_NETWORK_NAME) { + throw new HardhatNetworkNotSupportedError(); + } + + const currentChainId = parseInt( + await network.provider.send("eth_chainId"), + 16 + ); + + const { apiUrl, browserUrl } = config.sourcify; + + if (apiUrl === undefined) { + throw new HardhatVerifyError("Sourcify `apiUrl` is not defined"); + } + + if (browserUrl === undefined) { + throw new HardhatVerifyError("Sourcify `browserUrl` is not defined"); + } + + const sourcify = new Sourcify(currentChainId, apiUrl, browserUrl); + + const status = await sourcify.isVerified(address); + if (status !== false) { + const contractURL = sourcify.getContractUrl(address, status); + console.log(`The contract ${address} has already been verified on Sourcify. +${contractURL} +`); + return; + } + + const configCompilerVersions = await getCompilerVersions(config.solidity); + + const deployedBytecode = await Bytecode.getDeployedContractBytecode( + address, + network.provider, + network.name + ); + + const matchingCompilerVersions = await deployedBytecode.getMatchingVersions( + configCompilerVersions + ); + // don't error if the bytecode appears to be OVM bytecode, because we can't infer a specific OVM solc version from the bytecode + if (matchingCompilerVersions.length === 0 && !deployedBytecode.isOvm()) { + throw new CompilerVersionsMismatchError( + configCompilerVersions, + deployedBytecode.getVersion(), + network.name + ); + } + + const contractInformation: ExtendedContractInformation = await run( + TASK_VERIFY_GET_CONTRACT_INFORMATION, + { + contractFQN, + deployedBytecode, + matchingCompilerVersions, + libraries, + } + ); + + const { + success: verificationSuccess, + message: verificationMessage, + }: VerificationResponse = await run( + TASK_VERIFY_SOURCIFY_ATTEMPT_VERIFICATION, + { + address, + verificationInterface: sourcify, + contractInformation, + } + ); + + if (verificationSuccess) { + return; + } + + throw new ContractVerificationFailedError( + verificationMessage, + contractInformation.undetectableLibraries + ); + }); + +subtask(TASK_VERIFY_SOURCIFY_RESOLVE_ARGUMENTS) + .addOptionalParam("address") + .addOptionalParam("contract") + .addOptionalParam("libraries", undefined, undefined, types.any) + .setAction( + async ({ + address, + contract, + libraries: librariesModule, + }: VerifyTaskArgs): Promise => { + if (address === undefined) { + throw new MissingAddressError(); + } + + const { isAddress } = await import("@ethersproject/address"); + if (!isAddress(address)) { + throw new InvalidAddressError(address); + } + + if (contract !== undefined && !isFullyQualifiedName(contract)) { + throw new InvalidContractNameError(contract); + } + + let libraries; + if (typeof librariesModule === "object") { + libraries = librariesModule; + } else { + libraries = await resolveLibraries(librariesModule); + } + + return { + address, + libraries, + contractFQN: contract, + }; + } + ); + +subtask(TASK_VERIFY_SOURCIFY_ATTEMPT_VERIFICATION) + .addParam("address") + .addParam("contractInformation", undefined, undefined, types.any) + .addParam("verificationInterface", undefined, undefined, types.any) + .setAction( + async ({ + address, + verificationInterface, + contractInformation, + }: AttemptVerificationArgs): Promise => { + const { sourceName, contractName, contractOutput, compilerInput } = + contractInformation; + + const librarySourcesToContent = Object.keys( + contractInformation.libraries + ).reduce((acc: Record, libSourceName) => { + const libContent = compilerInput.sources[libSourceName].content; + acc[libSourceName] = libContent; + return acc; + }, {}); + + const response = await verificationInterface.verify(address, { + "metadata.json": (contractOutput as any).metadata, + [sourceName]: compilerInput.sources[sourceName].content, + ...librarySourcesToContent, + }); + + if (response.isOk()) { + const contractURL = verificationInterface.getContractUrl( + address, + response.status + ); + console.log(`Successfully verified contract ${contractName} on Sourcify. +${contractURL} +`); + } + + return { + success: response.isSuccess(), + message: "Contract successfully verified on Sourcify", + }; + } + ); + +subtask(TASK_VERIFY_SOURCIFY_DISABLED_WARNING, async () => { + console.info( + picocolors.cyan( + `[INFO] Sourcify Verification Skipped: Sourcify verification is currently disabled. To enable it, add the following entry to your Hardhat configuration: + +sourcify: { + enabled: true +} + +Or set 'enabled' to false to hide this message. + +For more information, visit https://hardhat.org/hardhat-runner/plugins/nomicfoundation-hardhat-verify#verifying-on-sourcify` + ) + ); +}); diff --git a/packages/hardhat-verify/src/internal/type-extensions.ts b/packages/hardhat-verify/src/internal/type-extensions.ts new file mode 100644 index 0000000000..5559398b51 --- /dev/null +++ b/packages/hardhat-verify/src/internal/type-extensions.ts @@ -0,0 +1,21 @@ +import type { + EtherscanConfig, + SourcifyConfig, + BlockscoutConfig, +} from "../types"; + +import "hardhat/types/config"; + +declare module "hardhat/types/config" { + interface HardhatUserConfig { + etherscan?: Partial; + sourcify?: Partial; + blockscout?: Partial; + } + + interface HardhatConfig { + etherscan: EtherscanConfig; + sourcify: SourcifyConfig; + blockscout: BlockscoutConfig; + } +} diff --git a/packages/hardhat-verify/src/undici.ts b/packages/hardhat-verify/src/internal/undici.ts similarity index 81% rename from packages/hardhat-verify/src/undici.ts rename to packages/hardhat-verify/src/internal/undici.ts index e5657d5927..a25acc8966 100644 --- a/packages/hardhat-verify/src/undici.ts +++ b/packages/hardhat-verify/src/internal/undici.ts @@ -14,7 +14,8 @@ export async function sendGetRequest( export async function sendPostRequest( url: URL, - body: string + body: string, + headers: Record = {} ): Promise { const { request } = await import("undici"); const dispatcher = getDispatcher(); @@ -22,7 +23,7 @@ export async function sendPostRequest( return request(url, { dispatcher, method: "POST", - headers: { "Content-Type": "application/x-www-form-urlencoded" }, + headers, body, }); } @@ -36,3 +37,7 @@ function getDispatcher(): Undici.Dispatcher { return getGlobalDispatcher(); } + +export function isSuccessStatusCode(statusCode: number): boolean { + return statusCode >= 200 && statusCode <= 299; +} diff --git a/packages/hardhat-verify/src/internal/utilities.ts b/packages/hardhat-verify/src/internal/utilities.ts new file mode 100644 index 0000000000..ea88f2863f --- /dev/null +++ b/packages/hardhat-verify/src/internal/utilities.ts @@ -0,0 +1,280 @@ +import type { JsonFragment } from "@ethersproject/abi"; +import type { SolidityConfig } from "hardhat/types"; +import type { ChainConfig } from "../types"; + +import picocolors from "picocolors"; +import path from "path"; +import { builtinChains } from "./chain-config"; +import { + ABIArgumentLengthError, + ABIArgumentOverflowError, + ABIArgumentTypeError, + EtherscanVersionNotSupportedError, + ExclusiveConstructorArgumentsError, + HardhatVerifyError, + ImportingModuleError, + InvalidConstructorArgumentsModuleError, + InvalidLibrariesModuleError, +} from "./errors"; + +import { LibraryToAddress } from "./solc/artifacts"; +import { + ABIArgumentTypeErrorType, + isABIArgumentLengthError, + isABIArgumentOverflowError, + isABIArgumentTypeError, +} from "./abi-validation-extras"; + +export async function sleep(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); +} + +/** + * Prints a table of networks supported by hardhat-verify, including both + * built-in and custom networks. + */ +export async function printSupportedNetworks( + customChains: ChainConfig[] +): Promise { + const { table } = await import("table"); + + // supported networks + const supportedNetworks = builtinChains.map(({ network, chainId }) => [ + network, + chainId, + ]); + + const supportedNetworksTable = table([ + [picocolors.bold("network"), picocolors.bold("chain id")], + ...supportedNetworks, + ]); + + // custom networks + const customNetworks = customChains.map(({ network, chainId }) => [ + network, + chainId, + ]); + + const customNetworksTable = + customNetworks.length > 0 + ? table([ + [picocolors.bold("network"), picocolors.bold("chain id")], + ...customNetworks, + ]) + : table([["No custom networks were added"]]); + + // print message + console.log( + ` +Networks supported by hardhat-verify: + +${supportedNetworksTable} + +Custom networks added by you or by plugins: + +${customNetworksTable} + +To learn how to add custom networks, follow these instructions: https://hardhat.org/verify-custom-networks +`.trimStart() + ); +} + +/** + * Prints verification errors to the console. + * @param errors - An object containing verification errors, where the keys + * are the names of verification subtasks and the values are HardhatVerifyError + * objects describing the specific errors. + * @remarks This function formats and logs the verification errors to the + * console with a red color using picocolors. Each error is displayed along with the + * name of the verification provider it belongs to. + * @example + * const errors: Record = { + * verify:etherscan: { message: 'Error message for Etherscan' }, + * verify:sourcify: { message: 'Error message for Sourcify' }, + * verify:blockscout: { message: 'Error message for Blockscout' }, + * // Add more errors here... + * }; + * printVerificationErrors(errors); + * // Output: + * // hardhat-verify found one or more errors during the verification process: + * // + * // Etherscan: + * // Error message for Etherscan + * // + * // Sourcify: + * // Error message for Sourcify + * // + * // Blockscout: + * // Error message for Blockscout + * // + * // ... (more errors if present) + */ +export function printVerificationErrors( + errors: Record +) { + let errorMessage = + "hardhat-verify found one or more errors during the verification process:\n\n"; + + for (const [subtaskLabel, error] of Object.entries(errors)) { + errorMessage += `${subtaskLabel}:\n${error.message}\n\n`; + } + + console.error(picocolors.red(errorMessage)); +} + +/** + * Returns the list of constructor arguments from the constructorArgsModule + * or the constructorArgsParams if the first is not defined. + */ +export async function resolveConstructorArguments( + constructorArgsParams: string[], + constructorArgsModule?: string +): Promise { + if (constructorArgsModule === undefined) { + return constructorArgsParams; + } + + if (constructorArgsParams.length > 0) { + throw new ExclusiveConstructorArgumentsError(); + } + + const constructorArgsModulePath = path.resolve( + process.cwd(), + constructorArgsModule + ); + + try { + const constructorArguments = (await import(constructorArgsModulePath)) + .default; + + if (!Array.isArray(constructorArguments)) { + throw new InvalidConstructorArgumentsModuleError( + constructorArgsModulePath + ); + } + + return constructorArguments; + } catch (error: any) { + throw new ImportingModuleError("constructor arguments list", error); + } +} + +/** + * Returns a dictionary of library addresses from the librariesModule or + * an empty object if not defined. + */ +export async function resolveLibraries( + librariesModule?: string +): Promise { + if (librariesModule === undefined) { + return {}; + } + + const librariesModulePath = path.resolve(process.cwd(), librariesModule); + + try { + const libraries = (await import(librariesModulePath)).default; + + if (typeof libraries !== "object" || Array.isArray(libraries)) { + throw new InvalidLibrariesModuleError(librariesModulePath); + } + + return libraries; + } catch (error: any) { + throw new ImportingModuleError("libraries dictionary", error); + } +} + +/** + * Retrieves the list of Solidity compiler versions for a given Solidity + * configuration. + * It checks that the versions are supported by Etherscan, and throws an + * error if any are not. + */ +export async function getCompilerVersions({ + compilers, + overrides, +}: SolidityConfig): Promise { + { + const compilerVersions = compilers.map(({ version }) => version); + if (overrides !== undefined) { + for (const { version } of Object.values(overrides)) { + compilerVersions.push(version); + } + } + + // Etherscan only supports solidity versions higher than or equal to v0.4.11. + // See https://etherscan.io/solcversions + const supportedSolcVersionRange = ">=0.4.11"; + const semver = await import("semver"); + if ( + compilerVersions.some( + (version) => !semver.satisfies(version, supportedSolcVersionRange) + ) + ) { + throw new EtherscanVersionNotSupportedError(); + } + + return compilerVersions; + } +} + +/** + * Encodes the constructor arguments for a given contract. + */ +export async function encodeArguments( + abi: JsonFragment[], + sourceName: string, + contractName: string, + constructorArguments: any[] +): Promise { + const { Interface } = await import("@ethersproject/abi"); + + const contractInterface = new Interface(abi); + let encodedConstructorArguments; + try { + // encodeDeploy doesn't catch subtle type mismatches, such as a number + // being passed when a string is expected, so we have to validate the + // scenario manually. + const expectedConstructorArgs = contractInterface.deploy.inputs; + constructorArguments.forEach((arg, i) => { + if ( + expectedConstructorArgs[i]?.type === "string" && + typeof arg !== "string" + ) { + throw new ABIArgumentTypeError({ + code: "INVALID_ARGUMENT", + argument: expectedConstructorArgs[i].name, + value: arg, + reason: "invalid string value", + } as ABIArgumentTypeErrorType); + } + }); + + encodedConstructorArguments = contractInterface + .encodeDeploy(constructorArguments) + .replace("0x", ""); + } catch (error) { + if (isABIArgumentLengthError(error)) { + throw new ABIArgumentLengthError(sourceName, contractName, error); + } + if (isABIArgumentTypeError(error)) { + throw new ABIArgumentTypeError(error); + } + if (isABIArgumentOverflowError(error)) { + throw new ABIArgumentOverflowError(error); + } + + // Should be unreachable. + throw error; + } + + return encodedConstructorArguments; +} + +export interface ValidationResponse { + isPending(): void; + isFailure(): void; + isSuccess(): void; + isOk(): void; +} diff --git a/packages/hardhat-verify/src/solc/bytecode.ts b/packages/hardhat-verify/src/solc/bytecode.ts deleted file mode 100644 index bbdefdca65..0000000000 --- a/packages/hardhat-verify/src/solc/bytecode.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { CompilerOutputBytecode, EthereumProvider } from "hardhat/types"; -import { DeployedBytecodeNotFoundError } from "../errors"; -import { - getMetadataSectionLength, - inferCompilerVersion, - METADATA_LENGTH, - MISSING_METADATA_VERSION_RANGE, - SOLC_NOT_FOUND_IN_METADATA_VERSION_RANGE, -} from "./metadata"; -import { - ByteOffset, - getCallProtectionOffsets, - getImmutableOffsets, - getLibraryOffsets, -} from "./artifacts"; - -// If the compiler output bytecode is OVM bytecode, we need to make a fix to account for a bug in some versions of -// the OVM compiler. The artifact’s deployedBytecode is incorrect, but because its bytecode (initcode) is correct, when we -// actually deploy contracts, the code that ends up getting stored on chain is also correct. During verification, -// Etherscan will compile the source code, pull out the artifact’s deployedBytecode, and then perform the -// below find and replace, then check that resulting output against the code retrieved on chain from eth_getCode. -// We define the strings for that find and replace here, and use them later so we can know if the bytecode matches -// before it gets to Etherscan. -// Source: https://github.com/ethereum-optimism/optimism/blob/8d67991aba584c1703692ea46273ea8a1ef45f56/packages/contracts/src/contract-dumps.ts#L195-L204 -const OVM_FIND_OPCODES = - "336000905af158601d01573d60011458600c01573d6000803e3d621234565260ea61109c52"; -const OVM_REPLACE_OPCODES = - "336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b"; - -export class Bytecode { - private _bytecode: string; - private _version: string; - private _executableSection: ByteOffset; - private _isOvm: boolean; - - constructor(bytecode: string) { - this._bytecode = bytecode; - - const bytecodeBuffer = Buffer.from(bytecode, "hex"); - this._version = inferCompilerVersion(bytecodeBuffer); - this._executableSection = { - start: 0, - length: bytecode.length - getMetadataSectionLength(bytecodeBuffer) * 2, - }; - - // Check if this is OVM bytecode by looking for the concatenation of the two opcodes defined here: - // https://github.com/ethereum-optimism/optimism/blob/33cb9025f5e463525d6abe67c8457f81a87c5a24/packages/contracts/contracts/optimistic-ethereum/OVM/execution/OVM_SafetyChecker.sol#L143 - // - This check would only fail if the EVM solidity compiler didn't use any of the following opcodes: https://github.com/ethereum-optimism/optimism/blob/c42fc0df2790a5319027393cb8fa34e4f7bb520f/packages/contracts/contracts/optimistic-ethereum/iOVM/execution/iOVM_ExecutionManager.sol#L94-L175 - // This is the list of opcodes that calls the OVM execution manager. But the current solidity - // compiler seems to add REVERT in all cases, meaning it currently won't happen and this check - // will always be correct. - // - It is possible, though very unlikely, that this string appears in the bytecode of an EVM - // contract. As a result result, this _isOvm flag should only be used after trying to infer - // the solc version - // - We need this check because OVM bytecode has no metadata, so when verifying - // OVM bytecode the check in `inferSolcVersion` will always return `MISSING_METADATA_VERSION_RANGE`. - this._isOvm = bytecode.includes(OVM_REPLACE_OPCODES); - } - - public static async getDeployedContractBytecode( - address: string, - provider: EthereumProvider, - network: string - ): Promise { - const response: string = await provider.send("eth_getCode", [ - address, - "latest", - ]); - const deployedBytecode = response.replace(/^0x/, ""); - - if (deployedBytecode === "") { - throw new DeployedBytecodeNotFoundError(address, network); - } - - return new Bytecode(deployedBytecode); - } - - public stringify() { - return this._bytecode; - } - - public getVersion() { - return this._version; - } - - public isOvm() { - return this._isOvm; - } - - public hasVersionRange(): boolean { - return ( - this._version === MISSING_METADATA_VERSION_RANGE || - this._version === SOLC_NOT_FOUND_IN_METADATA_VERSION_RANGE - ); - } - - public async getMatchingVersions(versions: string[]): Promise { - const semver = await import("semver"); - - const matchingCompilerVersions = versions.filter((version) => - semver.satisfies(version, this._version) - ); - - return matchingCompilerVersions; - } - - /** - * Compare the bytecode agaisnt a compiler's output bytecode, ignoring metadata. - */ - public compare( - compilerOutputDeployedBytecode: CompilerOutputBytecode - ): boolean { - // Ignore metadata since Etherscan performs a partial match. - // See: https://ethereum.org/es/developers/docs/smart-contracts/verifying/#etherscan - const executableSection = this._getExecutableSection(); - let referenceExecutableSection = inferExecutableSection( - compilerOutputDeployedBytecode.object - ); - - // If this is OVM bytecode, do the required find and replace (see above comments for more info) - if (this._isOvm) { - referenceExecutableSection = referenceExecutableSection - .split(OVM_FIND_OPCODES) - .join(OVM_REPLACE_OPCODES); - } - - if ( - executableSection.length !== referenceExecutableSection.length && - // OVM bytecode has no metadata so we ignore this comparison if operating on OVM bytecode - !this._isOvm - ) { - return false; - } - - const normalizedBytecode = nullifyBytecodeOffsets( - executableSection, - compilerOutputDeployedBytecode - ); - - // Library hash placeholders are embedded into the bytes where the library addresses are linked. - // We need to zero them out to compare them. - const normalizedReferenceBytecode = nullifyBytecodeOffsets( - referenceExecutableSection, - compilerOutputDeployedBytecode - ); - - if (normalizedBytecode === normalizedReferenceBytecode) { - return true; - } - - return false; - } - - private _getExecutableSection(): string { - const { start, length } = this._executableSection; - return this._bytecode.slice(start, length); - } -} - -function nullifyBytecodeOffsets( - bytecode: string, - { - object: referenceBytecode, - linkReferences, - immutableReferences, - }: CompilerOutputBytecode -): string { - const offsets = [ - ...getLibraryOffsets(linkReferences), - ...getImmutableOffsets(immutableReferences), - ...getCallProtectionOffsets(bytecode, referenceBytecode), - ]; - - for (const { start, length } of offsets) { - bytecode = [ - bytecode.slice(0, start * 2), - "0".repeat(length * 2), - bytecode.slice((start + length) * 2), - ].join(""); - } - - return bytecode; -} - -/** - * This function returns the executable section without actually - * decoding the whole bytecode string. - * - * This is useful because the runtime object emitted by the compiler - * may contain nonhexadecimal characters due to link placeholders. - */ -function inferExecutableSection(bytecode: string): string { - if (bytecode.startsWith("0x")) { - bytecode = bytecode.slice(2); - } - - // `Buffer.from` will return a buffer that contains bytes up until the last decodable byte. - // To work around this we'll just slice the relevant part of the bytecode. - const metadataLengthSlice = Buffer.from( - bytecode.slice(-METADATA_LENGTH * 2), - "hex" - ); - - // If, for whatever reason, the bytecode is so small that we can't even read two bytes off it, - // return the size of the entire bytecode. - if (metadataLengthSlice.length !== METADATA_LENGTH) { - return bytecode; - } - - const metadataSectionLength = getMetadataSectionLength(metadataLengthSlice); - - return bytecode.slice(0, bytecode.length - metadataSectionLength * 2); -} diff --git a/packages/hardhat-verify/src/sourcify.ts b/packages/hardhat-verify/src/sourcify.ts new file mode 100644 index 0000000000..7e146ea86f --- /dev/null +++ b/packages/hardhat-verify/src/sourcify.ts @@ -0,0 +1 @@ +export { Sourcify } from "./internal/sourcify"; diff --git a/packages/hardhat-verify/src/task-names.ts b/packages/hardhat-verify/src/task-names.ts deleted file mode 100644 index 11ed180965..0000000000 --- a/packages/hardhat-verify/src/task-names.ts +++ /dev/null @@ -1,12 +0,0 @@ -export const TASK_VERIFY = "verify"; -export const TASK_VERIFY_GET_VERIFICATION_SUBTASKS = - "verify:get-verification-subtasks"; -export const TASK_VERIFY_RESOLVE_ARGUMENTS = "verify:resolve-arguments"; -export const TASK_VERIFY_VERIFY = "verify:verify"; -export const TASK_VERIFY_ETHERSCAN = "verify:etherscan"; -export const TASK_VERIFY_ETHERSCAN_GET_CONTRACT_INFORMATION = - "verify:etherscan-get-contract-information"; -export const TASK_VERIFY_ETHERSCAN_GET_MINIMAL_INPUT = - "verify:etherscan-get-minimal-input"; -export const TASK_VERIFY_ETHERSCAN_ATTEMPT_VERIFICATION = - "verify:etherscan-attempt-verification"; diff --git a/packages/hardhat-verify/src/tsconfig.json b/packages/hardhat-verify/src/tsconfig.json new file mode 100644 index 0000000000..550a953bb3 --- /dev/null +++ b/packages/hardhat-verify/src/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "../../../config/typescript/tsconfig.json", + "compilerOptions": { + "outDir": "../", + "rootDirs": ["."], + "composite": true + }, + "include": ["./**/*.ts"], + "exclude": [], + "references": [ + { + "path": "../../hardhat-core/src" + }, + { + "path": "../../hardhat-ethers/src" + } + ] +} diff --git a/packages/hardhat-verify/src/type-extensions.ts b/packages/hardhat-verify/src/type-extensions.ts deleted file mode 100644 index 8435d1a7e2..0000000000 --- a/packages/hardhat-verify/src/type-extensions.ts +++ /dev/null @@ -1,13 +0,0 @@ -import "hardhat/types/config"; - -import { EtherscanConfig } from "./types"; - -declare module "hardhat/types/config" { - interface HardhatUserConfig { - etherscan?: Partial; - } - - interface HardhatConfig { - etherscan: EtherscanConfig; - } -} diff --git a/packages/hardhat-verify/src/types.ts b/packages/hardhat-verify/src/types.ts index 566084b86e..1afd60067a 100644 --- a/packages/hardhat-verify/src/types.ts +++ b/packages/hardhat-verify/src/types.ts @@ -10,6 +10,18 @@ export interface ChainConfig { export interface EtherscanConfig { apiKey: ApiKey; customChains: ChainConfig[]; + enabled: boolean; +} + +export interface SourcifyConfig { + enabled: boolean; + apiUrl?: string; + browserUrl?: string; +} + +export interface BlockscoutConfig { + enabled: boolean; + customChains: ChainConfig[]; } export type ApiKey = string | Record; diff --git a/packages/hardhat-verify/src/utilities.ts b/packages/hardhat-verify/src/utilities.ts deleted file mode 100644 index 36cbd8f1c1..0000000000 --- a/packages/hardhat-verify/src/utilities.ts +++ /dev/null @@ -1,210 +0,0 @@ -import type { JsonFragment } from "@ethersproject/abi"; - -import chalk from "chalk"; -import path from "path"; -import { SolidityConfig } from "hardhat/types"; -import { builtinChains } from "./chain-config"; -import { - ABIArgumentLengthError, - ABIArgumentOverflowError, - ABIArgumentTypeError, - EtherscanVersionNotSupportedError, - ExclusiveConstructorArgumentsError, - ImportingModuleError, - InvalidConstructorArgumentsModuleError, - InvalidLibrariesModuleError, -} from "./errors"; - -import { ChainConfig } from "./types"; -import { LibraryToAddress } from "./solc/artifacts"; -import { - isABIArgumentLengthError, - isABIArgumentOverflowError, - isABIArgumentTypeError, -} from "./abi-validation-extras"; - -export async function sleep(ms: number): Promise { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - -/** - * Prints a table of networks supported by hardhat-etherscan, including both - * built-in and custom networks. - */ -export async function printSupportedNetworks( - customChains: ChainConfig[] -): Promise { - const { table } = await import("table"); - - // supported networks - const supportedNetworks = builtinChains.map(({ network, chainId }) => [ - network, - chainId, - ]); - - const supportedNetworksTable = table([ - [chalk.bold("network"), chalk.bold("chain id")], - ...supportedNetworks, - ]); - - // custom networks - const customNetworks = customChains.map(({ network, chainId }) => [ - network, - chainId, - ]); - - const customNetworksTable = - customNetworks.length > 0 - ? table([ - [chalk.bold("network"), chalk.bold("chain id")], - ...customNetworks, - ]) - : table([["No custom networks were added"]]); - - // print message - console.log( - ` -Networks supported by hardhat-etherscan: - -${supportedNetworksTable} - -Custom networks added by you or by plugins: - -${customNetworksTable} - -To learn how to add custom networks, follow these instructions: https://hardhat.org/verify-custom-networks -`.trimStart() - ); -} - -/** - * Returns the list of constructor arguments from the constructorArgsModule - * or the constructorArgsParams if the first is not defined. - */ -export async function resolveConstructorArguments( - constructorArgsParams: string[], - constructorArgsModule?: string -): Promise { - if (constructorArgsModule === undefined) { - return constructorArgsParams; - } - - if (constructorArgsParams.length > 0) { - throw new ExclusiveConstructorArgumentsError(); - } - - const constructorArgsModulePath = path.resolve( - process.cwd(), - constructorArgsModule - ); - - try { - const constructorArguments = (await import(constructorArgsModulePath)) - .default; - - if (!Array.isArray(constructorArguments)) { - throw new InvalidConstructorArgumentsModuleError( - constructorArgsModulePath - ); - } - - return constructorArguments; - } catch (error: any) { - throw new ImportingModuleError("constructor arguments list", error); - } -} - -/** - * Returns a dictionary of library addresses from the librariesModule or - * an empty object if not defined. - */ -export async function resolveLibraries( - librariesModule?: string -): Promise { - if (librariesModule === undefined) { - return {}; - } - - const librariesModulePath = path.resolve(process.cwd(), librariesModule); - - try { - const libraries = (await import(librariesModulePath)).default; - - if (typeof libraries !== "object" || Array.isArray(libraries)) { - throw new InvalidLibrariesModuleError(librariesModulePath); - } - - return libraries; - } catch (error: any) { - throw new ImportingModuleError("libraries dictionary", error); - } -} - -/** - * Retrieves the list of Solidity compiler versions for a given Solidity - * configuration. - * It checks that the versions are supported by Etherscan, and throws an - * error if any are not. - */ -export async function getCompilerVersions({ - compilers, - overrides, -}: SolidityConfig): Promise { - { - const compilerVersions = compilers.map(({ version }) => version); - if (overrides !== undefined) { - for (const { version } of Object.values(overrides)) { - compilerVersions.push(version); - } - } - - // Etherscan only supports solidity versions higher than or equal to v0.4.11. - // See https://etherscan.io/solcversions - const supportedSolcVersionRange = ">=0.4.11"; - const semver = await import("semver"); - if ( - compilerVersions.some( - (version) => !semver.satisfies(version, supportedSolcVersionRange) - ) - ) { - throw new EtherscanVersionNotSupportedError(); - } - - return compilerVersions; - } -} - -/** - * Encodes the constructor arguments for a given contract. - */ -export async function encodeArguments( - abi: JsonFragment[], - sourceName: string, - contractName: string, - constructorArguments: any[] -): Promise { - const { Interface } = await import("@ethersproject/abi"); - - const contractInterface = new Interface(abi); - let encodedConstructorArguments; - try { - encodedConstructorArguments = contractInterface - .encodeDeploy(constructorArguments) - .replace("0x", ""); - } catch (error) { - if (isABIArgumentLengthError(error)) { - throw new ABIArgumentLengthError(sourceName, contractName, error); - } - if (isABIArgumentTypeError(error)) { - throw new ABIArgumentTypeError(error); - } - if (isABIArgumentOverflowError(error)) { - throw new ABIArgumentOverflowError(error); - } - - // Should be unreachable. - throw error; - } - - return encodedConstructorArguments; -} diff --git a/packages/hardhat-verify/test/.eslintrc.js b/packages/hardhat-verify/test/.eslintrc.js index 12ee5882f1..757fe8a3ca 100644 --- a/packages/hardhat-verify/test/.eslintrc.js +++ b/packages/hardhat-verify/test/.eslintrc.js @@ -1,5 +1,9 @@ module.exports = { extends: [`${__dirname}/../.eslintrc.js`], + parserOptions: { + project: `${__dirname}/../tsconfig.json`, + sourceType: "module", + }, rules: { "import/no-extraneous-dependencies": [ "error", diff --git a/packages/hardhat-verify/test/fixture-projects/hardhat-project/hardhat.config.js b/packages/hardhat-verify/test/fixture-projects/hardhat-project/hardhat.config.js index 1904ad4739..cc01486a97 100644 --- a/packages/hardhat-verify/test/fixture-projects/hardhat-project/hardhat.config.js +++ b/packages/hardhat-verify/test/fixture-projects/hardhat-project/hardhat.config.js @@ -1,4 +1,4 @@ -require("@nomiclabs/hardhat-ethers"); +require("@nomicfoundation/hardhat-ethers"); require("../../../src/index"); @@ -28,4 +28,13 @@ module.exports = { }, ], }, + sourcify: { + enabled: false, + customChains: [ + { + network: "hardhat", + chainId: 31337, + }, + ], + }, }; diff --git a/packages/hardhat-verify/test/helpers.ts b/packages/hardhat-verify/test/helpers.ts index 34b0a46032..24802875be 100644 --- a/packages/hardhat-verify/test/helpers.ts +++ b/packages/hardhat-verify/test/helpers.ts @@ -1,15 +1,18 @@ +import type {} from "@nomicfoundation/hardhat-ethers"; +import type { FactoryOptions, HardhatRuntimeEnvironment } from "hardhat/types"; + import path from "path"; +import debug from "debug"; import { resetHardhatContext } from "hardhat/plugins-testing"; -import type {} from "@nomiclabs/hardhat-ethers"; -import { FactoryOptions, HardhatRuntimeEnvironment } from "hardhat/types"; - declare module "mocha" { interface Context { hre: HardhatRuntimeEnvironment; } } +const log = debug("hardhat:hardhat-verify:tests"); + export const useEnvironment = (fixtureProjectName: string): void => { before("Loading hardhat environment", function () { process.chdir(path.join(__dirname, "fixture-projects", fixtureProjectName)); @@ -34,9 +37,10 @@ export const deployContract = async ( ): Promise => { const factory = await ethers.getContractFactory(contractName, options); const contract = await factory.deploy(...constructorArguments); - await contract.deployTransaction.wait(confirmations); - console.log(`Deployed ${contractName} at ${contract.address}`); - return contract.address; + await contract.deploymentTransaction()?.wait(confirmations); + const contractAddress = await contract.getAddress(); + log(`Deployed ${contractName} at ${contractAddress}`); + return contractAddress; }; export const getRandomAddress = (hre: HardhatRuntimeEnvironment): string => diff --git a/packages/hardhat-verify/test/integration/index.ts b/packages/hardhat-verify/test/integration/index.ts index 1ff457aa67..2c6b43a8c6 100644 --- a/packages/hardhat-verify/test/integration/index.ts +++ b/packages/hardhat-verify/test/integration/index.ts @@ -1,10 +1,15 @@ import fs from "fs"; import path from "path"; -import sinon from "sinon"; +import sinon, { SinonStub } from "sinon"; import { assert, expect } from "chai"; import { TASK_CLEAN, TASK_COMPILE } from "hardhat/builtin-tasks/task-names"; import { SolcConfig } from "hardhat/types/config"; -import { TASK_VERIFY, TASK_VERIFY_VERIFY } from "../../src/task-names"; +import { + TASK_VERIFY, + TASK_VERIFY_ETHERSCAN, + TASK_VERIFY_VERIFY, + TASK_VERIFY_SOURCIFY, +} from "../../src/internal/task-names"; import { deployContract, getRandomAddress, useEnvironment } from "../helpers"; import { interceptGetStatus, @@ -12,23 +17,37 @@ import { interceptVerify, mockEnvironment, } from "./mocks/etherscan"; +import { + interceptSourcifyIsVerified, + interceptSourcifyVerify, + mockEnvironmentSourcify, +} from "./mocks/sourcify"; -import "../../src/type-extensions"; +import "../../src/internal/type-extensions"; describe("verify task integration tests", () => { useEnvironment("hardhat-project"); mockEnvironment(); + // suppress sourcify info message + let consoleInfoStub: SinonStub; + before(() => { + consoleInfoStub = sinon.stub(console, "info"); + }); + + // suppress warnings + after(() => { + consoleInfoStub.restore(); + }); + it("should return after printing the supported networks", async function () { const logStub = sinon.stub(console, "log"); const taskResponse = await this.hre.run(TASK_VERIFY, { - address: getRandomAddress(this.hre), - constructorArgsParams: [], listNetworks: true, }); expect(logStub).to.be.calledOnceWith( - sinon.match(/Networks supported by hardhat-etherscan/) + sinon.match(/Networks supported by hardhat-verify/) ); logStub.restore(); assert.isUndefined(taskResponse); @@ -40,17 +59,18 @@ describe("verify task integration tests", () => { // cleanup the etherscan config since we have hardhat defined as custom chain const originalConfig = this.hre.config.etherscan; this.hre.config.etherscan = { + enabled: true, apiKey: "", customChains: [], }; await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address, constructorArgsParams: [], }) ).to.be.rejectedWith( - "The selected network is hardhat. Please select a network supported by Etherscan." + /The selected network is "hardhat", which is not supported for contract verification./ ); this.hre.config.etherscan = originalConfig; @@ -65,14 +85,15 @@ describe("verify task integration tests", () => { const logStub = sinon.stub(console, "log"); const address = getRandomAddress(this.hre); - const taskResponse = await this.hre.run(TASK_VERIFY, { + const taskResponse = await this.hre.run(TASK_VERIFY_ETHERSCAN, { address, constructorArgsParams: [], }); expect(logStub).to.be.calledOnceWith( - `The contract ${address} has already been verified. -https://hardhat.etherscan.io/address/${address}#code` + `The contract ${address} has already been verified on the block explorer. If you're trying to verify a partially verified contract, please use the --force flag. +https://hardhat.etherscan.io/address/${address}#code +` ); logStub.restore(); assert.isUndefined(taskResponse); @@ -134,7 +155,7 @@ https://hardhat.etherscan.io/address/${address}#code` const address = getRandomAddress(this.hre); await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address, constructorArgsParams: [], }) @@ -153,7 +174,7 @@ https://hardhat.etherscan.io/address/${address}#code` ]; await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: simpleContractAddress, constructorArgsParams: [], }) @@ -168,15 +189,14 @@ https://hardhat.etherscan.io/address/${address}#code` }); describe("with deleted artifacts", () => { - it("should not compile the project when the noCompile is provided", async function () { + it("should throw if the artifacts are missing", async function () { await this.hre.run(TASK_CLEAN); // task will fail since we deleted all the artifacts await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: simpleContractAddress, constructorArgsParams: [], - noCompile: true, }) ).to.be.rejectedWith( /The address provided as argument contains a contract, but its bytecode doesn't match any of your local contracts./ @@ -192,7 +212,7 @@ https://hardhat.etherscan.io/address/${address}#code` it("should throw if the deployed bytecode matches more than one contract", async function () { await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: duplicatedContractAddress, constructorArgsParams: [], }) @@ -205,7 +225,7 @@ https://hardhat.etherscan.io/address/${address}#code` const contractFQN = "contracts/SimpleContract.sol:NotFound"; await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: simpleContractAddress, constructorArgsParams: [], contract: contractFQN, @@ -219,7 +239,7 @@ https://hardhat.etherscan.io/address/${address}#code` it("should throw if there is an invalid address in the libraries parameter", async function () { await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: simpleContractAddress, constructorArgsParams: [], libraries: "invalid-libraries.js", @@ -231,7 +251,7 @@ https://hardhat.etherscan.io/address/${address}#code` it("should throw if the specified library is not used by the contract", async function () { await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: bothLibsContractAddress, constructorArgsParams: [], libraries: "not-used-libraries.js", @@ -243,7 +263,7 @@ https://hardhat.etherscan.io/address/${address}#code` it("should throw if the specified library is listed more than once in the libraries parameter", async function () { await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: onlyNormalLibContractAddress, constructorArgsParams: [], libraries: "duplicated-libraries.js", @@ -255,7 +275,7 @@ https://hardhat.etherscan.io/address/${address}#code` it("should throw if deployed library address does not match the address defined in the libraries parameter", async function () { await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: onlyNormalLibContractAddress, constructorArgsParams: [], libraries: "mismatched-address-libraries.js", @@ -269,7 +289,7 @@ https://hardhat.etherscan.io/address/${address}#code` it("should throw if there are undetectable libraries not specified by the libraries parameter", async function () { await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: bothLibsContractAddress, constructorArgsParams: [], libraries: "missing-undetectable-libraries.js", @@ -284,12 +304,12 @@ This can occur if the library is only called in the contract constructor. The mi it("should throw if the verification request fails", async function () { // do not intercept the verifysourcecode request so it throws an error await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: simpleContractAddress, constructorArgsParams: [], }) ).to.be.rejectedWith( - /Failed to send contract verification request.\nEndpoint URL: https:\/\/api-hardhat.etherscan.io\/api\nReason: getaddrinfo ENOTFOUND api-hardhat.etherscan.io/ + /A network request failed\. This is an error from the block explorer, not Hardhat\. Error: getaddrinfo ENOTFOUND api-hardhat\.etherscan\.io/ ); }); @@ -297,13 +317,13 @@ This can occur if the library is only called in the contract constructor. The mi interceptVerify({ error: "error verifying contract" }, 500); await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: simpleContractAddress, constructorArgsParams: [], }) - ).to.be.rejectedWith(`Failed to send contract verification request. -Endpoint URL: https://api-hardhat.etherscan.io/api -The HTTP server response is not ok. Status code: 500 Response text: {"error":"error verifying contract"}`); + ).to.be.rejectedWith( + /Failed to send contract verification request\.\nEndpoint URL: https:\/\/api-hardhat\.etherscan\.io\/api\n/s + ); }); it("should throw if the etherscan api can't find the bytecode at the contract address", async function () { @@ -312,16 +332,20 @@ The HTTP server response is not ok. Status code: 500 Response text: {"error":"er result: "Unable to locate ContractCode at 0x...", }); - await expect( - this.hre.run(TASK_VERIFY, { + try { + await this.hre.run(TASK_VERIFY_ETHERSCAN, { address: simpleContractAddress, constructorArgsParams: [], - }) - ).to.be.rejectedWith( - new RegExp( - `The Etherscan API responded that the address ${simpleContractAddress} does not have bytecode.` - ) - ); + }); + assert.fail("Expected error was not thrown"); + } catch (e: any) { + assert.match( + e.message, + new RegExp( + `The Etherscan API responded that the address ${simpleContractAddress} does not have bytecode.` + ) + ); + } }); it("should throw if the verification response status is not ok", async function () { @@ -331,7 +355,7 @@ The HTTP server response is not ok. Status code: 500 Response text: {"error":"er }); await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: simpleContractAddress, constructorArgsParams: [], }) @@ -347,11 +371,13 @@ The HTTP server response is not ok. Status code: 500 Response text: {"error":"er const logStub = sinon.stub(console, "log"); await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: simpleContractAddress, constructorArgsParams: [], }) - ).to.be.rejectedWith(/Failure during etherscan status polling./); + ).to.be.rejectedWith( + /A network request failed\. This is an error from the block explorer, not Hardhat\. Error: getaddrinfo ENOTFOUND api-hardhat\.etherscan\.io/ + ); expect(logStub).to.be .calledOnceWith(`Successfully submitted source code for contract @@ -370,7 +396,7 @@ for verification on the block explorer. Waiting for verification result... const logStub = sinon.stub(console, "log"); await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: simpleContractAddress, constructorArgsParams: [], }) @@ -398,7 +424,7 @@ for verification on the block explorer. Waiting for verification result... const logStub = sinon.stub(console, "log"); await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: simpleContractAddress, constructorArgsParams: [], }) @@ -426,7 +452,7 @@ for verification on the block explorer. Waiting for verification result... const logStub = sinon.stub(console, "log"); await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: simpleContractAddress, constructorArgsParams: [], }) @@ -465,8 +491,8 @@ contracts/SimpleContract.sol:SimpleContract at ${simpleContractAddress} for verification on the block explorer. Waiting for verification result... `); expect(logStub.getCall(1)).to.be - .calledWith(`Successfully verified contract SimpleContract on Etherscan. -https://hardhat.etherscan.io/address/${simpleContractAddress}#code`); + .calledWith(`Successfully verified contract SimpleContract on the block explorer. +https://hardhat.etherscan.io/address/${simpleContractAddress}#code\n`); logStub.restore(); assert.isUndefined(taskResponse); }); @@ -515,8 +541,8 @@ contracts/SimpleContract.sol:SimpleContract at ${simpleContractAddress} for verification on the block explorer. Waiting for verification result... `); expect(logStub.getCall(3)).to.be - .calledWith(`Successfully verified contract SimpleContract on Etherscan. -https://hardhat.etherscan.io/address/${simpleContractAddress}#code`); + .calledWith(`Successfully verified contract SimpleContract on the block explorer. +https://hardhat.etherscan.io/address/${simpleContractAddress}#code\n`); logStub.restore(); assert.equal(verifyCallCount, 2); assert.equal(getStatusCallCount, 2); @@ -543,7 +569,7 @@ https://hardhat.etherscan.io/address/${simpleContractAddress}#code`); const logStub = sinon.stub(console, "log"); await expect( - this.hre.run(TASK_VERIFY, { + this.hre.run(TASK_VERIFY_ETHERSCAN, { address: bothLibsContractAddress, constructorArgsParams: ["50"], libraries: "libraries.js", @@ -589,7 +615,6 @@ for verification on the block explorer. Waiting for verification result... NormalLib: normalLibAddress, ConstructorLib: constructorLibAddress, }, - // noCompile: true, }); assert.equal(logStub.callCount, 2); @@ -599,8 +624,186 @@ contracts/WithLibs.sol:BothLibs at ${bothLibsContractAddress} for verification on the block explorer. Waiting for verification result... `); expect(logStub.getCall(1)).to.be - .calledWith(`Successfully verified contract BothLibs on Etherscan. -https://hardhat.etherscan.io/address/${bothLibsContractAddress}#code`); + .calledWith(`Successfully verified contract BothLibs on the block explorer. +https://hardhat.etherscan.io/address/${bothLibsContractAddress}#code\n`); + logStub.restore(); + assert.isUndefined(taskResponse); + }); + + after(async function () { + await this.hre.run(TASK_CLEAN); + }); + }); + + describe("with a verified contract and '--force' flag", () => { + let simpleContractAddress: string; + before(async function () { + await this.hre.run(TASK_COMPILE, { force: true, quiet: true }); + simpleContractAddress = await deployContract( + "SimpleContract", + [], + this.hre + ); + }); + + beforeEach(() => { + interceptIsVerified({ message: "OK", result: [{ SourceCode: "code" }] }); + }); + + it("should validate a partially verified contract", async function () { + interceptVerify({ + status: 1, + result: "ezq878u486pzijkvvmerl6a9mzwhv6sefgvqi5tkwceejc7tvn", + }); + interceptGetStatus(() => { + return { + status: 1, + result: "Pass - Verified", + }; + }); + const logStub = sinon.stub(console, "log"); + + const taskResponse = await this.hre.run(TASK_VERIFY, { + address: simpleContractAddress, + constructorArgsParams: [], + force: true, + }); + + assert.equal(logStub.callCount, 2); + expect(logStub.getCall(0)).to.be + .calledWith(`Successfully submitted source code for contract +contracts/SimpleContract.sol:SimpleContract at ${simpleContractAddress} +for verification on the block explorer. Waiting for verification result... +`); + expect(logStub.getCall(1)).to.be + .calledWith(`Successfully verified contract SimpleContract on the block explorer. +https://hardhat.etherscan.io/address/${simpleContractAddress}#code\n`); + logStub.restore(); + assert.isUndefined(taskResponse); + }); + + it("should throw if the verification response status is 'already verified' (blockscout full matched)", async function () { + interceptVerify({ + status: 0, + result: "Smart-contract already verified.", + }); + + await expect( + this.hre.run(TASK_VERIFY_ETHERSCAN, { + address: simpleContractAddress, + constructorArgsParams: [], + force: true, + }) + ).to.be.rejectedWith( + new RegExp( + `The block explorer's API responded that the contract contracts/SimpleContract.sol:SimpleContract at ${simpleContractAddress} is already verified.` + ) + ); + }); + + // If contract was actually verified, Etherscan returns an error on the verification request. + it("should throw if the verification response status is 'already verified' (etherscan manually verified)", async function () { + interceptVerify({ + status: 0, + result: "Contract source code already verified", + }); + + await expect( + this.hre.run(TASK_VERIFY_ETHERSCAN, { + address: simpleContractAddress, + constructorArgsParams: [], + force: true, + }) + ).to.be.rejectedWith( + new RegExp( + `The block explorer's API responded that the contract contracts/SimpleContract.sol:SimpleContract at ${simpleContractAddress} is already verified.` + ) + ); + }); + + // If contract was verified via matching a deployed bytecode of another contract, + // Etherscan returns an error only on ve get verification status response. + it("should throw if the get verification status is 'already verified' (etherscan automatically verified)", async function () { + interceptVerify({ + status: 1, + result: "ezq878u486pzijkvvmerl6a9mzwhv6sefgvqi5tkwceejc7tvn", + }); + interceptGetStatus(() => { + return { + status: 0, + result: "Already Verified", + }; + }); + const logStub = sinon.stub(console, "log"); + + await expect( + this.hre.run(TASK_VERIFY_ETHERSCAN, { + address: simpleContractAddress, + constructorArgsParams: [], + force: true, + }) + ).to.be.rejectedWith( + new RegExp( + `The block explorer's API responded that the contract contracts/SimpleContract.sol:SimpleContract at ${simpleContractAddress} is already verified.` + ) + ); + + expect(logStub).to.be + .calledOnceWith(`Successfully submitted source code for contract +contracts/SimpleContract.sol:SimpleContract at ${simpleContractAddress} +for verification on the block explorer. Waiting for verification result... +`); + logStub.restore(); + }); + + after(async function () { + await this.hre.run(TASK_CLEAN); + }); + }); +}); + +describe("verify task Sourcify's integration tests", () => { + useEnvironment("hardhat-project"); + mockEnvironmentSourcify(); + + describe("with a non-verified contract", () => { + let simpleContractAddress: string; + + before(async function () { + await this.hre.run(TASK_COMPILE, { force: true, quiet: true }); + simpleContractAddress = await deployContract( + "SimpleContract", + [], + this.hre + ); + }); + + it("should verify a contract on Sourcify", async function () { + interceptSourcifyIsVerified([ + { address: simpleContractAddress, status: "false" }, + ]); + interceptSourcifyVerify({ + result: [ + { + address: simpleContractAddress, + status: "perfect", + }, + ], + }); + const logStub = sinon.stub(console, "log"); + // set network name to localhost to avoid the "hardhat is not supported" error + this.hre.network.name = "localhost"; + + const taskResponse = await this.hre.run(TASK_VERIFY_SOURCIFY, { + address: simpleContractAddress, + contract: "contracts/SimpleContract.sol:SimpleContract", + }); + + assert.equal(logStub.callCount, 1); + (expect(logStub.getCall(0)).to.be as any) + .calledWith(`Successfully verified contract SimpleContract on Sourcify. +https://repo.sourcify.dev/contracts/full_match/31337/${simpleContractAddress}/ +`); logStub.restore(); assert.isUndefined(taskResponse); }); diff --git a/packages/hardhat-verify/test/integration/mocks/sourcify.ts b/packages/hardhat-verify/test/integration/mocks/sourcify.ts new file mode 100644 index 0000000000..e38308b938 --- /dev/null +++ b/packages/hardhat-verify/test/integration/mocks/sourcify.ts @@ -0,0 +1,47 @@ +import { + Dispatcher, + getGlobalDispatcher, + MockAgent, + setGlobalDispatcher, +} from "undici"; + +const mockAgent = new MockAgent({ + keepAliveTimeout: 10, + keepAliveMaxTimeout: 10, +}); + +const client = mockAgent.get("https://sourcify.dev"); + +export const mockEnvironmentSourcify = () => { + let globalDispatcher: Dispatcher; + // enable network connections for everything but etherscan API + mockAgent.enableNetConnect(/^(?!https:\/\/sourcify\.dev)/); + + before(() => { + globalDispatcher = getGlobalDispatcher(); + setGlobalDispatcher(mockAgent); + }); + + after(() => { + setGlobalDispatcher(globalDispatcher); + }); +}; + +export const interceptSourcifyIsVerified = (response: any) => + client + .intercept({ + method: "GET", + path: /\/server\/check-all-by-addresses\?addresses=0x[a-fA-F0-9]{40}&chainIds=[0-9]+/, + }) + .reply(200, response); + +export const interceptSourcifyVerify = ( + response: any, + statusCode: number = 200 +) => + client + .intercept({ + path: "/server", + method: "POST", + }) + .reply(statusCode, response); diff --git a/packages/hardhat-verify/test/unit/chain-config.ts b/packages/hardhat-verify/test/unit/chain-config.ts index 0cebea66d5..075476891f 100644 --- a/packages/hardhat-verify/test/unit/chain-config.ts +++ b/packages/hardhat-verify/test/unit/chain-config.ts @@ -1,128 +1,7 @@ -import type { Network } from "hardhat/types"; -import type { ChainConfig } from "../../src/types"; -import { assert, expect } from "chai"; -import { builtinChains, getCurrentChainConfig } from "../../src/chain-config"; +import { assert } from "chai"; +import { builtinChains } from "../../src/internal/chain-config"; describe("Chain Config", () => { - describe("getCurrentChainConfig", () => { - const customChains: ChainConfig[] = [ - { - network: "customChain1", - chainId: 5000, - urls: { - apiURL: "", - browserURL: "", - }, - }, - { - network: "customChain2", - chainId: 5000, - urls: { - apiURL: "", - browserURL: "", - }, - }, - { - network: "customChain3", - chainId: 4999, - urls: { - apiURL: "", - browserURL: "", - }, - }, - ]; - - it("should return the last matching custom chain defined by the user", async function () { - const network = { - name: "customChain2", - provider: { - async send() { - return (5000).toString(16); - }, - }, - } as unknown as Network; - const chainConfig = await getCurrentChainConfig(network, customChains); - - assert.equal(chainConfig.network, "customChain2"); - assert.equal(chainConfig.chainId, 5000); - }); - - it("should return a built-in chain if no custom chain matches", async function () { - const network = { - name: "goerli", - provider: { - async send() { - return (5).toString(16); - }, - }, - } as unknown as Network; - const chainConfig = await getCurrentChainConfig(network, customChains); - - assert.equal(chainConfig.network, "goerli"); - assert.equal(chainConfig.chainId, 5); - }); - - it("should throw if the selected network is hardhat and it's not a added to custom chains", async () => { - const network = { - name: "hardhat", - provider: { - async send() { - return (31337).toString(16); - }, - }, - } as unknown as Network; - - await expect( - getCurrentChainConfig(network, customChains) - ).to.be.rejectedWith( - "The selected network is hardhat. Please select a network supported by Etherscan." - ); - }); - - it("should return hardhat if the selected network is hardhat and it was added as a custom chain", async () => { - const network = { - name: "hardhat", - provider: { - async send() { - return (31337).toString(16); - }, - }, - } as unknown as Network; - - const chainConfig = await getCurrentChainConfig(network, [ - ...customChains, - { - network: "hardhat", - chainId: 31337, - urls: { - apiURL: "", - browserURL: "", - }, - }, - ]); - - assert.equal(chainConfig.network, "hardhat"); - assert.equal(chainConfig.chainId, 31337); - }); - - it("should throw if there are no matches at all", async () => { - const network = { - name: "someNetwork", - provider: { - async send() { - return (21343214123).toString(16); - }, - }, - } as unknown as Network; - - await expect( - getCurrentChainConfig(network, customChains) - ).to.be.rejectedWith( - /Trying to verify a contract in a network with chain id 21343214123, but the plugin doesn't recognize it as a supported chain./ - ); - }); - }); - describe("builtinChains", () => { it("should have no duplicate chain ids", () => { // check that xdai/gnosis is the only duplicate diff --git a/packages/hardhat-verify/test/unit/config.ts b/packages/hardhat-verify/test/unit/config.ts index 210c2a976d..030d2c4f7c 100644 --- a/packages/hardhat-verify/test/unit/config.ts +++ b/packages/hardhat-verify/test/unit/config.ts @@ -1,14 +1,37 @@ +import type { HardhatConfig, HardhatUserConfig } from "hardhat/types"; +import type { EtherscanConfig, SourcifyConfig } from "../../src/types"; + import sinon from "sinon"; import { assert, expect } from "chai"; -import { HardhatConfig, HardhatUserConfig } from "hardhat/types"; -import { etherscanConfigExtender } from "../../src/config"; -import { EtherscanConfig } from "../../src/types"; -describe("Chain Config", () => { - it("should extend the hardhat config with the user config", async () => { - const hardhatConfig = {} as HardhatConfig; - const userConfig: HardhatUserConfig = { - etherscan: { +import { + etherscanConfigExtender, + sourcifyConfigExtender, +} from "../../src/internal/config"; + +describe("Extend config", () => { + describe("Etherscan config extender", () => { + it("should extend the hardhat config with the user config", async () => { + const hardhatConfig = {} as HardhatConfig; + const userConfig: HardhatUserConfig = { + etherscan: { + apiKey: { + goerli: "", + }, + customChains: [ + { + network: "goerli", + chainId: 5, + urls: { + apiURL: "https://api-goerli.etherscan.io/api", + browserURL: "https://goerli.etherscan.io", + }, + }, + ], + }, + }; + const expected: EtherscanConfig = { + enabled: true, apiKey: { goerli: "", }, @@ -22,58 +45,69 @@ describe("Chain Config", () => { }, }, ], - }, - }; - const expected: EtherscanConfig = { - apiKey: { - goerli: "", - }, - customChains: [ - { - network: "goerli", - chainId: 5, - urls: { - apiURL: "https://api-goerli.etherscan.io/api", - browserURL: "https://goerli.etherscan.io", - }, - }, - ], - }; - etherscanConfigExtender(hardhatConfig, userConfig); + }; + etherscanConfigExtender(hardhatConfig, userConfig); - assert.deepEqual(hardhatConfig.etherscan, expected); - }); + assert.deepEqual(hardhatConfig.etherscan, expected); + }); - it("should override the hardhat config with the user config", async () => { - const hardhatConfig = {} as HardhatConfig; - hardhatConfig.etherscan = { - apiKey: { - goerli: "", - }, - customChains: [ - { - network: "goerli", - chainId: 5, - urls: { - apiURL: "https://api-goerli.etherscan.io/api", - browserURL: "https://goerli.etherscan.io", + it("should override the hardhat config with the user config", async () => { + const hardhatConfig = {} as HardhatConfig; + hardhatConfig.etherscan = { + enabled: true, + apiKey: { + goerli: "", + }, + customChains: [ + { + network: "goerli", + chainId: 5, + urls: { + apiURL: "https://api-goerli.etherscan.io/api", + browserURL: "https://goerli.etherscan.io", + }, + }, + ], + }; + const userConfig: HardhatUserConfig = { + etherscan: { + apiKey: { + mainnet: "", + sepolia: "", }, + customChains: [ + { + network: "mainnet", + chainId: 1, + urls: { + apiURL: "https://api.etherscan.io/api", + browserURL: "https://etherscan.io", + }, + }, + { + network: "sepolia", + chainId: 11155111, + urls: { + apiURL: "https://api-sepolia.etherscan.io/api", + browserURL: "https://sepolia.etherscan.io", + }, + }, + ], }, - ], - }; - const userConfig: HardhatUserConfig = { - etherscan: { + }; + const expected: EtherscanConfig = { + enabled: true, apiKey: { - ropsten: "", + mainnet: "", sepolia: "", }, customChains: [ { - network: "ropsten", - chainId: 3, + network: "mainnet", + chainId: 1, urls: { - apiURL: "https://api-ropsten.etherscan.io/api", - browserURL: "https://ropsten.etherscan.io", + apiURL: "https://api.etherscan.io/api", + browserURL: "https://etherscan.io", }, }, { @@ -85,69 +119,61 @@ describe("Chain Config", () => { }, }, ], - }, - }; - const expected: EtherscanConfig = { - apiKey: { - ropsten: "", - sepolia: "", - }, - customChains: [ - { - network: "ropsten", - chainId: 3, - urls: { - apiURL: "https://api-ropsten.etherscan.io/api", - browserURL: "https://ropsten.etherscan.io", - }, - }, - { - network: "sepolia", - chainId: 11155111, - urls: { - apiURL: "https://api-sepolia.etherscan.io/api", - browserURL: "https://sepolia.etherscan.io", - }, - }, - ], - }; - etherscanConfigExtender(hardhatConfig, userConfig); + }; + etherscanConfigExtender(hardhatConfig, userConfig); - assert.deepEqual(hardhatConfig.etherscan, expected); - }); + assert.deepEqual(hardhatConfig.etherscan, expected); + }); - it("should set default values when user config is not provided", async () => { - const hardhatConfig = {} as HardhatConfig; - const userConfig: HardhatUserConfig = {}; - const expected: EtherscanConfig = { - apiKey: "", - customChains: [], - }; - etherscanConfigExtender(hardhatConfig, userConfig); + it("should set default values when user config is not provided", async () => { + const hardhatConfig = {} as HardhatConfig; + const userConfig: HardhatUserConfig = {}; + const expected: EtherscanConfig = { + enabled: true, + apiKey: "", + customChains: [], + }; + etherscanConfigExtender(hardhatConfig, userConfig); - assert.deepEqual(hardhatConfig.etherscan, expected); - }); + assert.deepEqual(hardhatConfig.etherscan, expected); + }); - it("should display a warning message if there is an etherscan entry in the networks object", async () => { - const warnStub = sinon.stub(console, "warn"); - const hardhatConfig = { - networks: { - etherscan: { - apiKey: { - goerli: "", + it("should display a warning message if there is an etherscan entry in the networks object", async () => { + const warnStub = sinon.stub(console, "warn"); + const hardhatConfig = { + networks: { + etherscan: { + apiKey: { + goerli: "", + }, }, }, - }, - }; - const userConfig: HardhatUserConfig = {}; + }; + const userConfig: HardhatUserConfig = {}; + + // @ts-expect-error + etherscanConfigExtender(hardhatConfig, userConfig); + expect(warnStub).to.be.calledOnceWith( + sinon.match( + /WARNING: you have an 'etherscan' entry in your networks configuration./ + ) + ); + warnStub.restore(); + }); + }); + + describe("Sourcify config extender", () => { + it("should set default values when user config is not provided", async () => { + const hardhatConfig = {} as HardhatConfig; + const userConfig: HardhatUserConfig = {}; + const expected: SourcifyConfig = { + enabled: false, + apiUrl: "https://sourcify.dev/server", + browserUrl: "https://repo.sourcify.dev", + }; + sourcifyConfigExtender(hardhatConfig, userConfig); - // @ts-expect-error - etherscanConfigExtender(hardhatConfig, userConfig); - expect(warnStub).to.be.calledOnceWith( - sinon.match( - /WARNING: you have an 'etherscan' entry in your networks configuration./ - ) - ); - warnStub.restore(); + assert.deepEqual(hardhatConfig.sourcify, expected); + }); }); }); diff --git a/packages/hardhat-verify/test/unit/etherscan.ts b/packages/hardhat-verify/test/unit/etherscan.ts index 0bcdd816c4..3f5de75015 100644 --- a/packages/hardhat-verify/test/unit/etherscan.ts +++ b/packages/hardhat-verify/test/unit/etherscan.ts @@ -1,5 +1,8 @@ +import type { EthereumProvider } from "hardhat/types"; +import type { ChainConfig } from "../../src/types"; + import { assert, expect } from "chai"; -import { Etherscan } from "../../src/etherscan"; +import { Etherscan } from "../../src/internal/etherscan"; describe("Etherscan", () => { const chainConfig = { @@ -13,34 +16,166 @@ describe("Etherscan", () => { describe("constructor", () => { it("should throw if the apiKey is undefined or empty", () => { - expect(() => new Etherscan(undefined, chainConfig)).to.throw( + expect(() => Etherscan.fromChainConfig(undefined, chainConfig)).to.throw( /You are trying to verify a contract in 'goerli', but no API token was found for this network./ ); - expect(() => new Etherscan("", chainConfig)).to.throw( + expect(() => Etherscan.fromChainConfig("", chainConfig)).to.throw( /You are trying to verify a contract in 'goerli', but no API token was found for this network./ ); }); it("should throw if the apiKey is an object but apiKey[network] is undefined or empty", () => { - expect(() => new Etherscan({}, chainConfig)).to.throw( + expect(() => Etherscan.fromChainConfig({}, chainConfig)).to.throw( /You are trying to verify a contract in 'goerli', but no API token was found for this network./ ); - expect(() => new Etherscan({ goerli: "" }, chainConfig)).to.throw( + expect(() => + Etherscan.fromChainConfig({ goerli: "" }, chainConfig) + ).to.throw( /You are trying to verify a contract in 'goerli', but no API token was found for this network./ ); }); }); + describe("getCurrentChainConfig", () => { + const customChains: ChainConfig[] = [ + { + network: "customChain1", + chainId: 5000, + urls: { + apiURL: "", + browserURL: "", + }, + }, + { + network: "customChain2", + chainId: 5000, + urls: { + apiURL: "", + browserURL: "", + }, + }, + { + network: "customChain3", + chainId: 4999, + urls: { + apiURL: "", + browserURL: "", + }, + }, + ]; + + it("should return the last matching custom chain defined by the user", async function () { + const networkName = "customChain2"; + const ethereumProvider = { + async send() { + return (5000).toString(16); + }, + } as unknown as EthereumProvider; + + const currentChainConfig = await Etherscan.getCurrentChainConfig( + networkName, + ethereumProvider, + customChains + ); + + assert.equal(currentChainConfig.network, networkName); + assert.equal(currentChainConfig.chainId, 5000); + }); + + it("should return a built-in chain if no custom chain matches", async function () { + const networkName = "goerli"; + const ethereumProvider = { + async send() { + return (5).toString(16); + }, + } as unknown as EthereumProvider; + const currentChainConfig = await Etherscan.getCurrentChainConfig( + networkName, + ethereumProvider, + customChains + ); + + assert.equal(currentChainConfig.network, networkName); + assert.equal(currentChainConfig.chainId, 5); + }); + + it("should throw if the selected network is hardhat and it's not added to custom chains", async () => { + const networkName = "hardhat"; + const ethereumProvider = { + async send() { + return (31337).toString(16); + }, + } as unknown as EthereumProvider; + + await expect( + Etherscan.getCurrentChainConfig( + networkName, + ethereumProvider, + customChains + ) + ).to.be.rejectedWith( + /The selected network is "hardhat", which is not supported for contract verification./ + ); + }); + + it("should return hardhat if the selected network is hardhat and it was added as a custom chain", async () => { + const networkName = "hardhat"; + const ethereumProvider = { + async send() { + return (31337).toString(16); + }, + } as unknown as EthereumProvider; + + const currentChainConfig = await Etherscan.getCurrentChainConfig( + networkName, + ethereumProvider, + [ + ...customChains, + { + network: "hardhat", + chainId: 31337, + urls: { + apiURL: "", + browserURL: "", + }, + }, + ] + ); + + assert.equal(currentChainConfig.network, networkName); + assert.equal(currentChainConfig.chainId, 31337); + }); + + it("should throw if there are no matches at all", async () => { + const networkName = "someNetwork"; + const ethereumProvider = { + async send() { + return (21343214123).toString(16); + }, + } as unknown as EthereumProvider; + + await expect( + Etherscan.getCurrentChainConfig( + networkName, + ethereumProvider, + customChains + ) + ).to.be.rejectedWith( + /Trying to verify a contract in a network with chain id 21343214123, but the plugin doesn't recognize it as a supported chain./ + ); + }); + }); + describe("getContractUrl", () => { it("should return the contract url", () => { const expectedContractAddress = "https://goerli.etherscan.io/address/someAddress#code"; - let etherscan = new Etherscan("someApiKey", chainConfig); + let etherscan = Etherscan.fromChainConfig("someApiKey", chainConfig); let contractUrl = etherscan.getContractUrl("someAddress"); assert.equal(contractUrl, expectedContractAddress); - etherscan = new Etherscan("someApiKey", { + etherscan = Etherscan.fromChainConfig("someApiKey", { network: "goerli", chainId: 5, urls: { diff --git a/packages/hardhat-verify/test/unit/index.ts b/packages/hardhat-verify/test/unit/index.ts index 46ec2fe913..946fa51834 100644 --- a/packages/hardhat-verify/test/unit/index.ts +++ b/packages/hardhat-verify/test/unit/index.ts @@ -1,17 +1,24 @@ +import type { VerificationSubtask } from "../.."; import { assert, expect } from "chai"; +import sinon, { SinonStub } from "sinon"; + import { - TASK_VERIFY_RESOLVE_ARGUMENTS, + TASK_VERIFY_ETHERSCAN, + TASK_VERIFY_GET_VERIFICATION_SUBTASKS, + TASK_VERIFY_ETHERSCAN_RESOLVE_ARGUMENTS, + TASK_VERIFY_SOURCIFY, + TASK_VERIFY_SOURCIFY_DISABLED_WARNING, TASK_VERIFY_VERIFY, -} from "../../src/task-names"; +} from "../../src/internal/task-names"; import { getRandomAddress, useEnvironment } from "../helpers"; describe("verify task", () => { useEnvironment("hardhat-project"); - describe("verify:resolve-arguments", () => { + describe(TASK_VERIFY_ETHERSCAN_RESOLVE_ARGUMENTS, () => { it("should throw if address is not provided", async function () { await expect( - this.hre.run(TASK_VERIFY_RESOLVE_ARGUMENTS, { + this.hre.run(TASK_VERIFY_ETHERSCAN_RESOLVE_ARGUMENTS, { constructorArgsParams: [], constructorArgs: "constructor-args.js", libraries: "libraries.js", @@ -21,7 +28,7 @@ describe("verify task", () => { it("should throw if address is invalid", async function () { await expect( - this.hre.run(TASK_VERIFY_RESOLVE_ARGUMENTS, { + this.hre.run(TASK_VERIFY_ETHERSCAN_RESOLVE_ARGUMENTS, { address: "invalidAddress", constructorArgsParams: [], constructorArgs: "constructor-args.js", @@ -32,7 +39,7 @@ describe("verify task", () => { it("should throw if contract is not a fully qualified name", async function () { await expect( - this.hre.run(TASK_VERIFY_RESOLVE_ARGUMENTS, { + this.hre.run(TASK_VERIFY_ETHERSCAN_RESOLVE_ARGUMENTS, { address: getRandomAddress(this.hre), constructorArgsParams: [], constructorArgs: "constructor-args.js", @@ -42,7 +49,7 @@ describe("verify task", () => { ).to.be.rejectedWith(/A valid fully qualified name was expected./); }); - it("should return the proccesed arguments", async function () { + it("should return the processed arguments", async function () { const address = getRandomAddress(this.hre); const expectedArgs = { address, @@ -60,54 +67,24 @@ describe("verify task", () => { ConstructorLib: "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9", }, contractFQN: "contracts/TestContract.sol:TestContract", - listNetworks: true, - noCompile: true, + force: false, }; - const proccesedArgs = await this.hre.run(TASK_VERIFY_RESOLVE_ARGUMENTS, { - address, - constructorArgsParams: [], - constructorArgs: "constructor-args.js", - libraries: "libraries.js", - contract: "contracts/TestContract.sol:TestContract", - listNetworks: true, - noCompile: true, - }); - - assert.deepEqual(proccesedArgs, expectedArgs); - }); - }); - - describe("verify:verify", () => { - it("should throw if address is not provided", async function () { - await expect( - this.hre.run(TASK_VERIFY_VERIFY, { - constructorArguments: [], - libraries: {}, - }) - ).to.be.rejectedWith(/You didn’t provide any address./); - }); - - it("should throw if address is invalid", async function () { - await expect( - this.hre.run(TASK_VERIFY_VERIFY, { - address: "invalidAddress", - constructorArguments: [], - libraries: {}, - }) - ).to.be.rejectedWith(/invalidAddress is an invalid address./); - }); + const processedArgs = await this.hre.run( + TASK_VERIFY_ETHERSCAN_RESOLVE_ARGUMENTS, + { + address, + constructorArgsParams: [], + constructorArgs: "constructor-args.js", + libraries: "libraries.js", + contract: "contracts/TestContract.sol:TestContract", + } + ); - it("should throw if contract is not a fully qualified name", async function () { - await expect( - this.hre.run(TASK_VERIFY_VERIFY, { - address: getRandomAddress(this.hre), - constructorArguments: [], - libraries: {}, - contract: "not-a-fully-qualified-name", - }) - ).to.be.rejectedWith(/A valid fully qualified name was expected./); + assert.deepEqual(processedArgs, expectedArgs); }); + }); + describe(TASK_VERIFY_VERIFY, () => { it("should throw if constructorArguments is not an array", async function () { await expect( this.hre.run(TASK_VERIFY_VERIFY, { @@ -130,4 +107,129 @@ describe("verify task", () => { ).to.be.rejectedWith(/The libraries parameter should be a dictionary./); }); }); + + describe(TASK_VERIFY_GET_VERIFICATION_SUBTASKS, () => { + // suppress warnings + let warnStub: SinonStub; + beforeEach(() => { + warnStub = sinon.stub(console, "warn"); + }); + afterEach(() => { + warnStub.restore(); + }); + + it("should return the etherscan subtask by default", async function () { + const verificationSubtasks: VerificationSubtask[] = await this.hre.run( + TASK_VERIFY_GET_VERIFICATION_SUBTASKS + ); + + assert.isTrue( + verificationSubtasks.some( + ({ subtaskName }) => subtaskName === TASK_VERIFY_ETHERSCAN + ) + ); + }); + + it("should return the etherscan subtask if it is enabled", async function () { + const originalConfig = this.hre.config.etherscan; + this.hre.config.etherscan = { + enabled: true, + apiKey: "", + customChains: [], + }; + + const verificationSubtasks: VerificationSubtask[] = await this.hre.run( + TASK_VERIFY_GET_VERIFICATION_SUBTASKS + ); + + this.hre.config.etherscan = originalConfig; + + assert.isTrue( + verificationSubtasks.some( + ({ subtaskName }) => subtaskName === TASK_VERIFY_ETHERSCAN + ) + ); + }); + + it("should ignore the etherscan subtask if it is disabled", async function () { + const originalConfig = this.hre.config.etherscan; + this.hre.config.etherscan = { + enabled: false, + apiKey: "", + customChains: [], + }; + + const verificationSubtasks: VerificationSubtask[] = await this.hre.run( + TASK_VERIFY_GET_VERIFICATION_SUBTASKS + ); + + this.hre.config.etherscan = originalConfig; + + assert.isFalse( + verificationSubtasks.some( + ({ subtaskName }) => subtaskName === TASK_VERIFY_ETHERSCAN + ) + ); + }); + + it("should ignore the sourcify subtask by default", async function () { + const verificationSubtasks: VerificationSubtask[] = await this.hre.run( + TASK_VERIFY_GET_VERIFICATION_SUBTASKS + ); + + assert.isFalse( + verificationSubtasks.some( + ({ subtaskName }) => subtaskName === TASK_VERIFY_SOURCIFY + ) + ); + }); + + it("should return the sourcify subtask if it is enabled", async function () { + const originalConfig = this.hre.config.sourcify; + this.hre.config.sourcify = { + enabled: true, + }; + + const verificationSubtasks: VerificationSubtask[] = await this.hre.run( + TASK_VERIFY_GET_VERIFICATION_SUBTASKS + ); + + this.hre.config.sourcify = originalConfig; + + assert.isTrue( + verificationSubtasks.some( + ({ subtaskName }) => subtaskName === TASK_VERIFY_SOURCIFY + ) + ); + assert.isFalse( + verificationSubtasks.some( + ({ subtaskName }) => + subtaskName === TASK_VERIFY_SOURCIFY_DISABLED_WARNING + ) + ); + }); + + it("should provide a warning message if both etherscan and sourcify are disabled", async function () { + const originalEtherscanConfig = this.hre.config.etherscan; + this.hre.config.etherscan = { + enabled: false, + apiKey: "", + customChains: [], + }; + const originalSourcifyConfig = this.hre.config.etherscan; + this.hre.config.sourcify = { + enabled: false, + }; + + await this.hre.run(TASK_VERIFY_GET_VERIFICATION_SUBTASKS); + + this.hre.config.etherscan = originalEtherscanConfig; + this.hre.config.sourcify = originalSourcifyConfig; + + assert.isTrue(warnStub.calledOnce); + expect(warnStub).to.be.calledWith( + sinon.match(/\[WARNING\] No verification services are enabled./) + ); + }); + }); }); diff --git a/packages/hardhat-verify/test/unit/solc/artifacts.ts b/packages/hardhat-verify/test/unit/solc/artifacts.ts index ebef87e0f3..ac9fa2a007 100644 --- a/packages/hardhat-verify/test/unit/solc/artifacts.ts +++ b/packages/hardhat-verify/test/unit/solc/artifacts.ts @@ -1,11 +1,13 @@ +import type { CompilerOutputBytecode } from "hardhat/types"; + import { assert } from "chai"; -import { CompilerOutputBytecode } from "hardhat/types"; + import { ByteOffset, getCallProtectionOffsets, getImmutableOffsets, getLibraryOffsets, -} from "../../../src/solc/artifacts"; +} from "../../../src/internal/solc/artifacts"; describe("artifacts", () => { describe("getLibraryOffsets", () => { diff --git a/packages/hardhat-verify/test/unit/solc/metadata.ts b/packages/hardhat-verify/test/unit/solc/metadata.ts index b7adeea603..ed4a0e6b22 100644 --- a/packages/hardhat-verify/test/unit/solc/metadata.ts +++ b/packages/hardhat-verify/test/unit/solc/metadata.ts @@ -2,7 +2,7 @@ import { assert } from "chai"; import { getMetadataSectionLength, inferCompilerVersion, -} from "../../../src/solc/metadata"; +} from "../../../src/internal/solc/metadata"; describe("Metadata Decoder", () => { describe("inferCompilerVersion", () => { diff --git a/packages/hardhat-verify/test/unit/sourcify.ts b/packages/hardhat-verify/test/unit/sourcify.ts new file mode 100644 index 0000000000..87d288e41f --- /dev/null +++ b/packages/hardhat-verify/test/unit/sourcify.ts @@ -0,0 +1,25 @@ +import { assert } from "chai"; +import { Sourcify } from "../../src/sourcify"; +import { ContractStatus } from "../../src/internal/sourcify.types"; + +describe("Sourcify", () => { + const chainId = 100; + + describe("getContractUrl", () => { + it("should return the contract url", () => { + const expectedContractAddress = + "https://repo.sourcify.dev/contracts/full_match/100/0xC4c622862a8F548997699bE24EA4bc504e5cA865/"; + const sourcify = new Sourcify( + chainId, + "https://sourcify.dev/server", + "https://repo.sourcify.dev" + ); + const contractUrl = sourcify.getContractUrl( + "0xC4c622862a8F548997699bE24EA4bc504e5cA865", + ContractStatus.PERFECT + ); + + assert.equal(contractUrl, expectedContractAddress); + }); + }); +}); diff --git a/packages/hardhat-verify/test/unit/utilities.ts b/packages/hardhat-verify/test/unit/utilities.ts index 88ac13067f..d82f0fb79d 100644 --- a/packages/hardhat-verify/test/unit/utilities.ts +++ b/packages/hardhat-verify/test/unit/utilities.ts @@ -1,15 +1,85 @@ +import type { JsonFragment } from "@ethersproject/abi"; +import type { SolidityConfig } from "hardhat/types"; +import type { ChainConfig } from "../../src/types"; + import path from "path"; import { assert, expect } from "chai"; -import { SolidityConfig } from "hardhat/types"; -import { JsonFragment } from "@ethersproject/abi"; +import sinon from "sinon"; +import picocolors from "picocolors"; + import { encodeArguments, getCompilerVersions, + printSupportedNetworks, + printVerificationErrors, resolveConstructorArguments, resolveLibraries, -} from "../../src/utilities"; +} from "../../src/internal/utilities"; +import { HardhatVerifyError } from "../../src/internal/errors"; +import { builtinChains } from "../../src/internal/chain-config"; describe("Utilities", () => { + describe("printSupportedNetworks", () => { + it("should print supported and custom networks", async () => { + const customChains: ChainConfig[] = [ + { + network: "MyNetwork", + chainId: 1337, + urls: { + apiURL: "https://api.mynetwork.io/api", + browserURL: "https://mynetwork.io", + }, + }, + ]; + + const logStub = sinon.stub(console, "log"); + + await printSupportedNetworks(customChains); + + sinon.restore(); + + assert.isTrue(logStub.calledOnce); + const actualTableOutput = logStub.getCall(0).args[0]; + const allChains = [...builtinChains, ...customChains]; + allChains.forEach(({ network, chainId }) => { + const regex = new RegExp(`║\\s*${network}\\s*│\\s*${chainId}\\s*║`); + assert.isTrue(regex.test(actualTableOutput)); + }); + }); + }); + + describe("printVerificationErrors", () => { + it("should print verification errors", () => { + const errors: Record = { + Etherscan: new HardhatVerifyError("Etherscan error message"), + Sourcify: new HardhatVerifyError("Sourcify error message"), + }; + + const errorStub = sinon.stub(console, "error"); + + printVerificationErrors(errors); + + sinon.restore(); + + assert.isTrue(errorStub.calledOnce); + const errorMessage = errorStub.getCall(0).args[0]; + assert.equal( + errorMessage, + picocolors.red( + `hardhat-verify found one or more errors during the verification process: + +Etherscan: +Etherscan error message + +Sourcify: +Sourcify error message + +` + ) + ); + }); + }); + describe("resolveConstructorArguments", () => { it("should return the constructorArgsParams if constructorArgsModule is not defined", async () => { const constructorArgsParams = ["1", "arg2", "false"]; @@ -467,6 +537,39 @@ but 2 arguments were provided instead.`); ); }); + it("should throw if a parameter type does not match its expected type: number instead of string", async () => { + const abi: JsonFragment[] = [ + { + inputs: [ + { + name: "amount", + type: "uint256", + }, + { + name: "amount", + type: "string", + }, + { + name: "amount", + type: "address", + }, + ], + stateMutability: "nonpayable", + type: "constructor", + }, + ]; + const constructorArguments: any[] = [ + 50, + 50, // Invalid string + "0x752C8191E6b1Db38B41A8c8921F7a703F2969d18", + ]; + await expect( + encodeArguments(abi, sourceName, contractName, constructorArguments) + ).to.be.rejectedWith( + /Value 50 cannot be encoded for the parameter amount./ + ); + }); + it("should throw if an unsafe integer is provided as an argument", async () => { const abi: JsonFragment[] = [ { diff --git a/packages/hardhat-verify/tsconfig.json b/packages/hardhat-verify/tsconfig.json index 1bf285e948..65ecfc33b9 100644 --- a/packages/hardhat-verify/tsconfig.json +++ b/packages/hardhat-verify/tsconfig.json @@ -1,16 +1,15 @@ { "extends": "../../config/typescript/tsconfig.json", "compilerOptions": { - "outDir": "./dist", + "outDir": "./build-test", + "rootDirs": ["./test"], "composite": true }, - "exclude": ["./dist", "./node_modules", "./test/**/hardhat.config.ts"], + "include": ["./test/**/*.ts"], + "exclude": ["./node_modules", "./test/**/hardhat.config.ts"], "references": [ { - "path": "../hardhat-core/src" - }, - { - "path": "../hardhat-ethers/src" + "path": "./src" } ] } diff --git a/packages/hardhat-viem/.eslintignore b/packages/hardhat-viem/.eslintignore new file mode 100644 index 0000000000..54bbdb1232 --- /dev/null +++ b/packages/hardhat-viem/.eslintignore @@ -0,0 +1,8 @@ +.eslintrc.js + +*.d.ts +index.js + +/build-test +/internal +/test/fixture-projects diff --git a/packages/hardhat-viem/.eslintrc.js b/packages/hardhat-viem/.eslintrc.js new file mode 100644 index 0000000000..13139c79c6 --- /dev/null +++ b/packages/hardhat-viem/.eslintrc.js @@ -0,0 +1,24 @@ +const { + slowImportsCommonIgnoredModules, +} = require("../../config/eslint/constants"); + +module.exports = { + extends: [`${__dirname}/../../config/eslint/eslintrc.js`], + parserOptions: { + project: `${__dirname}/src/tsconfig.json`, + sourceType: "module", + }, + overrides: [ + { + files: ["src/index.ts"], + rules: { + "@nomicfoundation/slow-imports/no-top-level-external-import": [ + "error", + { + ignoreModules: [...slowImportsCommonIgnoredModules], + }, + ], + }, + }, + ], +}; diff --git a/packages/hardhat-viem/.gitignore b/packages/hardhat-viem/.gitignore new file mode 100644 index 0000000000..8e1785ba1e --- /dev/null +++ b/packages/hardhat-viem/.gitignore @@ -0,0 +1,98 @@ +# Node modules +/node_modules + +# Compilation output +/build-test/ +/dist + +# Code coverage artifacts +/coverage +/.nyc_output + +/*.js +!/.eslintrc.js +/*.js.map +/*.d.ts +/*.d.ts.map +/builtin-tasks +/common +/internal +/types +/utils + +# Below is Github's node gitignore template, +# ignoring the node_modules part, as it'd ignore every node_modules, and we have some for testing + +# Logs +logs +*.log + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +#node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'pnpm pack' +*.tgz + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +test/fixture-projects/*/artifacts +test/fixture-projects/*/cache diff --git a/packages/hardhat-viem/.mocharc.json b/packages/hardhat-viem/.mocharc.json new file mode 100644 index 0000000000..cc5f5768f7 --- /dev/null +++ b/packages/hardhat-viem/.mocharc.json @@ -0,0 +1,6 @@ +{ + "require": "ts-node/register/files", + "file": "./test/setup.ts", + "ignore": ["test/fixture-projects/**/*", "test/update-snapshots.ts"], + "timeout": 10000 +} diff --git a/packages/hardhat-viem/.prettierignore b/packages/hardhat-viem/.prettierignore new file mode 100644 index 0000000000..4c9a81a3da --- /dev/null +++ b/packages/hardhat-viem/.prettierignore @@ -0,0 +1,12 @@ +/node_modules +/internal +/*.d.ts +/*.d.ts.map +/*.js +/*.js.map +/build-test +/test/fixture-projects/**/artifacts +/test/fixture-projects/**/cache +/test/fixture-projects/**/snapshots +CHANGELOG.md +.nyc_output diff --git a/packages/hardhat-viem/CHANGELOG.md b/packages/hardhat-viem/CHANGELOG.md new file mode 100644 index 0000000000..fc7b790e90 --- /dev/null +++ b/packages/hardhat-viem/CHANGELOG.md @@ -0,0 +1,67 @@ +# @nomicfoundation/hardhat-viem + +## 2.0.6 + +### Patch Changes + +- 90bcfda: Remove unnecessary peerDependency + +## 2.0.5 + +### Patch Changes + +- 6010386: Moved types to `HardhatViemHelpers` and initialized `ContractTypesMap` as empty for better extensibility. Improved performance by disabling retries in dev nets (thanks @TateB!) + +## 2.0.4 + +### Patch Changes + +- efa905d: Fix for corrupted Hardhat peer dependency version from pnpm. + +## 2.0.3 + +### Patch Changes + +- a8a6038: Added `ContractTypesMap` to simplify contract type imports (thanks @beepidibop!) + +## 2.0.2 + +### Patch Changes + +- ccb0ace: Added support for library linking (thanks @Chlebamaticon!) + +## 2.0.1 + +### Patch Changes + +- a181462: Fix to add guard for updated `TransactionReceipt` type in `viem` + +## 2.0.0 + +### Major Changes + +- e4b1c07b7: Upgraded hardhat-viem to support viem@2 + +## 1.0.4 + +### Patch Changes + +- 29516eb: Fixed broken link in network error message (thanks @sunsetlover36!). + +## 1.0.3 + +### Patch Changes + +- ffb301f14: Improved loading performance + +## 1.0.2 + +### Patch Changes + +- b521c2a05: Add configurable public client to getContractAt, deployContract and sendDeploymentTransaction + +## 1.0.1 + +### Patch Changes + +- 4943519d0: Fixed an issue with development networks using custom chain ids diff --git a/packages/hardhat-viem/LICENSE b/packages/hardhat-viem/LICENSE new file mode 100644 index 0000000000..3b7e8c7eab --- /dev/null +++ b/packages/hardhat-viem/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Nomic Foundation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/hardhat-viem/README.md b/packages/hardhat-viem/README.md new file mode 100644 index 0000000000..30e8aac08a --- /dev/null +++ b/packages/hardhat-viem/README.md @@ -0,0 +1,269 @@ +[![npm](https://img.shields.io/npm/v/@nomicfoundation/hardhat-viem.svg)](https://www.npmjs.com/package/@nomicfoundation/hardhat-viem) [![hardhat](https://hardhat.org/buidler-plugin-badge.svg?1)](https://hardhat.org) + +# hardhat-viem + +[Hardhat](https://hardhat.org) plugin for integration with [Viem](https://github.com/wagmi-dev/viem), a lightweight, composable, and type-safe Ethereum library. + +## What + +This plugin integrates the Viem Ethereum library into your Hardhat development environment. Viem is an alternative to [ethers.js](https://docs.ethers.io/) that offers developers a different way to interact with the Ethereum blockchain. + +By installing and configuring `hardhat-viem`, you gain access to the capabilities of the Viem library directly within your Hardhat projects. This integration enables you to perform various Ethereum-related tasks using Viem's features and functionalities. + +Note: This plugin relies on the Viem library, so familiarity with [Viem's documentation](https://viem.sh/docs/getting-started.html) can enhance your experience when working with `hardhat-viem`. + +## Installation + +```bash +npm install --save-dev @nomicfoundation/hardhat-viem viem +``` + +And add the following statement to your `hardhat.config.js`: + +```js +require("@nomicfoundation/hardhat-viem"); +``` + +Or, if you are using TypeScript, add this to your `hardhat.config.ts`: + +```js +import "@nomicfoundation/hardhat-viem"; +``` + +**Note:** you might want to pin Viem-related dependencies because Viem does not strictly follow semantic versioning for type changes. You can read more [here](https://hardhat.org/hardhat-runner/docs/advanced/using-viem#managing-types-and-version-stability). + +## Required plugins + +No plugins dependencies. + +## Tasks + +This plugin creates no additional tasks. + +## Environment extensions + +This plugins adds a `viem` object to the Hardhat Runtime Environment which provides a minimal set of capabilities for interacting with the blockchain. + +### Clients + +Viem supports three types of clients: + +#### Public client + +A Public Client is an interface to "public" JSON-RPC API methods such as retrieving block numbers, transactions, reading from smart contracts, etc through [Public Actions](https://viem.sh/docs/actions/public/introduction.html). + +```typescript +import hre from "hardhat"; + +const publicClient = await hre.viem.getPublicClient(); + +const blockNumber = await publicClient.getBlockNumber(); + +const balance = await publicClient.getBalance({ + address: "0xA0Cf798816D4b9b9866b5330EEa46a18382f251e", +}); +``` + +#### Wallet client + +A Wallet Client is an interface to interact with Ethereum Accounts and provides the ability to retrieve accounts, execute transactions, sign messages, etc. through [Wallet Actions](https://viem.sh/docs/actions/wallet/introduction.html). + +```typescript +import hre from "hardhat"; + +const [fromWalletClient, toWalletClient] = await hre.viem.getWalletClients(); + +const hash = await fromWalletClient.sendTransaction({ + to: toWalletClient.account.address, + value: parseEther("0.0001"), +}); +``` + +```typescript +import hre from "hardhat"; + +const walletClient = await hre.viem.getWalletClient( + "0xA0Cf798816D4b9b9866b5330EEa46a18382f251e" +); + +const signature = await walletClient.signMessage({ + account, + message: "hello world", +}); +``` + +#### Test client + +A Test Client is an interface to "test" JSON-RPC API methods such as mining blocks, impersonating accounts, setting fees, etc. through [Test Actions](https://viem.sh/docs/actions/test/introduction.html). + +```typescript +import hre from "hardhat"; + +const testClient = await hre.viem.getTestClient(); + +await testClient.mine({ + blocks: 1000000, +}); +``` + +#### Client options + +You can pass options to the `getPublicClient`, `getWalletClient`, and `getTestClient` methods to customize the client's behavior. + +```typescript +import hre from "hardhat"; + +const publicClient = await hre.viem.getPublicClient({ + pollingInterval: 1000, + cacheTime: 2000, +}); +``` + +For a complete list of options, see: + +- [Public client parameters](https://viem.sh/docs/clients/public.html#parameters) +- [Wallet client parameters](https://viem.sh/docs/clients/wallet.html#parameters) +- [Test client parameters](https://viem.sh/docs/clients/test.html#parameters) + +### Contracts + +The `viem` object provides convenient methods for deploying and interacting with smart contracts on the blockchain. + +#### Deploying a Contract + +To deploy a contract to the blockchain, use the `deployContract` method: + +```typescript +import hre from "hardhat"; + +const contract = await hre.viem.deployContract("contractName", [ + "arg1", + 50, + "arg3", +]); +``` + +By default, the first wallet client retrieved by `hre.viem.getWalletClients()` is used to deploy the contract. You can also specify a different wallet client by passing a third parameter, along with other properties, such as `gas` and `value`: + +```typescript +import hre from "hardhat"; + +const [_, secondWalletClient] = await hre.viem.getWalletClients(); + +const contractA = await hre.viem.deployContract( + "contractName", + ["arg1", 50, "arg3"], + { + client: { wallet: secondWalletClient } + gas: 1000000, + value: parseEther("0.0001"), + confirmations: 5, // 1 by default + } +); +``` + +#### Retrieving an Existing Contract + +If the contract is already deployed, you can retrieve an instance of it using the `getContractAt` method: + +```typescript +import hre from "hardhat"; + +const contract = await hre.viem.getContractAt( + "contractName", + "0x1234567890123456789012345678901234567890" +); +``` + +By default, the first wallet client retrieved by `hre.viem.getWalletClients()` will be used for interacting with the contract. If you want to specify a different wallet client, you can do so by passing it as a third parameter, just like when deploying a contract: + +```typescript +import hre from "hardhat"; + +const [_, secondWalletClient] = await hre.viem.getWalletClients(); + +const contract = await hre.viem.getContractAt( + "contractName", + "0x1234567890123456789012345678901234567890", + { client: { wallet: secondWalletClient } } +); +``` + +#### Interacting with Contracts + +Once you have an instance of a contract, you can interact with it by calling its methods: + +```typescript +let response = await contract.read.method1(); +await contract.write.method2([10, "arg2"]); +``` + +##### Send deployment transaction + +By default, the `deployContract` method sends a deployment transaction to the blockchain and waits for the transaction to be mined. If you want to send the transaction without waiting for it to be mined, you can do so by using `sendDeploymentTransaction`: + +```typescript +import hre from "hardhat"; + +const { contract: contractName, deploymentTransaction } = + await hre.viem.sendDeploymentTransaction( + "contractName", + ["arg1", 50, "arg3"], + { + client: { wallet: secondWalletClient }, + gas: 1000000, + value: parseEther("0.0001"), + } + ); +``` + +Then, if you want to wait for the transaction to be mined, you can do: + +```typescript +import hre from "hardhat"; + +const publicClient = await hre.viem.getPublicClient(); +const { contractAddress } = await publicClient.waitForTransactionReceipt({ + hash: deploymentTransaction.hash, +}); +``` + +##### Library linking + +Some contracts need to be linked with libraries before they are deployed. You can pass the addresses of their libraries to the `deployContract` and `sendDeploymentTransaction` functions with an object like this: + +```typescript +const contractA = await hre.viem.deployContract( + "contractName", + ["arg1", 50, "arg3"], + { + libraries: { + ExampleLib: "0x...", + }, + } +); +``` + +This allows you to deploy a contract linked to the `ExampleLib` library at the address `"0x..."`. + +To deploy a contract, all libraries must be linked. An error will be thrown if any libraries are missing. + +#### Using `ContractTypesMap` for easier contract type imports + +To simplify importing contract types in `hardhat-viem`, you can use the `ContractTypesMap`. This map contains the contract types of all contracts in your project, indexed by their names. + +```typescript +import { ContractTypesMap } from "hardhat/types/artifacts"; + +const contract: ContractTypesMap["ContractName"]; +``` + +This reduces the need for multiple imports and makes your code cleaner and easier to manage. + +## Usage + +There are no additional steps you need to take for this plugin to work. + +Install it and access Viem through the Hardhat Runtime Environment anywhere you need it (tasks, scripts, tests, etc). + +Read the documentation on the [Hardhat Runtime Environment](https://hardhat.org/hardhat-runner/docs/advanced/hardhat-runtime-environment) to learn how to access the HRE in different ways to use Viem from anywhere the HRE is accessible. diff --git a/packages/hardhat-viem/package.json b/packages/hardhat-viem/package.json new file mode 100644 index 0000000000..5832d87e86 --- /dev/null +++ b/packages/hardhat-viem/package.json @@ -0,0 +1,79 @@ +{ + "name": "@nomicfoundation/hardhat-viem", + "version": "2.0.6", + "description": "Hardhat plugin for viem", + "homepage": "https://github.com/nomicfoundation/hardhat/tree/main/packages/hardhat-viem", + "repository": "github:nomicfoundation/hardhat", + "author": "Nomic Foundation", + "license": "MIT", + "main": "index.js", + "types": "index.d.ts", + "keywords": [ + "ethereum", + "smart-contracts", + "hardhat", + "hardhat-plugin", + "viem" + ], + "scripts": { + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", + "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", + "prettier": "prettier \"**/*.{js,md,json}\"", + "pretest": "cd ../.. && pnpm build", + "test": "mocha --recursive \"test/**/*.ts\" -c --exit", + "snapshots:update": "ts-node test/update-snapshots.ts", + "coverage": "nyc pnpm test -- --reporter min", + "build": "tsc --build .", + "prepublishOnly": "pnpm build", + "clean": "rimraf internal *.{d.ts,js}{,.map} build-test tsconfig.tsbuildinfo" + }, + "files": [ + "src/", + "internal/", + "*.d.ts", + "*.d.ts.map", + "*.js", + "*.js.map", + "LICENSE", + "README.md" + ], + "devDependencies": { + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", + "@types/chai": "^4.2.0", + "@types/chai-as-promised": "^7.1.3", + "@types/lodash": "^4.14.123", + "@types/lodash.memoize": "^4.1.7", + "@types/mocha": ">=9.1.0", + "@types/node": "^18.0.0", + "@types/sinon": "^9.0.8", + "@typescript-eslint/eslint-plugin": "5.61.0", + "@typescript-eslint/parser": "5.61.0", + "chai": "^4.2.0", + "chai-as-promised": "^7.1.1", + "eslint": "^8.44.0", + "eslint-config-prettier": "8.3.0", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-mocha": "10.4.1", + "eslint-plugin-prettier": "3.4.0", + "hardhat": "workspace:^2.17.0", + "jest-diff": "^29.7.0", + "mocha": "^10.0.0", + "nyc": "^15.1.0", + "prettier": "2.4.1", + "rimraf": "^3.0.2", + "sinon": "^9.0.0", + "ts-node": "^10.8.0", + "typescript": "~5.0.0", + "viem": "^2.7.6" + }, + "peerDependencies": { + "hardhat": "workspace:^2.17.0", + "viem": "^2.7.6" + }, + "dependencies": { + "abitype": "^0.9.8", + "lodash.memoize": "^4.1.2" + } +} diff --git a/packages/hardhat-viem/src/index.ts b/packages/hardhat-viem/src/index.ts new file mode 100644 index 0000000000..d7b1f9f45f --- /dev/null +++ b/packages/hardhat-viem/src/index.ts @@ -0,0 +1,42 @@ +import { extendEnvironment } from "hardhat/config"; + +import { + getPublicClient, + getWalletClients, + getWalletClient, + getTestClient, +} from "./internal/clients"; +import { + deployContract, + sendDeploymentTransaction, + getContractAt, +} from "./internal/contracts"; +import "./internal/type-extensions"; +import "./internal/tasks"; + +extendEnvironment((hre) => { + const { provider } = hre.network; + + hre.viem = { + getPublicClient: (publicClientConfig) => + getPublicClient(provider, publicClientConfig), + + getWalletClients: (walletClientConfig) => + getWalletClients(provider, walletClientConfig), + + getWalletClient: (address, walletClientConfig) => + getWalletClient(provider, address, walletClientConfig), + + getTestClient: (testClientConfig) => + getTestClient(provider, testClientConfig), + + deployContract: (contractName, constructorArgs, config) => + deployContract(hre, contractName, constructorArgs, config), + + sendDeploymentTransaction: (contractName, constructorArgs, config) => + sendDeploymentTransaction(hre, contractName, constructorArgs, config), + + getContractAt: (contractName, address, config) => + getContractAt(hre, contractName, address, config), + }; +}); diff --git a/packages/hardhat-viem/src/internal/accounts.ts b/packages/hardhat-viem/src/internal/accounts.ts new file mode 100644 index 0000000000..479cd4942e --- /dev/null +++ b/packages/hardhat-viem/src/internal/accounts.ts @@ -0,0 +1,9 @@ +import type { EthereumProvider } from "hardhat/types"; +import type { Address } from "viem"; + +import memoize from "lodash.memoize"; + +export const getAccounts = memoize( + async (provider: EthereumProvider): Promise => + provider.send("eth_accounts") +); diff --git a/packages/hardhat-viem/src/internal/bytecode.ts b/packages/hardhat-viem/src/internal/bytecode.ts new file mode 100644 index 0000000000..553aacf256 --- /dev/null +++ b/packages/hardhat-viem/src/internal/bytecode.ts @@ -0,0 +1,138 @@ +import type * as viemT from "viem"; +import type { Artifact } from "hardhat/types/artifacts"; + +import { + AmbigousLibraryNameError, + MissingLibraryAddressError, + OverlappingLibraryNamesError, + UnnecessaryLibraryLinkError, +} from "./errors"; + +export interface Libraries
    { + [libraryName: string]: Address; +} + +export interface Link { + sourceName: string; + libraryName: string; + address: string; +} + +export async function linkBytecode( + artifact: Artifact, + libraries: Link[] +): Promise { + const { isHex } = await import("viem"); + let bytecode = artifact.bytecode; + + // TODO: measure performance impact + for (const { sourceName, libraryName, address } of libraries) { + const linkReferences = artifact.linkReferences[sourceName][libraryName]; + for (const { start, length } of linkReferences) { + bytecode = + bytecode.substring(0, 2 + start * 2) + + address.substring(2) + + bytecode.substring(2 + (start + length) * 2); + } + } + + return isHex(bytecode) ? bytecode : `0x${bytecode}`; +} + +async function throwOnAmbigousLibraryNameOrUnnecessaryLink( + contractName: string, + libraries: Libraries, + neededLibraries: Link[] +) { + for (const linkedLibraryName of Object.keys(libraries)) { + const matchingLibraries = neededLibraries.filter( + ({ sourceName, libraryName }) => + libraryName === linkedLibraryName || + `${sourceName}:${libraryName}` === linkedLibraryName + ); + + if (matchingLibraries.length > 1) { + throw new AmbigousLibraryNameError( + contractName, + linkedLibraryName, + matchingLibraries.map( + ({ sourceName, libraryName }) => `${sourceName}:${libraryName}` + ) + ); + } else if (matchingLibraries.length === 0) { + throw new UnnecessaryLibraryLinkError(contractName, linkedLibraryName); + } + } +} + +async function throwOnMissingLibrariesAddress( + contractName: string, + libraries: Libraries, + neededLibraries: Link[] +) { + const missingLibraries = []; + for (const { sourceName, libraryName } of neededLibraries) { + const address = + libraries[`${sourceName}:${libraryName}`] ?? libraries[libraryName]; + + if (address === undefined) { + missingLibraries.push({ sourceName, libraryName }); + } + } + + if (missingLibraries.length > 0) { + throw new MissingLibraryAddressError(contractName, missingLibraries); + } +} + +async function throwOnOverlappingLibraryNames( + contractName: string, + libraries: Libraries, + neededLibraries: Link[] +) { + for (const { sourceName, libraryName } of neededLibraries) { + if ( + libraries[`${sourceName}:${libraryName}`] !== undefined && + libraries[libraryName] !== undefined + ) { + throw new OverlappingLibraryNamesError(sourceName, libraryName); + } + } +} + +export async function resolveBytecodeWithLinkedLibraries( + artifact: Artifact, + libraries: Libraries +): Promise { + const { linkReferences } = artifact; + + const neededLibraries: Link[] = []; + for (const [sourceName, sourceLibraries] of Object.entries(linkReferences)) { + for (const libraryName of Object.keys(sourceLibraries)) { + neededLibraries.push({ + sourceName, + libraryName, + address: + libraries[`${sourceName}:${libraryName}`] ?? libraries[libraryName], + }); + } + } + + await throwOnAmbigousLibraryNameOrUnnecessaryLink( + artifact.contractName, + libraries, + neededLibraries + ); + await throwOnOverlappingLibraryNames( + artifact.contractName, + libraries, + neededLibraries + ); + await throwOnMissingLibrariesAddress( + artifact.contractName, + libraries, + neededLibraries + ); + + return linkBytecode(artifact, neededLibraries); +} diff --git a/packages/hardhat-viem/src/internal/chains.ts b/packages/hardhat-viem/src/internal/chains.ts new file mode 100644 index 0000000000..013f62b9ae --- /dev/null +++ b/packages/hardhat-viem/src/internal/chains.ts @@ -0,0 +1,97 @@ +import type { EthereumProvider } from "hardhat/types"; +import type { Chain } from "viem"; +import type { TestClientMode } from "../types"; + +import memoize from "lodash.memoize"; + +import { + UnknownDevelopmentNetworkError, + NetworkNotFoundError, + MultipleMatchingNetworksError, +} from "./errors"; + +export async function getChain(provider: EthereumProvider): Promise { + const chains: Record = require("viem/chains"); + const chainId = await getChainId(provider); + + if (isDevelopmentNetwork(chainId)) { + if (await isHardhatNetwork(provider)) { + return chains.hardhat; + } else if (await isFoundryNetwork(provider)) { + return chains.foundry; + } else { + throw new UnknownDevelopmentNetworkError(); + } + } + + const matchingChains = Object.values(chains).filter( + ({ id }) => id === chainId + ); + + if (matchingChains.length === 0) { + if (await isHardhatNetwork(provider)) { + return { + ...chains.hardhat, + id: chainId, + }; + } else if (await isFoundryNetwork(provider)) { + return { + ...chains.foundry, + id: chainId, + }; + } else { + throw new NetworkNotFoundError(chainId); + } + } + + if (matchingChains.length > 1) { + throw new MultipleMatchingNetworksError(chainId); + } + + return matchingChains[0]; +} + +export function isDevelopmentNetwork(chainId: number) { + return chainId === 31337; +} + +export async function getMode( + provider: EthereumProvider +): Promise { + if (await isHardhatNetwork(provider)) { + return "hardhat"; + } else if (await isFoundryNetwork(provider)) { + return "anvil"; + } else { + throw new UnknownDevelopmentNetworkError(); + } +} + +const getChainId = memoize(async (provider: EthereumProvider) => + Number(await provider.send("eth_chainId")) +); + +const isHardhatNetwork = memoize(async (provider: EthereumProvider) => + detectNetworkByMethodName(provider, NetworkMethod.HARDHAT_METADATA) +); + +const isFoundryNetwork = memoize(async (provider: EthereumProvider) => + detectNetworkByMethodName(provider, NetworkMethod.ANVIL_NODE_INFO) +); + +enum NetworkMethod { + HARDHAT_METADATA = "hardhat_metadata", + ANVIL_NODE_INFO = "anvil_nodeInfo", +} + +async function detectNetworkByMethodName( + provider: EthereumProvider, + methodName: string +) { + try { + await provider.send(methodName); + return true; + } catch { + return false; + } +} diff --git a/packages/hardhat-viem/src/internal/clients.ts b/packages/hardhat-viem/src/internal/clients.ts new file mode 100644 index 0000000000..e92272aeb6 --- /dev/null +++ b/packages/hardhat-viem/src/internal/clients.ts @@ -0,0 +1,176 @@ +import type { EthereumProvider } from "hardhat/types"; +import type { + Address, + Chain, + PublicClientConfig, + WalletClientConfig, + TestClientConfig, +} from "viem"; +import type { + PublicClient, + TestClient, + TestClientMode, + WalletClient, +} from "../types"; + +async function getParameters( + chain: Chain, + config: TConfig +) { + const { isDevelopmentNetwork } = await import("./chains"); + + const defaultParameters = isDevelopmentNetwork(chain.id) + ? { pollingInterval: 50, cacheTime: 0 } + : {}; + + const transportParameters = isDevelopmentNetwork(chain.id) + ? { retryCount: 0 } + : {}; + + return { + clientParameters: { ...defaultParameters, ...config }, + transportParameters, + }; +} + +/** + * Get a PublicClient instance. This is a read-only client that can be used to + * query the blockchain. + * + * @param provider The Ethereum provider used to connect to the blockchain. + * @param publicClientConfig Optional configuration for the PublicClient instance. See the viem documentation for more information. + * @returns A PublicClient instance. + */ +export async function getPublicClient( + provider: EthereumProvider, + publicClientConfig?: Partial +): Promise { + const { getChain } = await import("./chains"); + const chain = publicClientConfig?.chain ?? (await getChain(provider)); + return innerGetPublicClient(provider, chain, publicClientConfig); +} + +export async function innerGetPublicClient( + provider: EthereumProvider, + chain: Chain, + publicClientConfig?: Partial +): Promise { + const viem = await import("viem"); + const { clientParameters, transportParameters } = await getParameters( + chain, + publicClientConfig + ); + + const publicClient = viem.createPublicClient({ + chain, + transport: viem.custom(provider, transportParameters), + ...clientParameters, + }); + + return publicClient; +} + +/** + * Get a list of WalletClient instances. These are read-write clients that can + * be used to send transactions to the blockchain. Each client is associated + * with an account obtained from the provider using `eth_accounts`. + * + * @param provider The Ethereum provider used to connect to the blockchain. + * @param walletClientConfig Optional configuration for the WalletClient instances. See the viem documentation for more information. + * @returns A list of WalletClient instances. + */ +export async function getWalletClients( + provider: EthereumProvider, + walletClientConfig?: Partial +): Promise { + const { getAccounts } = await import("./accounts"); + const { getChain } = await import("./chains"); + const chain = walletClientConfig?.chain ?? (await getChain(provider)); + const accounts = await getAccounts(provider); + return innerGetWalletClients(provider, chain, accounts, walletClientConfig); +} + +export async function innerGetWalletClients( + provider: EthereumProvider, + chain: Chain, + accounts: Address[], + walletClientConfig?: Partial +): Promise { + const viem = await import("viem"); + const { clientParameters, transportParameters } = await getParameters( + chain, + walletClientConfig + ); + + const walletClients = accounts.map((account) => + viem.createWalletClient({ + chain, + account, + transport: viem.custom(provider, transportParameters), + ...clientParameters, + }) + ); + + return walletClients; +} + +/** + * Get a WalletClient instance for a specific address. This is a read-write + * client that can be used to send transactions to the blockchain. + * + * @param provider The Ethereum provider used to connect to the blockchain. + * @param address The public address of the account to use. + * @param walletClientConfig Optional configuration for the WalletClient instance. See the viem documentation for more information. + * @returns A WalletClient instance. + */ +export async function getWalletClient( + provider: EthereumProvider, + address: Address, + walletClientConfig?: Partial +): Promise { + const { getChain } = await import("./chains"); + const chain = walletClientConfig?.chain ?? (await getChain(provider)); + return ( + await innerGetWalletClients(provider, chain, [address], walletClientConfig) + )[0]; +} + +/** + * Get a TestClient instance. This is a read-write client that can be used to + * perform actions only available on test nodes such as hardhat or anvil. + * + * @param provider The Ethereum provider used to connect to the blockchain. + * @param testClientConfig Optional configuration for the TestClient instance. See the viem documentation for more information. + * @returns A TestClient instance. + */ +export async function getTestClient( + provider: EthereumProvider, + testClientConfig?: Partial +): Promise { + const { getChain, getMode } = await import("./chains"); + const chain = testClientConfig?.chain ?? (await getChain(provider)); + const mode = await getMode(provider); + return innerGetTestClient(provider, chain, mode, testClientConfig); +} + +export async function innerGetTestClient( + provider: EthereumProvider, + chain: Chain, + mode: TestClientMode, + testClientConfig?: Partial +): Promise { + const viem = await import("viem"); + const { clientParameters, transportParameters } = await getParameters( + chain, + testClientConfig + ); + + const testClient = viem.createTestClient({ + mode, + chain, + transport: viem.custom(provider, transportParameters), + ...clientParameters, + }); + + return testClient; +} diff --git a/packages/hardhat-viem/src/internal/contracts.ts b/packages/hardhat-viem/src/internal/contracts.ts new file mode 100644 index 0000000000..51475a34aa --- /dev/null +++ b/packages/hardhat-viem/src/internal/contracts.ts @@ -0,0 +1,261 @@ +import type { + EthereumProvider, + HardhatRuntimeEnvironment, +} from "hardhat/types"; +import type { Abi, Address, Hex } from "viem"; +import type { + DeployContractConfig, + GetContractAtConfig, + GetContractReturnType, + GetTransactionReturnType, + PublicClient, + SendDeploymentTransactionConfig, + WalletClient, +} from "../types"; + +import { Libraries, resolveBytecodeWithLinkedLibraries } from "./bytecode"; +import { getPublicClient, getWalletClients } from "./clients"; +import { + DefaultWalletClientNotFoundError, + DeployContractError, + HardhatViemError, + InvalidConfirmationsError, +} from "./errors"; + +async function getContractAbiAndBytecode( + artifacts: HardhatRuntimeEnvironment["artifacts"], + contractName: string, + libraries: Libraries
    +) { + const artifact = await artifacts.readArtifact(contractName); + const bytecode = await resolveBytecodeWithLinkedLibraries( + artifact, + libraries + ); + + return { + abi: artifact.abi, + bytecode, + }; +} + +export async function deployContract( + { artifacts, network }: HardhatRuntimeEnvironment, + contractName: string, + constructorArgs: any[] = [], + config: DeployContractConfig = {} +): Promise { + const { + client, + confirmations, + libraries = {}, + ...deployContractParameters + } = config; + const [publicClient, walletClient, { abi, bytecode }] = await Promise.all([ + client?.public ?? getPublicClient(network.provider), + client?.wallet ?? getDefaultWalletClient(network.provider, network.name), + getContractAbiAndBytecode(artifacts, contractName, libraries), + ]); + + return innerDeployContract( + publicClient, + walletClient, + abi, + bytecode, + constructorArgs, + deployContractParameters, + confirmations + ); +} + +export async function innerDeployContract( + publicClient: PublicClient, + walletClient: WalletClient, + contractAbi: Abi, + contractBytecode: Hex, + constructorArgs: any[], + deployContractParameters: DeployContractConfig = {}, + confirmations: number = 1 +): Promise { + let deploymentTxHash: Hex; + // If gasPrice is defined, then maxFeePerGas and maxPriorityFeePerGas + // must be undefined because it's a legaxy tx. + if (deployContractParameters.gasPrice !== undefined) { + deploymentTxHash = await walletClient.deployContract({ + abi: contractAbi, + bytecode: contractBytecode, + args: constructorArgs, + ...deployContractParameters, + maxFeePerGas: undefined, + maxPriorityFeePerGas: undefined, + }); + } else { + deploymentTxHash = await walletClient.deployContract({ + abi: contractAbi, + bytecode: contractBytecode, + args: constructorArgs, + ...deployContractParameters, + gasPrice: undefined, + }); + } + + if (confirmations < 0) { + throw new HardhatViemError("Confirmations must be greater than 0."); + } + if (confirmations === 0) { + throw new InvalidConfirmationsError(); + } + + const { contractAddress } = await publicClient.waitForTransactionReceipt({ + hash: deploymentTxHash, + confirmations, + }); + + if (contractAddress === null || contractAddress === undefined) { + const transaction = await publicClient.getTransaction({ + hash: deploymentTxHash, + }); + throw new DeployContractError(deploymentTxHash, transaction.blockNumber); + } + + const contract = await innerGetContractAt( + publicClient, + walletClient, + contractAbi, + contractAddress + ); + + return contract; +} + +export async function sendDeploymentTransaction( + { artifacts, network }: HardhatRuntimeEnvironment, + contractName: string, + constructorArgs: any[] = [], + config: SendDeploymentTransactionConfig = {} +): Promise<{ + contract: GetContractReturnType; + deploymentTransaction: GetTransactionReturnType; +}> { + const { client, libraries = {}, ...deployContractParameters } = config; + const [publicClient, walletClient, { abi, bytecode }] = await Promise.all([ + client?.public ?? getPublicClient(network.provider), + client?.wallet ?? getDefaultWalletClient(network.provider, network.name), + getContractAbiAndBytecode(artifacts, contractName, libraries), + ]); + + return innerSendDeploymentTransaction( + publicClient, + walletClient, + abi, + bytecode, + constructorArgs, + deployContractParameters + ); +} + +async function innerSendDeploymentTransaction( + publicClient: PublicClient, + walletClient: WalletClient, + contractAbi: Abi, + contractBytecode: Hex, + constructorArgs: any[], + deployContractParameters: SendDeploymentTransactionConfig = {} +): Promise<{ + contract: GetContractReturnType; + deploymentTransaction: GetTransactionReturnType; +}> { + let deploymentTxHash: Hex; + // If gasPrice is defined, then maxFeePerGas and maxPriorityFeePerGas + // must be undefined because it's a legaxy tx. + if (deployContractParameters.gasPrice !== undefined) { + deploymentTxHash = await walletClient.deployContract({ + abi: contractAbi, + bytecode: contractBytecode, + args: constructorArgs, + ...deployContractParameters, + maxFeePerGas: undefined, + maxPriorityFeePerGas: undefined, + }); + } else { + deploymentTxHash = await walletClient.deployContract({ + abi: contractAbi, + bytecode: contractBytecode, + args: constructorArgs, + ...deployContractParameters, + gasPrice: undefined, + }); + } + + const deploymentTx = await publicClient.getTransaction({ + hash: deploymentTxHash, + }); + + const { getContractAddress } = await import("viem"); + const contractAddress = getContractAddress({ + from: walletClient.account.address, + nonce: BigInt(deploymentTx.nonce), + }); + + const contract = await innerGetContractAt( + publicClient, + walletClient, + contractAbi, + contractAddress + ); + + return { contract, deploymentTransaction: deploymentTx }; +} + +export async function getContractAt( + { artifacts, network }: HardhatRuntimeEnvironment, + contractName: string, + address: Address, + config: GetContractAtConfig = {} +): Promise { + const [publicClient, walletClient, contractArtifact] = await Promise.all([ + config.client?.public ?? getPublicClient(network.provider), + config.client?.wallet ?? + getDefaultWalletClient(network.provider, network.name), + artifacts.readArtifact(contractName), + ]); + + return innerGetContractAt( + publicClient, + walletClient, + contractArtifact.abi, + address + ); +} + +async function innerGetContractAt( + publicClient: PublicClient, + walletClient: WalletClient, + contractAbi: Abi, + address: Address +): Promise { + const viem = await import("viem"); + const contract = viem.getContract({ + address, + client: { + public: publicClient, + wallet: walletClient, + }, + abi: contractAbi, + }); + + return contract; +} + +async function getDefaultWalletClient( + provider: EthereumProvider, + networkName: string +): Promise { + const [defaultWalletClient] = await getWalletClients(provider); + + if (defaultWalletClient === undefined) { + throw new DefaultWalletClientNotFoundError(networkName); + } + + return defaultWalletClient; +} diff --git a/packages/hardhat-viem/src/internal/errors.ts b/packages/hardhat-viem/src/internal/errors.ts new file mode 100644 index 0000000000..2d0f8ffd7b --- /dev/null +++ b/packages/hardhat-viem/src/internal/errors.ts @@ -0,0 +1,125 @@ +import type { Link } from "./bytecode"; + +import { NomicLabsHardhatPluginError } from "hardhat/plugins"; + +export class HardhatViemError extends NomicLabsHardhatPluginError { + constructor(message: string, parent?: Error) { + super("@nomicfoundation/hardhat-viem", message, parent); + } +} + +export class UnknownDevelopmentNetworkError extends HardhatViemError { + constructor() { + super(`The chain id corresponds to a development network but we couldn't detect which one. +Please report this issue if you're using Hardhat or Foundry.`); + } +} + +export class NetworkNotFoundError extends HardhatViemError { + constructor(chainId: number) { + super( + `No network with chain id ${chainId} found. You can override the chain by passing it as a parameter to the client getter: + +import { someChain } from "viem/chains"; +const client = await hre.viem.getPublicClient({ + chain: someChain, + ... +}); + +You can find a list of supported networks here: https://github.com/wevm/viem/blob/main/src/chains/index.ts` + ); + } +} + +export class MultipleMatchingNetworksError extends HardhatViemError { + constructor(chainId: number) { + super( + `Multiple networks with chain id ${chainId} found. You can override the chain by passing it as a parameter to the client getter: + +import { someChain } from "viem/chains"; +const client = await hre.viem.getPublicClient({ + chain: someChain, + ... +}); + +You can find a list of supported networks here: https://github.com/wevm/viem/blob/main/src/chains/index.ts` + ); + } +} + +export class DefaultWalletClientNotFoundError extends HardhatViemError { + constructor(networkName: string) { + super( + `Default wallet client not found. This can happen if no accounts were configured for this network (network: '${networkName}'). + +Alternatively, you can set a custom wallet client by passing it as a parameter in the deployContract function: + +const walletClient = await hre.viem.getWalletClient(address); +const contractA = await hre.viem.deployContract("A", [], { walletClient }); +const contractB = await hre.viem.getContractAt("B", address, { walletClient });` + ); + } +} + +export class InvalidConfirmationsError extends HardhatViemError { + constructor() { + super( + "deployContract does not support 0 confirmations. Use sendDeploymentTransaction if you want to handle the deployment transaction yourself." + ); + } +} + +export class DeployContractError extends HardhatViemError { + constructor(txHash: string, blockNumber: bigint) { + super( + `The deployment transaction '${txHash}' was mined in block '${blockNumber}' but its receipt doesn't contain a contract address` + ); + } +} + +export class AmbigousLibraryNameError extends HardhatViemError { + constructor( + contractName: string, + libraryName: string, + matchingLibraries: string[] + ) { + super( + `The library name "${libraryName}" is ambiguous for the contract "${contractName}". +It may resolve to one of the following libraries: +${matchingLibraries.map((fqn) => `\n\t* ${fqn}`).join(",")} + +To fix this, choose one of these fully qualified library names and replace where appropriate.` + ); + } +} + +export class OverlappingLibraryNamesError extends HardhatViemError { + constructor(sourceName: string, libraryName: string) { + super( + `The library name "${libraryName}" and "${sourceName}:${libraryName}" are both linking to the same library. Please use one of them, or If they are not the same library, use fully qualified names instead.` + ); + } +} + +export class UnnecessaryLibraryLinkError extends HardhatViemError { + constructor(contractName: string, libraryName: string) { + super( + `The library name "${libraryName}" was linked but it's not referenced by the "${contractName}" contract.` + ); + } +} + +export class MissingLibraryAddressError extends HardhatViemError { + constructor( + contractName: string, + missingLibraries: Array> + ) { + super( + `The libraries needed are: +${missingLibraries + .map(({ sourceName, libraryName }) => `\t* "${sourceName}:${libraryName}"`) + .join(",\n")} +Please deploy them first and link them while deploying "${contractName}"` + ); + } +} diff --git a/packages/hardhat-viem/src/internal/tasks.ts b/packages/hardhat-viem/src/internal/tasks.ts new file mode 100644 index 0000000000..a6bb4f2980 --- /dev/null +++ b/packages/hardhat-viem/src/internal/tasks.ts @@ -0,0 +1,341 @@ +import type { Artifact, Artifacts } from "hardhat/types"; +import type { ArtifactsEmittedPerFile } from "hardhat/types/builtin-tasks"; + +import { join, dirname, relative } from "path"; +import { mkdir, writeFile, rm } from "fs/promises"; + +import { subtask } from "hardhat/config"; +import { + TASK_COMPILE_SOLIDITY_EMIT_ARTIFACTS, + TASK_COMPILE_SOLIDITY, + TASK_COMPILE_REMOVE_OBSOLETE_ARTIFACTS, +} from "hardhat/builtin-tasks/task-names"; +import { + getFullyQualifiedName, + parseFullyQualifiedName, +} from "hardhat/utils/contract-names"; +import { getAllFilesMatching } from "hardhat/internal/util/fs-utils"; +import { replaceBackslashes } from "hardhat/utils/source-names"; + +interface EmittedArtifacts { + artifactsEmittedPerFile: ArtifactsEmittedPerFile; +} + +/** + * Override task that generates an `artifacts.d.ts` file with `never` + * types for duplicate contract names. This file is used in conjunction with + * the `artifacts.d.ts` file inside each contract directory to type + * `hre.artifacts`. + */ +subtask(TASK_COMPILE_SOLIDITY).setAction( + async (_, { config, artifacts }, runSuper) => { + const superRes = await runSuper(); + + const duplicateContractNames = await findDuplicateContractNames(artifacts); + + const duplicateArtifactsDTs = generateDuplicateArtifactsDefinition( + duplicateContractNames + ); + + try { + await writeFile( + join(config.paths.artifacts, "artifacts.d.ts"), + duplicateArtifactsDTs + ); + } catch (error) { + console.error("Error writing artifacts definition:", error); + } + + return superRes; + } +); + +/** + * Override task to emit TypeScript and definition files for each contract. + * Generates a `.d.ts` file per contract, and a `artifacts.d.ts` per solidity + * file, which is used in conjunction to the root `artifacts.d.ts` + * to type `hre.artifacts`. + */ +subtask(TASK_COMPILE_SOLIDITY_EMIT_ARTIFACTS).setAction( + async (_, { artifacts, config }, runSuper): Promise => { + const { artifactsEmittedPerFile }: EmittedArtifacts = await runSuper(); + const duplicateContractNames = await findDuplicateContractNames(artifacts); + + await Promise.all( + artifactsEmittedPerFile.map(async ({ file, artifactsEmitted }) => { + const srcDir = join(config.paths.artifacts, file.sourceName); + await mkdir(srcDir, { + recursive: true, + }); + + const contractTypeData = await Promise.all( + artifactsEmitted.map(async (contractName) => { + const fqn = getFullyQualifiedName(file.sourceName, contractName); + const artifact = await artifacts.readArtifact(fqn); + const isDuplicate = duplicateContractNames.has(contractName); + const declaration = generateContractDeclaration( + artifact, + isDuplicate + ); + + const typeName = `${contractName}$Type`; + + return { contractName, fqn, typeName, declaration }; + }) + ); + + const fp: Array> = []; + for (const { contractName, declaration } of contractTypeData) { + fp.push(writeFile(join(srcDir, `${contractName}.d.ts`), declaration)); + } + + const dTs = generateArtifactsDefinition(contractTypeData); + fp.push(writeFile(join(srcDir, "artifacts.d.ts"), dTs)); + + try { + await Promise.all(fp); + } catch (error) { + console.error("Error writing artifacts definition:", error); + } + }) + ); + + return { artifactsEmittedPerFile }; + } +); + +/** + * Override task for cleaning up outdated artifacts. + * Deletes directories with stale `artifacts.d.ts` files that no longer have + * a matching `.sol` file. + */ +subtask(TASK_COMPILE_REMOVE_OBSOLETE_ARTIFACTS).setAction( + async (_, { config, artifacts }, runSuper) => { + const superRes = await runSuper(); + + const fqns = await artifacts.getAllFullyQualifiedNames(); + const existingSourceNames = new Set( + fqns.map((fqn) => parseFullyQualifiedName(fqn).sourceName) + ); + const allArtifactsDTs = await getAllFilesMatching( + config.paths.artifacts, + (f) => f.endsWith("artifacts.d.ts") + ); + + for (const artifactDTs of allArtifactsDTs) { + const dir = dirname(artifactDTs); + const sourceName = replaceBackslashes( + relative(config.paths.artifacts, dir) + ); + // If sourceName is empty, it means that the artifacts.d.ts file is in the + // root of the artifacts directory, and we shouldn't delete it. + if (sourceName === "") { + continue; + } + + if (!existingSourceNames.has(sourceName)) { + await rm(dir, { force: true, recursive: true }); + } + } + + return superRes; + } +); + +const AUTOGENERATED_FILE_PREFACE = `// This file was autogenerated by hardhat-viem, do not edit it. +// prettier-ignore +// tslint:disable +// eslint-disable`; + +/** + * Generates TypeScript code that extends the `ArtifactsMap` with `never` types + * for duplicate contract names. + */ +function generateDuplicateArtifactsDefinition( + duplicateContractNames: Set +) { + return `${AUTOGENERATED_FILE_PREFACE} + +import "hardhat/types/artifacts"; + +declare module "hardhat/types/artifacts" { + interface ArtifactsMap { + ${Array.from(duplicateContractNames) + .map((name) => `${name}: never;`) + .join("\n ")} + } + + interface ContractTypesMap { + ${Array.from(duplicateContractNames) + .map((name) => `${name}: never;`) + .join("\n ")} + } +} +`; +} + +/** + * Generates TypeScript code to declare a contract and its associated + * TypeScript types. + */ +function generateContractDeclaration(artifact: Artifact, isDuplicate: boolean) { + const { contractName, sourceName } = artifact; + const fqn = getFullyQualifiedName(sourceName, contractName); + const validNames = isDuplicate ? [fqn] : [contractName, fqn]; + const json = JSON.stringify(artifact, undefined, 2); + const contractTypeName = `${contractName}$Type`; + + const constructorAbi = artifact.abi.find( + ({ type }) => type === "constructor" + ); + + const inputs: Array<{ + internalType: string; + name: string; + type: string; + }> = constructorAbi !== undefined ? constructorAbi.inputs : []; + + const constructorArgs = + inputs.length > 0 + ? `constructorArgs: [${inputs + .map(({ name, type }) => getArgType(name, type)) + .join(", ")}]` + : `constructorArgs?: []`; + + return `${AUTOGENERATED_FILE_PREFACE} + +import type { Address } from "viem"; +${ + inputs.length > 0 + ? `import type { AbiParameterToPrimitiveType, GetContractReturnType } from "@nomicfoundation/hardhat-viem/types";` + : `import type { GetContractReturnType } from "@nomicfoundation/hardhat-viem/types";` +} +import "@nomicfoundation/hardhat-viem/types"; + +export interface ${contractTypeName} ${json} + +declare module "@nomicfoundation/hardhat-viem/types" { + ${validNames + .map( + (name) => `export function deployContract( + contractName: "${name}", + ${constructorArgs}, + config?: DeployContractConfig + ): Promise>;` + ) + .join("\n ")} + + ${validNames + .map( + (name) => `export function sendDeploymentTransaction( + contractName: "${name}", + ${constructorArgs}, + config?: SendDeploymentTransactionConfig + ): Promise<{ + contract: GetContractReturnType<${contractTypeName}["abi"]>; + deploymentTransaction: GetTransactionReturnType; + }>;` + ) + .join("\n ")} + + ${validNames + .map( + (name) => `export function getContractAt( + contractName: "${name}", + address: Address, + config?: GetContractAtConfig + ): Promise>;` + ) + .join("\n ")} +} +`; +} + +/** + * Generates TypeScript code to extend the `ArtifactsMap` interface with + * contract types. + */ +function generateArtifactsDefinition( + contractTypeData: Array<{ + contractName: string; + fqn: string; + typeName: string; + declaration: string; + }> +) { + return `${AUTOGENERATED_FILE_PREFACE} + +import "hardhat/types/artifacts"; +import type { GetContractReturnType } from "@nomicfoundation/hardhat-viem/types"; + +${contractTypeData + .map((ctd) => `import { ${ctd.typeName} } from "./${ctd.contractName}";`) + .join("\n")} + +declare module "hardhat/types/artifacts" { + interface ArtifactsMap { + ${contractTypeData + .map((ctd) => `["${ctd.contractName}"]: ${ctd.typeName};`) + .join("\n ")} + ${contractTypeData + .map((ctd) => `["${ctd.fqn}"]: ${ctd.typeName};`) + .join("\n ")} + } + + interface ContractTypesMap { + ${contractTypeData + .map( + (ctd) => + `["${ctd.contractName}"]: GetContractReturnType<${ctd.typeName}["abi"]>;` + ) + .join("\n ")} + ${contractTypeData + .map( + (ctd) => + `["${ctd.fqn}"]: GetContractReturnType<${ctd.typeName}["abi"]>;` + ) + .join("\n ")} + } +} +`; +} + +/** + * Returns the type of a function argument in one of the following formats: + * - If the 'name' is provided: + * "name: AbiParameterToPrimitiveType<{ name: string; type: string; }>" + * + * - If the 'name' is empty: + * "AbiParameterToPrimitiveType<{ name: string; type: string; }>" + */ +function getArgType(name: string | undefined, type: string) { + const argType = `AbiParameterToPrimitiveType<${JSON.stringify({ + name, + type, + })}>`; + + return name !== "" && name !== undefined ? `${name}: ${argType}` : argType; +} + +/** + * Returns a set of duplicate contract names. + */ +async function findDuplicateContractNames(artifacts: Artifacts) { + const fqns = await artifacts.getAllFullyQualifiedNames(); + const contractNames = fqns.map( + (fqn) => parseFullyQualifiedName(fqn).contractName + ); + + const duplicates = new Set(); + const existing = new Set(); + + for (const name of contractNames) { + if (existing.has(name)) { + duplicates.add(name); + } + + existing.add(name); + } + + return duplicates; +} diff --git a/packages/hardhat-viem/src/internal/type-extensions.ts b/packages/hardhat-viem/src/internal/type-extensions.ts new file mode 100644 index 0000000000..356bdec1c4 --- /dev/null +++ b/packages/hardhat-viem/src/internal/type-extensions.ts @@ -0,0 +1,27 @@ +import type { HardhatViemHelpers } from "../types"; +import "hardhat/types/runtime"; +import "hardhat/types/artifacts"; + +declare module "hardhat/types/runtime" { + interface HardhatRuntimeEnvironment { + viem: HardhatViemHelpers; + } +} + +declare module "hardhat/types/artifacts" { + // eslint-disable-next-line @typescript-eslint/no-empty-interface + interface ArtifactsMap {} + + // eslint-disable-next-line @typescript-eslint/no-empty-interface + interface ContractTypesMap {} + + interface Artifacts { + readArtifact( + contractNameOrFullyQualifiedName: ArgT + ): Promise; + + readArtifactSync( + contractNameOrFullyQualifiedName: ArgT + ): ArtifactsMap[ArgT]; + } +} diff --git a/packages/hardhat-viem/src/tsconfig.json b/packages/hardhat-viem/src/tsconfig.json new file mode 100644 index 0000000000..aa452dcdf7 --- /dev/null +++ b/packages/hardhat-viem/src/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../../config/typescript/tsconfig.json", + "compilerOptions": { + "outDir": "../", + "rootDirs": ["."], + "composite": true + }, + "include": ["./**/*.ts"], + "exclude": [], + "references": [ + { + "path": "../../hardhat-core/src" + } + ] +} diff --git a/packages/hardhat-viem/src/types.ts b/packages/hardhat-viem/src/types.ts new file mode 100644 index 0000000000..0ea2fe2604 --- /dev/null +++ b/packages/hardhat-viem/src/types.ts @@ -0,0 +1,105 @@ +import type * as viemT from "viem"; +import type { ArtifactsMap } from "hardhat/types/artifacts"; +import type { Libraries } from "./internal/bytecode"; + +export type PublicClient = viemT.PublicClient; +export type WalletClient = viemT.WalletClient< + viemT.Transport, + viemT.Chain, + viemT.Account +>; +export type TestClient = viemT.TestClient< + TestClientMode, + viemT.Transport, + viemT.Chain +>; + +export type KeyedClient = + | { + public?: PublicClient; + wallet: WalletClient; + } + | { + public: PublicClient; + wallet?: WalletClient; + }; + +export type TestClientMode = Parameters< + typeof viemT.createTestClient +>[0]["mode"]; + +export interface SendTransactionConfig { + client?: KeyedClient; + gas?: bigint; + gasPrice?: bigint; + maxFeePerGas?: bigint; + maxPriorityFeePerGas?: bigint; + value?: bigint; +} + +export interface DeployContractConfig extends SendTransactionConfig { + confirmations?: number; + libraries?: Libraries; +} + +export interface SendDeploymentTransactionConfig extends SendTransactionConfig { + libraries?: Libraries; +} + +export interface GetContractAtConfig { + client?: KeyedClient; +} + +export type GetContractReturnType< + TAbi extends viemT.Abi | readonly unknown[] = viemT.Abi +> = viemT.GetContractReturnType, viemT.Address>; + +export type GetTransactionReturnType = viemT.GetTransactionReturnType< + viemT.Chain, + "latest" +>; + +export type ContractName = + StringT extends keyof ArtifactsMap ? never : StringT; + +export declare function deployContract( + contractName: ContractName, + constructorArgs?: any[], + config?: DeployContractConfig +): Promise; + +export declare function sendDeploymentTransaction( + contractName: ContractName, + constructorArgs?: any[], + config?: SendDeploymentTransactionConfig +): Promise<{ + contract: GetContractReturnType; + deploymentTransaction: GetTransactionReturnType; +}>; + +export declare function getContractAt( + contractName: ContractName, + address: viemT.Address, + config?: GetContractAtConfig +): Promise; + +export interface HardhatViemHelpers { + getPublicClient( + publicClientConfig?: Partial + ): Promise; + getWalletClients( + walletClientConfig?: Partial + ): Promise; + getWalletClient( + address: viemT.Address, + walletClientConfig?: Partial + ): Promise; + getTestClient( + testClientConfig?: Partial + ): Promise; + deployContract: typeof deployContract; + sendDeploymentTransaction: typeof sendDeploymentTransaction; + getContractAt: typeof getContractAt; +} + +export type { AbiParameterToPrimitiveType } from "abitype"; diff --git a/packages/hardhat-viem/test/.eslintrc.js b/packages/hardhat-viem/test/.eslintrc.js new file mode 100644 index 0000000000..757fe8a3ca --- /dev/null +++ b/packages/hardhat-viem/test/.eslintrc.js @@ -0,0 +1,15 @@ +module.exports = { + extends: [`${__dirname}/../.eslintrc.js`], + parserOptions: { + project: `${__dirname}/../tsconfig.json`, + sourceType: "module", + }, + rules: { + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: true, + }, + ], + }, +}; diff --git a/packages/hardhat-viem/test/chains.ts b/packages/hardhat-viem/test/chains.ts new file mode 100644 index 0000000000..bee7e82679 --- /dev/null +++ b/packages/hardhat-viem/test/chains.ts @@ -0,0 +1,165 @@ +import type { EthereumProvider } from "hardhat/types"; + +import { expect, assert } from "chai"; +import sinon from "sinon"; +import * as chains from "viem/chains"; + +import { + getChain, + getMode, + isDevelopmentNetwork, +} from "../src/internal/chains"; +import { EthereumMockedProvider } from "./mocks/provider"; + +describe("chains", () => { + describe("getChain", () => { + afterEach(sinon.restore); + + it("should return the chain corresponding to the chain id", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + const sendStub = sinon.stub(provider, "send"); + sendStub.withArgs("eth_chainId").returns(Promise.resolve("0x1")); // mainnet chain id + sendStub.withArgs("hardhat_metadata").throws(); + sendStub.withArgs("anvil_nodeInfo").throws(); + + const chain = await getChain(provider); + + expect(chain).to.deep.equal(chains.mainnet); + assert.equal(sendStub.callCount, 1); + }); + + it("should return the hardhat chain if the chain id is 31337 and the network is hardhat", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + const sendStub = sinon.stub(provider, "send"); + sendStub.withArgs("eth_chainId").returns(Promise.resolve("0x7a69")); // 31337 in hex + sendStub.withArgs("hardhat_metadata").returns(Promise.resolve({})); + sendStub.withArgs("anvil_nodeInfo").throws(); + + const chain = await getChain(provider); + + expect(chain).to.deep.equal(chains.hardhat); + }); + + it("should return the foundry chain if the chain id is 31337 and the network is foundry", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + const sendStub = sinon.stub(provider, "send"); + sendStub.withArgs("eth_chainId").returns(Promise.resolve("0x7a69")); // 31337 in hex + sendStub.withArgs("hardhat_metadata").throws(); + sendStub.withArgs("anvil_nodeInfo").returns(Promise.resolve({})); + + const chain = await getChain(provider); + + expect(chain).to.deep.equal(chains.foundry); + }); + + it("should throw if the chain id is 31337 and the network is neither hardhat nor foundry", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + const sendStub = sinon.stub(provider, "send"); + sendStub.withArgs("eth_chainId").returns(Promise.resolve("0x7a69")); // 31337 in hex + sendStub.withArgs("hardhat_metadata").throws(); + sendStub.withArgs("anvil_nodeInfo").throws(); + + await expect(getChain(provider)).to.be.rejectedWith( + `The chain id corresponds to a development network but we couldn't detect which one. +Please report this issue if you're using Hardhat or Foundry.` + ); + }); + + it("should throw if the chain id is not 31337 and there is no chain with that id", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + const sendStub = sinon.stub(provider, "send"); + sendStub.withArgs("eth_chainId").returns(Promise.resolve("0x0")); // fake chain id 0 + sendStub.withArgs("hardhat_metadata").throws(); + sendStub.withArgs("anvil_nodeInfo").throws(); + + await expect(getChain(provider)).to.be.rejectedWith( + /No network with chain id 0 found/ + ); + }); + + it("should throw if the chain id is not 31337 and there are multiple chains with that id", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + const sendStub = sinon.stub(provider, "send"); + // chain id 999 corresponds to Wanchain Testnet but also Zora Goerli Testnet + sendStub.withArgs("eth_chainId").returns(Promise.resolve("0x3e7")); + sendStub.withArgs("hardhat_metadata").throws(); + sendStub.withArgs("anvil_nodeInfo").throws(); + + await expect(getChain(provider)).to.be.rejectedWith( + /Multiple networks with chain id 999 found./ + ); + }); + }); + + describe("isDevelopmentNetwork", () => { + it("should return true if the chain id is 31337", () => { + assert.ok(isDevelopmentNetwork(31337)); + }); + + it("should return false if the chain id is not 31337", () => { + assert.notOk(isDevelopmentNetwork(1)); + }); + }); + + describe("getMode", () => { + it("should return hardhat if the network is hardhat", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + const sendStub = sinon.stub(provider, "send"); + sendStub.withArgs("hardhat_metadata").returns(Promise.resolve({})); + sendStub.withArgs("anvil_nodeInfo").throws(); + + const mode = await getMode(provider); + + expect(mode).to.equal("hardhat"); + }); + + it("should return anvil if the network is foundry", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + const sendStub = sinon.stub(provider, "send"); + sendStub.withArgs("hardhat_metadata").throws(); + sendStub.withArgs("anvil_nodeInfo").returns(Promise.resolve({})); + + const mode = await getMode(provider); + + expect(mode).to.equal("anvil"); + }); + + it("should throw if the network is neither hardhat nor foundry", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + const sendStub = sinon.stub(provider, "send"); + sendStub.withArgs("hardhat_metadata").throws(); + sendStub.withArgs("anvil_nodeInfo").throws(); + + await expect(getMode(provider)).to.be.rejectedWith( + `The chain id corresponds to a development network but we couldn't detect which one. +Please report this issue if you're using Hardhat or Foundry.` + ); + }); + + it("should return a hardhat chain with the custom chainId", async function () { + const provider: EthereumProvider = new EthereumMockedProvider(); + const sendStub = sinon.stub(provider, "send"); + sendStub.withArgs("eth_chainId").returns(Promise.resolve("0x3039")); // 12345 in hex + sendStub.withArgs("hardhat_metadata").returns(Promise.resolve({})); + sendStub.withArgs("anvil_nodeInfo").throws(); + + const chain = await getChain(provider); + + expect(chain.id).to.equal(12345); + expect(chain.name).to.equal("Hardhat"); + }); + + it("should return a foundry chain with the custom chainId", async function () { + const provider: EthereumProvider = new EthereumMockedProvider(); + const sendStub = sinon.stub(provider, "send"); + sendStub.withArgs("eth_chainId").returns(Promise.resolve("0x3039")); // 12345 in hex + sendStub.withArgs("anvil_nodeInfo").returns(Promise.resolve({})); + sendStub.withArgs("hardhat_metadata").throws(); + + const chain = await getChain(provider); + + expect(chain.id).to.equal(12345); + expect(chain.name).to.equal("Foundry"); + }); + }); +}); diff --git a/packages/hardhat-viem/test/clients.ts b/packages/hardhat-viem/test/clients.ts new file mode 100644 index 0000000000..50129b60ec --- /dev/null +++ b/packages/hardhat-viem/test/clients.ts @@ -0,0 +1,241 @@ +import type { EthereumProvider } from "hardhat/types"; + +import { assert, expect } from "chai"; +import * as chains from "viem/chains"; + +import { + innerGetPublicClient, + innerGetWalletClients, + innerGetTestClient, +} from "../src/internal/clients"; +import { EthereumMockedProvider } from "./mocks/provider"; + +describe("clients", () => { + describe("innerGetPublicClient", () => { + it("should return a public client", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + + const client = await innerGetPublicClient(provider, chains.mainnet); + + assert.isDefined(client); + assert.equal(client.type, "publicClient"); + assert.equal(client.chain.id, chains.mainnet.id); + }); + + it("should return a public client with custom parameters", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + + const client = await innerGetPublicClient(provider, chains.mainnet, { + pollingInterval: 1000, + cacheTime: 2000, + }); + + assert.equal(client.pollingInterval, 1000); + assert.equal(client.cacheTime, 2000); + assert.equal(client.transport.retryCount, 3); + }); + + it("should return a public client with default parameters for development networks", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + + const client = await innerGetPublicClient(provider, chains.hardhat); + + assert.equal(client.pollingInterval, 50); + assert.equal(client.cacheTime, 0); + assert.equal(client.transport.retryCount, 0); + }); + + it("should retry failed calls on public client", async () => { + const provider = new EthereumMockedProvider(); + + const client = await innerGetPublicClient(provider, chains.mainnet); + + await expect(client.getBlockNumber()).to.eventually.be.rejectedWith( + /unknown RPC error/ + ); + assert.equal(provider.calledCount, 4); + }); + + it("should not retry failed calls on public client when using a development network", async () => { + const provider = new EthereumMockedProvider(); + + const client = await innerGetPublicClient(provider, chains.hardhat); + + await expect(client.getBlockNumber()).to.eventually.be.rejectedWith( + /unknown RPC error/ + ); + assert.equal(provider.calledCount, 1); + }); + }); + + describe("innerGetWalletClients", () => { + it("should return a list of wallet clients", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + + const clients = await innerGetWalletClients(provider, chains.mainnet, [ + "0x1", + "0x2", + ]); + + assert.isArray(clients); + assert.isNotEmpty(clients); + clients.forEach((client) => { + assert.equal(client.type, "walletClient"); + assert.equal(client.chain.id, chains.mainnet.id); + }); + assert.equal(clients[0].account.address, "0x1"); + assert.equal(clients[1].account.address, "0x2"); + }); + + it("should return a list of wallet clients with custom parameters", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + + const clients = await innerGetWalletClients( + provider, + chains.mainnet, + ["0x1", "0x2"], + { + pollingInterval: 1000, + cacheTime: 2000, + } + ); + + assert.isArray(clients); + assert.isNotEmpty(clients); + clients.forEach((client) => { + assert.equal(client.pollingInterval, 1000); + assert.equal(client.cacheTime, 2000); + }); + }); + + it("should return a list of wallet clients with default parameters for development networks", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + + const clients = await innerGetWalletClients(provider, chains.hardhat, [ + "0x1", + "0x2", + ]); + + assert.isArray(clients); + assert.isNotEmpty(clients); + clients.forEach((client) => { + assert.equal(client.pollingInterval, 50); + assert.equal(client.cacheTime, 0); + assert.equal(client.transport.retryCount, 0); + }); + }); + + it("should retry failed calls on wallet client", async () => { + const provider = new EthereumMockedProvider(); + + const [client] = await innerGetWalletClients(provider, chains.mainnet, [ + "0x1", + ]); + + await expect(client.getChainId()).to.eventually.be.rejectedWith( + /unknown RPC error/ + ); + assert.equal(provider.calledCount, 4); + }); + + it("should not retry failed calls on wallet client when using a development network", async () => { + const provider = new EthereumMockedProvider(); + + const [client] = await innerGetWalletClients(provider, chains.hardhat, [ + "0x1", + ]); + + await expect(client.getChainId()).to.eventually.be.rejectedWith( + /unknown RPC error/ + ); + assert.equal(provider.calledCount, 1); + }); + + it("should return an empty array if there are no accounts owned by the user", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + + const clients = await innerGetWalletClients(provider, chains.mainnet, []); + + assert.isArray(clients); + assert.isEmpty(clients); + }); + }); + + describe("innerGetTestClient", () => { + it("should return a test client with hardhat mode", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + + const client = await innerGetTestClient( + provider, + chains.hardhat, + "hardhat" + ); + + assert.isDefined(client); + assert.equal(client.type, "testClient"); + assert.equal(client.chain.id, chains.hardhat.id); + assert.equal(client.mode, "hardhat"); + }); + + it("should return a test client with anvil mode", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + + const client = await innerGetTestClient( + provider, + chains.foundry, + "anvil" + ); + + assert.isDefined(client); + assert.equal(client.type, "testClient"); + assert.equal(client.chain.id, chains.foundry.id); + assert.equal(client.mode, "anvil"); + }); + + it("should return a test client with custom parameters", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + + const client = await innerGetTestClient( + provider, + chains.hardhat, + "hardhat", + { + pollingInterval: 1000, + cacheTime: 2000, + } + ); + + assert.equal(client.pollingInterval, 1000); + assert.equal(client.cacheTime, 2000); + }); + + it("should return a test client with default parameters for development networks", async () => { + const provider: EthereumProvider = new EthereumMockedProvider(); + + const client = await innerGetTestClient( + provider, + chains.hardhat, + "hardhat" + ); + + assert.equal(client.pollingInterval, 50); + assert.equal(client.cacheTime, 0); + assert.equal(client.transport.retryCount, 0); + }); + + it("should not retry failed calls on test client", async () => { + const provider = new EthereumMockedProvider(); + + const client = await innerGetTestClient( + provider, + chains.hardhat, + "hardhat" + ); + + await expect(client.getAutomine()).to.eventually.be.rejectedWith( + /unknown RPC error/ + ); + assert.equal(provider.calledCount, 1); + }); + }); +}); diff --git a/packages/hardhat-viem/test/fixture-projects/hardhat-project/contracts/ConstructorLib.sol b/packages/hardhat-viem/test/fixture-projects/hardhat-project/contracts/ConstructorLib.sol new file mode 100644 index 0000000000..0c7e22222f --- /dev/null +++ b/packages/hardhat-viem/test/fixture-projects/hardhat-project/contracts/ConstructorLib.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +library ConstructorLib { + function libDo(uint256 n) pure external returns (uint256) { + return n * n; + } +} diff --git a/packages/hardhat-viem/test/fixture-projects/hardhat-project/contracts/WithConstructorArgs.sol b/packages/hardhat-viem/test/fixture-projects/hardhat-project/contracts/WithConstructorArgs.sol new file mode 100644 index 0000000000..3352d4fad5 --- /dev/null +++ b/packages/hardhat-viem/test/fixture-projects/hardhat-project/contracts/WithConstructorArgs.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +contract WithConstructorArgs { + uint256 public data; + address public owner; + + constructor(uint256 _data) { + data = _data; + owner = msg.sender; + } + + function setData(uint256 _newValue) external { + data = _newValue; + } + + function getData() external view returns (uint256) { + return data; + } + + function getOwner() external view returns (address) { + return owner; + } +} diff --git a/packages/hardhat-viem/test/fixture-projects/hardhat-project/contracts/WithLibs.sol b/packages/hardhat-viem/test/fixture-projects/hardhat-project/contracts/WithLibs.sol new file mode 100644 index 0000000000..7c6c052a3d --- /dev/null +++ b/packages/hardhat-viem/test/fixture-projects/hardhat-project/contracts/WithLibs.sol @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +import { ConstructorLib as ExternalConstructorLib } from './ConstructorLib.sol'; + +library NormalLib { + function libDo(uint256 n) pure external returns (uint256) { + return n * 2; + } +} + +library ConstructorLib { + function libDo(uint256 n) pure external returns (uint256) { + return n * 4; + } +} + +contract OnlyNormalLib { + + string message = "placeholder1"; + + constructor() {} + + function getNumber(uint256 aNumber) pure public returns (uint256) { + return NormalLib.libDo(aNumber); + } +} + +contract OnlyConstructorLib { + + uint256 public someNumber; + string message = "placeholder2"; + + constructor(uint256 aNumber) { + someNumber = ConstructorLib.libDo(aNumber); + } + + function getNumber() view public returns (uint256) { + return someNumber; + } +} + +contract BothLibs { + + uint256 public someNumber; + string message = "placeholder3"; + + constructor(uint256 aNumber) { + someNumber = ConstructorLib.libDo(aNumber); + } + + function getNumber(uint256 aNumber) pure public returns (uint256) { + return NormalLib.libDo(aNumber); + } + + function getNumber() view public returns (uint256) { + return someNumber; + } +} + +contract BothConstructorLibs { + uint256 public someNumber; + string message = "placeholder4"; + + constructor(uint256 aNumber) { + someNumber = ExternalConstructorLib.libDo(ConstructorLib.libDo(aNumber)); + } + + function getNumber() view public returns (uint256) { + return someNumber; + } +} diff --git a/packages/hardhat-viem/test/fixture-projects/hardhat-project/contracts/WithoutConstructorArgs.sol b/packages/hardhat-viem/test/fixture-projects/hardhat-project/contracts/WithoutConstructorArgs.sol new file mode 100644 index 0000000000..80d165a039 --- /dev/null +++ b/packages/hardhat-viem/test/fixture-projects/hardhat-project/contracts/WithoutConstructorArgs.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +contract WithoutConstructorArgs { + uint256 public data; + address public owner; + + constructor() payable { + owner = msg.sender; + } + + function setData(uint256 _newValue) external { + data = _newValue; + } + + function getData() external view returns (uint256) { + return data; + } + + function getOwner() external view returns (address) { + return owner; + } +} diff --git a/packages/hardhat-viem/test/fixture-projects/hardhat-project/hardhat.config.js b/packages/hardhat-viem/test/fixture-projects/hardhat-project/hardhat.config.js new file mode 100644 index 0000000000..a59d1ed4d8 --- /dev/null +++ b/packages/hardhat-viem/test/fixture-projects/hardhat-project/hardhat.config.js @@ -0,0 +1,5 @@ +require("../../../src/index"); + +module.exports = { + solidity: "0.8.19", +}; diff --git a/packages/hardhat-viem/test/fixture-projects/type-generation/contracts/A.sol b/packages/hardhat-viem/test/fixture-projects/type-generation/contracts/A.sol new file mode 100644 index 0000000000..ad028f8b3a --- /dev/null +++ b/packages/hardhat-viem/test/fixture-projects/type-generation/contracts/A.sol @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +contract A { + address owner; + string name; + + constructor(address _owner, uint256, string memory _name) { + owner = _owner; + name = _name; + } + + function getA() public pure returns (uint256) { + return 1; + } + + function getOwner() public view returns (address) { + return owner; + } +} + +contract B { + function getB() public pure returns (uint256) { + return 2; + } +} diff --git a/packages/hardhat-viem/test/fixture-projects/type-generation/contracts/C.sol b/packages/hardhat-viem/test/fixture-projects/type-generation/contracts/C.sol new file mode 100644 index 0000000000..9bac18334d --- /dev/null +++ b/packages/hardhat-viem/test/fixture-projects/type-generation/contracts/C.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity 0.8.19; + +contract C { + function getC() public pure returns (uint256) { + return 3; + } +} + +contract B { + uint256 b; + string s; + + constructor(uint256 _b, string memory _s) { + b = _b; + s = _s; + } + + function getB() public view returns (uint256) { + return b; + } +} diff --git a/packages/hardhat-viem/test/fixture-projects/type-generation/hardhat.config.js b/packages/hardhat-viem/test/fixture-projects/type-generation/hardhat.config.js new file mode 100644 index 0000000000..a59d1ed4d8 --- /dev/null +++ b/packages/hardhat-viem/test/fixture-projects/type-generation/hardhat.config.js @@ -0,0 +1,5 @@ +require("../../../src/index"); + +module.exports = { + solidity: "0.8.19", +}; diff --git a/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/artifacts.d.ts b/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/artifacts.d.ts new file mode 100644 index 0000000000..c01f03bcd3 --- /dev/null +++ b/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/artifacts.d.ts @@ -0,0 +1,16 @@ +// This file was autogenerated by hardhat-viem, do not edit it. +// prettier-ignore +// tslint:disable +// eslint-disable + +import "hardhat/types/artifacts"; + +declare module "hardhat/types/artifacts" { + interface ArtifactsMap { + B: never; + } + + interface ContractTypesMap { + B: never; + } +} diff --git a/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/A.sol/A.d.ts b/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/A.sol/A.d.ts new file mode 100644 index 0000000000..912e6385cd --- /dev/null +++ b/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/A.sol/A.d.ts @@ -0,0 +1,108 @@ +// This file was autogenerated by hardhat-viem, do not edit it. +// prettier-ignore +// tslint:disable +// eslint-disable + +import type { Address } from "viem"; +import type { AbiParameterToPrimitiveType, GetContractReturnType } from "@nomicfoundation/hardhat-viem/types"; +import "@nomicfoundation/hardhat-viem/types"; + +export interface A$Type { + "_format": "hh-sol-artifact-1", + "contractName": "A", + "sourceName": "contracts/A.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "address", + "name": "_owner", + "type": "address" + }, + { + "internalType": "uint256", + "name": "", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_name", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "getA", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "getOwner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b5060405161076938038061076983398181016040528101906100329190610293565b826000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080600190816100819190610519565b505050506105eb565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100c98261009e565b9050919050565b6100d9816100be565b81146100e457600080fd5b50565b6000815190506100f6816100d0565b92915050565b6000819050919050565b61010f816100fc565b811461011a57600080fd5b50565b60008151905061012c81610106565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6101858261013c565b810181811067ffffffffffffffff821117156101a4576101a361014d565b5b80604052505050565b60006101b761008a565b90506101c3828261017c565b919050565b600067ffffffffffffffff8211156101e3576101e261014d565b5b6101ec8261013c565b9050602081019050919050565b60005b838110156102175780820151818401526020810190506101fc565b60008484015250505050565b6000610236610231846101c8565b6101ad565b90508281526020810184848401111561025257610251610137565b5b61025d8482856101f9565b509392505050565b600082601f83011261027a57610279610132565b5b815161028a848260208601610223565b91505092915050565b6000806000606084860312156102ac576102ab610094565b5b60006102ba868287016100e7565b93505060206102cb8682870161011d565b925050604084015167ffffffffffffffff8111156102ec576102eb610099565b5b6102f886828701610265565b9150509250925092565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061035457607f821691505b6020821081036103675761036661030d565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026103cf7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610392565b6103d98683610392565b95508019841693508086168417925050509392505050565b6000819050919050565b600061041661041161040c846100fc565b6103f1565b6100fc565b9050919050565b6000819050919050565b610430836103fb565b61044461043c8261041d565b84845461039f565b825550505050565b600090565b61045961044c565b610464818484610427565b505050565b5b818110156104885761047d600082610451565b60018101905061046a565b5050565b601f8211156104cd5761049e8161036d565b6104a784610382565b810160208510156104b6578190505b6104ca6104c285610382565b830182610469565b50505b505050565b600082821c905092915050565b60006104f0600019846008026104d2565b1980831691505092915050565b600061050983836104df565b9150826002028217905092915050565b61052282610302565b67ffffffffffffffff81111561053b5761053a61014d565b5b610545825461033c565b61055082828561048c565b600060209050601f8311600181146105835760008415610571578287015190505b61057b85826104fd565b8655506105e3565b601f1984166105918661036d565b60005b828110156105b957848901518255600182019150602085019450602081019050610594565b868310156105d657848901516105d2601f8916826104df565b8355505b6001600288020188555050505b505050505050565b61016f806105fa6000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063893d20e81461003b578063d46300fd14610059575b600080fd5b610043610077565b60405161005091906100ea565b60405180910390f35b6100616100a0565b60405161006e919061011e565b60405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006001905090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100d4826100a9565b9050919050565b6100e4816100c9565b82525050565b60006020820190506100ff60008301846100db565b92915050565b6000819050919050565b61011881610105565b82525050565b6000602082019050610133600083018461010f565b9291505056fea264697066735822122096d0f807114d408e2aa4f29fa4fa9774523526abe709bbf7de02dbe02a245ae264736f6c63430008130033", + "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063893d20e81461003b578063d46300fd14610059575b600080fd5b610043610077565b60405161005091906100ea565b60405180910390f35b6100616100a0565b60405161006e919061011e565b60405180910390f35b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006001905090565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006100d4826100a9565b9050919050565b6100e4816100c9565b82525050565b60006020820190506100ff60008301846100db565b92915050565b6000819050919050565b61011881610105565b82525050565b6000602082019050610133600083018461010f565b9291505056fea264697066735822122096d0f807114d408e2aa4f29fa4fa9774523526abe709bbf7de02dbe02a245ae264736f6c63430008130033", + "linkReferences": {}, + "deployedLinkReferences": {} +} + +declare module "@nomicfoundation/hardhat-viem/types" { + export function deployContract( + contractName: "A", + constructorArgs: [_owner: AbiParameterToPrimitiveType<{"name":"_owner","type":"address"}>, AbiParameterToPrimitiveType<{"name":"","type":"uint256"}>, _name: AbiParameterToPrimitiveType<{"name":"_name","type":"string"}>], + config?: DeployContractConfig + ): Promise>; + export function deployContract( + contractName: "contracts/A.sol:A", + constructorArgs: [_owner: AbiParameterToPrimitiveType<{"name":"_owner","type":"address"}>, AbiParameterToPrimitiveType<{"name":"","type":"uint256"}>, _name: AbiParameterToPrimitiveType<{"name":"_name","type":"string"}>], + config?: DeployContractConfig + ): Promise>; + + export function sendDeploymentTransaction( + contractName: "A", + constructorArgs: [_owner: AbiParameterToPrimitiveType<{"name":"_owner","type":"address"}>, AbiParameterToPrimitiveType<{"name":"","type":"uint256"}>, _name: AbiParameterToPrimitiveType<{"name":"_name","type":"string"}>], + config?: SendDeploymentTransactionConfig + ): Promise<{ + contract: GetContractReturnType; + deploymentTransaction: GetTransactionReturnType; + }>; + export function sendDeploymentTransaction( + contractName: "contracts/A.sol:A", + constructorArgs: [_owner: AbiParameterToPrimitiveType<{"name":"_owner","type":"address"}>, AbiParameterToPrimitiveType<{"name":"","type":"uint256"}>, _name: AbiParameterToPrimitiveType<{"name":"_name","type":"string"}>], + config?: SendDeploymentTransactionConfig + ): Promise<{ + contract: GetContractReturnType; + deploymentTransaction: GetTransactionReturnType; + }>; + + export function getContractAt( + contractName: "A", + address: Address, + config?: GetContractAtConfig + ): Promise>; + export function getContractAt( + contractName: "contracts/A.sol:A", + address: Address, + config?: GetContractAtConfig + ): Promise>; +} diff --git a/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/A.sol/B.d.ts b/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/A.sol/B.d.ts new file mode 100644 index 0000000000..917fea72bd --- /dev/null +++ b/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/A.sol/B.d.ts @@ -0,0 +1,56 @@ +// This file was autogenerated by hardhat-viem, do not edit it. +// prettier-ignore +// tslint:disable +// eslint-disable + +import type { Address } from "viem"; +import type { GetContractReturnType } from "@nomicfoundation/hardhat-viem/types"; +import "@nomicfoundation/hardhat-viem/types"; + +export interface B$Type { + "_format": "hh-sol-artifact-1", + "contractName": "B", + "sourceName": "contracts/A.sol", + "abi": [ + { + "inputs": [], + "name": "getB", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b5060b68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063a1c5191514602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b60006002905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b9291505056fea2646970667358221220fe48236ca287d1fb02c67c759d4bbebdc9702638fef90f605955fa2db9c0049864736f6c63430008130033", + "deployedBytecode": "0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063a1c5191514602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b60006002905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b9291505056fea2646970667358221220fe48236ca287d1fb02c67c759d4bbebdc9702638fef90f605955fa2db9c0049864736f6c63430008130033", + "linkReferences": {}, + "deployedLinkReferences": {} +} + +declare module "@nomicfoundation/hardhat-viem/types" { + export function deployContract( + contractName: "contracts/A.sol:B", + constructorArgs?: [], + config?: DeployContractConfig + ): Promise>; + + export function sendDeploymentTransaction( + contractName: "contracts/A.sol:B", + constructorArgs?: [], + config?: SendDeploymentTransactionConfig + ): Promise<{ + contract: GetContractReturnType; + deploymentTransaction: GetTransactionReturnType; + }>; + + export function getContractAt( + contractName: "contracts/A.sol:B", + address: Address, + config?: GetContractAtConfig + ): Promise>; +} diff --git a/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/A.sol/artifacts.d.ts b/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/A.sol/artifacts.d.ts new file mode 100644 index 0000000000..270ec057ef --- /dev/null +++ b/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/A.sol/artifacts.d.ts @@ -0,0 +1,26 @@ +// This file was autogenerated by hardhat-viem, do not edit it. +// prettier-ignore +// tslint:disable +// eslint-disable + +import "hardhat/types/artifacts"; +import type { GetContractReturnType } from "@nomicfoundation/hardhat-viem/types"; + +import { A$Type } from "./A"; +import { B$Type } from "./B"; + +declare module "hardhat/types/artifacts" { + interface ArtifactsMap { + ["A"]: A$Type; + ["B"]: B$Type; + ["contracts/A.sol:A"]: A$Type; + ["contracts/A.sol:B"]: B$Type; + } + + interface ContractTypesMap { + ["A"]: GetContractReturnType; + ["B"]: GetContractReturnType; + ["contracts/A.sol:A"]: GetContractReturnType; + ["contracts/A.sol:B"]: GetContractReturnType; + } +} diff --git a/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/C.sol/B.d.ts b/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/C.sol/B.d.ts new file mode 100644 index 0000000000..2f0deb8393 --- /dev/null +++ b/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/C.sol/B.d.ts @@ -0,0 +1,72 @@ +// This file was autogenerated by hardhat-viem, do not edit it. +// prettier-ignore +// tslint:disable +// eslint-disable + +import type { Address } from "viem"; +import type { AbiParameterToPrimitiveType, GetContractReturnType } from "@nomicfoundation/hardhat-viem/types"; +import "@nomicfoundation/hardhat-viem/types"; + +export interface B$Type { + "_format": "hh-sol-artifact-1", + "contractName": "B", + "sourceName": "contracts/C.sol", + "abi": [ + { + "inputs": [ + { + "internalType": "uint256", + "name": "_b", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_s", + "type": "string" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "getB", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b50604051610604380380610604833981810160405281019061003291906101fb565b816000819055508060019081610048919061046e565b505050610540565b6000604051905090565b600080fd5b600080fd5b6000819050919050565b61007781610064565b811461008257600080fd5b50565b6000815190506100948161006e565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6100ed826100a4565b810181811067ffffffffffffffff8211171561010c5761010b6100b5565b5b80604052505050565b600061011f610050565b905061012b82826100e4565b919050565b600067ffffffffffffffff82111561014b5761014a6100b5565b5b610154826100a4565b9050602081019050919050565b60005b8381101561017f578082015181840152602081019050610164565b60008484015250505050565b600061019e61019984610130565b610115565b9050828152602081018484840111156101ba576101b961009f565b5b6101c5848285610161565b509392505050565b600082601f8301126101e2576101e161009a565b5b81516101f284826020860161018b565b91505092915050565b600080604083850312156102125761021161005a565b5b600061022085828601610085565b925050602083015167ffffffffffffffff8111156102415761024061005f565b5b61024d858286016101cd565b9150509250929050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806102a957607f821691505b6020821081036102bc576102bb610262565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026103247fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826102e7565b61032e86836102e7565b95508019841693508086168417925050509392505050565b6000819050919050565b600061036b61036661036184610064565b610346565b610064565b9050919050565b6000819050919050565b61038583610350565b61039961039182610372565b8484546102f4565b825550505050565b600090565b6103ae6103a1565b6103b981848461037c565b505050565b5b818110156103dd576103d26000826103a6565b6001810190506103bf565b5050565b601f821115610422576103f3816102c2565b6103fc846102d7565b8101602085101561040b578190505b61041f610417856102d7565b8301826103be565b50505b505050565b600082821c905092915050565b600061044560001984600802610427565b1980831691505092915050565b600061045e8383610434565b9150826002028217905092915050565b61047782610257565b67ffffffffffffffff8111156104905761048f6100b5565b5b61049a8254610291565b6104a58282856103e1565b600060209050601f8311600181146104d857600084156104c6578287015190505b6104d08582610452565b865550610538565b601f1984166104e6866102c2565b60005b8281101561050e578489015182556001820191506020850194506020810190506104e9565b8683101561052b5784890151610527601f891682610434565b8355505b6001600288020188555050505b505050505050565b60b68061054e6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063a1c5191514602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b60008054905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b9291505056fea2646970667358221220d9268b96329d3a8617cfa3925eac59afcfbe7935e6fa7baab75e296746f136f264736f6c63430008130033", + "deployedBytecode": "0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063a1c5191514602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b60008054905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b9291505056fea2646970667358221220d9268b96329d3a8617cfa3925eac59afcfbe7935e6fa7baab75e296746f136f264736f6c63430008130033", + "linkReferences": {}, + "deployedLinkReferences": {} +} + +declare module "@nomicfoundation/hardhat-viem/types" { + export function deployContract( + contractName: "contracts/C.sol:B", + constructorArgs: [_b: AbiParameterToPrimitiveType<{"name":"_b","type":"uint256"}>, _s: AbiParameterToPrimitiveType<{"name":"_s","type":"string"}>], + config?: DeployContractConfig + ): Promise>; + + export function sendDeploymentTransaction( + contractName: "contracts/C.sol:B", + constructorArgs: [_b: AbiParameterToPrimitiveType<{"name":"_b","type":"uint256"}>, _s: AbiParameterToPrimitiveType<{"name":"_s","type":"string"}>], + config?: SendDeploymentTransactionConfig + ): Promise<{ + contract: GetContractReturnType; + deploymentTransaction: GetTransactionReturnType; + }>; + + export function getContractAt( + contractName: "contracts/C.sol:B", + address: Address, + config?: GetContractAtConfig + ): Promise>; +} diff --git a/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/C.sol/C.d.ts b/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/C.sol/C.d.ts new file mode 100644 index 0000000000..cc7edacffa --- /dev/null +++ b/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/C.sol/C.d.ts @@ -0,0 +1,74 @@ +// This file was autogenerated by hardhat-viem, do not edit it. +// prettier-ignore +// tslint:disable +// eslint-disable + +import type { Address } from "viem"; +import type { GetContractReturnType } from "@nomicfoundation/hardhat-viem/types"; +import "@nomicfoundation/hardhat-viem/types"; + +export interface C$Type { + "_format": "hh-sol-artifact-1", + "contractName": "C", + "sourceName": "contracts/C.sol", + "abi": [ + { + "inputs": [], + "name": "getC", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + } + ], + "bytecode": "0x608060405234801561001057600080fd5b5060b68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063a2375d1e14602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b60006003905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b9291505056fea264697066735822122047c1ea5199833309c2261ac9cf25569e6acf133d1cf8dc638f656e33f555635d64736f6c63430008130033", + "deployedBytecode": "0x6080604052348015600f57600080fd5b506004361060285760003560e01c8063a2375d1e14602d575b600080fd5b60336047565b604051603e91906067565b60405180910390f35b60006003905090565b6000819050919050565b6061816050565b82525050565b6000602082019050607a6000830184605a565b9291505056fea264697066735822122047c1ea5199833309c2261ac9cf25569e6acf133d1cf8dc638f656e33f555635d64736f6c63430008130033", + "linkReferences": {}, + "deployedLinkReferences": {} +} + +declare module "@nomicfoundation/hardhat-viem/types" { + export function deployContract( + contractName: "C", + constructorArgs?: [], + config?: DeployContractConfig + ): Promise>; + export function deployContract( + contractName: "contracts/C.sol:C", + constructorArgs?: [], + config?: DeployContractConfig + ): Promise>; + + export function sendDeploymentTransaction( + contractName: "C", + constructorArgs?: [], + config?: SendDeploymentTransactionConfig + ): Promise<{ + contract: GetContractReturnType; + deploymentTransaction: GetTransactionReturnType; + }>; + export function sendDeploymentTransaction( + contractName: "contracts/C.sol:C", + constructorArgs?: [], + config?: SendDeploymentTransactionConfig + ): Promise<{ + contract: GetContractReturnType; + deploymentTransaction: GetTransactionReturnType; + }>; + + export function getContractAt( + contractName: "C", + address: Address, + config?: GetContractAtConfig + ): Promise>; + export function getContractAt( + contractName: "contracts/C.sol:C", + address: Address, + config?: GetContractAtConfig + ): Promise>; +} diff --git a/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/C.sol/artifacts.d.ts b/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/C.sol/artifacts.d.ts new file mode 100644 index 0000000000..1171b90f27 --- /dev/null +++ b/packages/hardhat-viem/test/fixture-projects/type-generation/snapshots/contracts/C.sol/artifacts.d.ts @@ -0,0 +1,26 @@ +// This file was autogenerated by hardhat-viem, do not edit it. +// prettier-ignore +// tslint:disable +// eslint-disable + +import "hardhat/types/artifacts"; +import type { GetContractReturnType } from "@nomicfoundation/hardhat-viem/types"; + +import { B$Type } from "./B"; +import { C$Type } from "./C"; + +declare module "hardhat/types/artifacts" { + interface ArtifactsMap { + ["B"]: B$Type; + ["C"]: C$Type; + ["contracts/C.sol:B"]: B$Type; + ["contracts/C.sol:C"]: C$Type; + } + + interface ContractTypesMap { + ["B"]: GetContractReturnType; + ["C"]: GetContractReturnType; + ["contracts/C.sol:B"]: GetContractReturnType; + ["contracts/C.sol:C"]: GetContractReturnType; + } +} diff --git a/packages/hardhat-viem/test/helpers.ts b/packages/hardhat-viem/test/helpers.ts new file mode 100644 index 0000000000..d2a72c8391 --- /dev/null +++ b/packages/hardhat-viem/test/helpers.ts @@ -0,0 +1,63 @@ +import type { HardhatRuntimeEnvironment } from "hardhat/types"; + +import path from "path"; +import fs from "fs/promises"; +import { assert } from "chai"; +import { diffLinesUnified } from "jest-diff"; +import { resetHardhatContext } from "hardhat/plugins-testing"; + +// Import this plugin type extensions for the HardhatRuntimeEnvironment +import "../src/internal/type-extensions"; + +declare module "mocha" { + interface Context { + hre: HardhatRuntimeEnvironment; + } +} + +export const useEnvironment = (fixtureProjectName: string): void => { + before("Loading hardhat environment", function () { + process.chdir(path.join(__dirname, "fixture-projects", fixtureProjectName)); + process.env.HARDHAT_NETWORK = "hardhat"; + + this.hre = require("hardhat"); + }); + + after("Resetting hardhat context", async function () { + process.chdir(path.resolve(`${__dirname}/..`)); + resetHardhatContext(); + delete process.env.HARDHAT_NETWORK; + }); +}; + +export const assertSnapshotMatch = async ( + snapshotPath: string, + generatedFilePath: string +) => { + const expectedSnapshotContent = await fs.readFile(snapshotPath, "utf-8"); + const generatedFileContent = await fs.readFile(generatedFilePath, "utf-8"); + + if (expectedSnapshotContent !== generatedFileContent) { + assert.fail(` +Generated file differs from the expected snapshot: + +${generatedFilePath} should match ${snapshotPath} + +To update the snapshot, run: +pnpm snapshots:update + +${diffLinesUnified( + expectedSnapshotContent.split("\n"), + generatedFileContent.split("\n"), + { + contextLines: 3, + expand: false, + includeChangeCounts: true, + } +)}`); + } +}; + +export function sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} diff --git a/packages/hardhat-viem/test/integration.ts b/packages/hardhat-viem/test/integration.ts new file mode 100644 index 0000000000..b06d740485 --- /dev/null +++ b/packages/hardhat-viem/test/integration.ts @@ -0,0 +1,606 @@ +import type { Hex, TransactionReceipt } from "viem"; +import type { EthereumProvider } from "hardhat/types"; + +import path from "path"; +import { assert, expect } from "chai"; +import sinon from "sinon"; +import { getAddress, parseEther } from "viem"; + +import { TASK_CLEAN, TASK_COMPILE } from "hardhat/builtin-tasks/task-names"; +import { deployContract, innerDeployContract } from "../src/internal/contracts"; +import { EthereumMockedProvider } from "./mocks/provider"; +import { assertSnapshotMatch, sleep, useEnvironment } from "./helpers"; + +describe("Integration tests", function () { + afterEach(function () { + sinon.restore(); + }); + + describe("Hardhat Runtime Environment extension", function () { + useEnvironment("hardhat-project"); + + it("should add the viem object and it's properties", function () { + expect(this.hre.viem) + .to.be.an("object") + .that.has.all.keys([ + "getPublicClient", + "getWalletClients", + "getWalletClient", + "getTestClient", + "deployContract", + "sendDeploymentTransaction", + "getContractAt", + ]); + }); + }); + + describe("Viem plugin", function () { + useEnvironment("hardhat-project"); + + before(async function () { + await this.hre.run(TASK_COMPILE, { quiet: true }); + }); + + after(async function () { + await this.hre.run(TASK_CLEAN); + }); + + beforeEach(async function () { + await this.hre.network.provider.send("hardhat_reset"); + }); + + describe("Clients", function () { + it("should be able to query the blockchain using the public client", async function () { + const client = await this.hre.viem.getPublicClient(); + const blockNumber = await client.getBlockNumber(); + + assert.equal(blockNumber, 0n); + }); + + it("should be able to query the blockchain using the wallet client", async function () { + const publicClient = await this.hre.viem.getPublicClient(); + const [fromWalletClient, toWalletClient] = + await this.hre.viem.getWalletClients(); + const fromAddress = fromWalletClient.account.address; + const toAddress = toWalletClient.account.address; + + const fromBalanceBefore = await publicClient.getBalance({ + address: fromAddress, + }); + const toBalanceBefore = await publicClient.getBalance({ + address: toAddress, + }); + + const etherAmount = parseEther("0.0001"); + const hash = await fromWalletClient.sendTransaction({ + to: toAddress, + value: etherAmount, + }); + const receipt = await publicClient.waitForTransactionReceipt({ hash }); + const transactionFee = receipt.gasUsed * receipt.effectiveGasPrice; + + const fromBalanceAfter = await publicClient.getBalance({ + address: fromAddress, + }); + const toBalanceAfter = await publicClient.getBalance({ + address: toAddress, + }); + + assert.isDefined(receipt); + assert.equal(receipt.status, "success"); + assert.equal( + fromBalanceAfter, + fromBalanceBefore - etherAmount - transactionFee + ); + assert.equal(toBalanceAfter, toBalanceBefore + etherAmount); + }); + + it("should be able to query the blockchain using the test client", async function () { + const publicClient = await this.hre.viem.getPublicClient(); + const testClient = await this.hre.viem.getTestClient(); + + await testClient.mine({ + blocks: 1000000, + }); + const blockNumber = await publicClient.getBlockNumber(); + assert.equal(blockNumber, 1000000n); + }); + }); + + describe("deployContract", function () { + it("should be able to deploy a contract without constructor args", async function () { + const contract = await this.hre.viem.deployContract( + "WithoutConstructorArgs" + ); + + await contract.write.setData([50n]); + const data = await contract.read.getData(); + assert.equal(data, 50n); + }); + + it("should be able to deploy a contract with constructor args", async function () { + const [defaultWalletClient] = await this.hre.viem.getWalletClients(); + const contract = await this.hre.viem.deployContract( + "WithConstructorArgs", + [50n] + ); + + let data = await contract.read.getData(); + assert.equal(data, 50n); + + const owner = await contract.read.getOwner(); + assert.equal(owner, getAddress(defaultWalletClient.account.address)); + + await contract.write.setData([100n]); + data = await contract.read.getData(); + assert.equal(data, 100n); + }); + + it("should be able to deploy a contract with a different wallet client", async function () { + const [_, secondWalletClient] = await this.hre.viem.getWalletClients(); + const contract = await this.hre.viem.deployContract( + "WithoutConstructorArgs", + [], + { client: { wallet: secondWalletClient } } + ); + + const owner = await contract.read.getOwner(); + assert.equal(owner, getAddress(secondWalletClient.account.address)); + }); + + it("should be able to deploy a contract with initial ETH", async function () { + const publicClient = await this.hre.viem.getPublicClient(); + const [defaultWalletClient] = await this.hre.viem.getWalletClients(); + const ownerBalanceBefore = await publicClient.getBalance({ + address: defaultWalletClient.account.address, + }); + const etherAmount = parseEther("0.0001"); + const contract = await this.hre.viem.deployContract( + "WithoutConstructorArgs", + [], + { value: etherAmount } + ); + const ownerBalanceAfter = await publicClient.getBalance({ + address: defaultWalletClient.account.address, + }); + const contractBalance = await publicClient.getBalance({ + address: contract.address, + }); + const block = await publicClient.getBlock({ + includeTransactions: true, + }); + const receipt = await publicClient.getTransactionReceipt({ + hash: block.transactions[0].hash, + }); + const transactionFee = receipt.gasUsed * receipt.effectiveGasPrice; + + assert.equal(contractBalance, etherAmount); + assert.equal( + ownerBalanceAfter, + ownerBalanceBefore - etherAmount - transactionFee + ); + }); + + it("should be able to deploy a contract with normal library linked", async function () { + const normalLibContract = await this.hre.viem.deployContract( + "NormalLib" + ); + + const contract = await this.hre.viem.deployContract( + "OnlyNormalLib", + [], + { + libraries: { + NormalLib: normalLibContract.address, + }, + } + ); + + await expect(contract.read.getNumber([2n])).to.eventually.equal(4n); + }); + + it("should be able to deploy a contract with constructor library linked", async function () { + const ctorLibContract = await this.hre.viem.deployContract( + "contracts/WithLibs.sol:ConstructorLib" + ); + + const contract = await this.hre.viem.deployContract( + "OnlyConstructorLib", + [2n], + { + libraries: { + ConstructorLib: ctorLibContract.address, + }, + } + ); + + await expect(contract.read.getNumber([])).to.eventually.equal(8n); + }); + + it("should be able to deploy a contract with both normal and constructor libraries linked", async function () { + const [ctorLibContract, normalLibContract] = await Promise.all([ + this.hre.viem.deployContract("contracts/WithLibs.sol:ConstructorLib"), + this.hre.viem.deployContract("NormalLib"), + ]); + + const contract = await this.hre.viem.deployContract("BothLibs", [3n], { + libraries: { + ConstructorLib: ctorLibContract.address, + NormalLib: normalLibContract.address, + }, + }); + + await expect(contract.read.getNumber([])).to.eventually.equal(12n); + await expect(contract.read.getNumber([5n])).to.eventually.equal(10n); + }); + + it("should throw an error if the contract address can't be retrieved", async function () { + const publicClient = await this.hre.viem.getPublicClient(); + sinon.stub(publicClient, "waitForTransactionReceipt").returns( + Promise.resolve({ + contractAddress: null, + }) as unknown as Promise + ); + const [walletClient] = await this.hre.viem.getWalletClients(); + const contractArtifact = await this.hre.artifacts.readArtifact( + "WithoutConstructorArgs" + ); + + await expect( + innerDeployContract( + publicClient, + walletClient, + contractArtifact.abi, + contractArtifact.bytecode as Hex, + [] + ) + ).to.be.rejectedWith( + /The deployment transaction '0x[a-fA-F0-9]{64}' was mined in block '\d+' but its receipt doesn't contain a contract address/ + ); + }); + + it("should throw an error if no accounts are configured for the network", async function () { + const provider: EthereumProvider = new EthereumMockedProvider(); + const sendStub = sinon.stub(provider, "send"); + sendStub.withArgs("eth_accounts").returns(Promise.resolve([])); + const hre = { + ...this.hre, + network: { + ...this.hre.network, + provider, + }, + }; + + await expect( + deployContract(hre, "WithoutConstructorArgs") + ).to.be.rejectedWith( + /Default wallet client not found. This can happen if no accounts were configured for this network/ + ); + }); + + it("should wait for confirmations", async function () { + const publicClient = await this.hre.viem.getPublicClient(); + const testClient = await this.hre.viem.getTestClient(); + const sleepingTime = 2 * publicClient.pollingInterval; + await testClient.setAutomine(false); + + let contractPromiseResolved = false; + const contractPromise = this.hre.viem + .deployContract("WithoutConstructorArgs", [], { + confirmations: 5, + }) + .then(() => { + contractPromiseResolved = true; + }); + await sleep(sleepingTime); + assert.isFalse(contractPromiseResolved); + + await testClient.mine({ + blocks: 3, + }); + await sleep(sleepingTime); + assert.isFalse(contractPromiseResolved); + + await testClient.mine({ + blocks: 1, + }); + await sleep(sleepingTime); + assert.isFalse(contractPromiseResolved); + + await testClient.mine({ + blocks: 1, + }); + await contractPromise; + assert.isTrue(contractPromiseResolved); + }); + + it("should throw if the confirmations parameter is less than 0", async function () { + await expect( + this.hre.viem.deployContract("WithoutConstructorArgs", [], { + confirmations: -1, + }) + ).to.be.rejectedWith("Confirmations must be greater than 0."); + }); + + it("should throw if the confirmations parameter is 0", async function () { + await expect( + this.hre.viem.deployContract("WithoutConstructorArgs", [], { + confirmations: 0, + }) + ).to.be.rejectedWith( + "deployContract does not support 0 confirmations. Use sendDeploymentTransaction if you want to handle the deployment transaction yourself." + ); + }); + + it("should throw if there are any missing libraries", async function () { + await expect( + this.hre.viem.deployContract("OnlyNormalLib", [], {}) + ).to.be.rejectedWith( + `The libraries needed are:\n\t* "contracts/WithLibs.sol:NormalLib"\nPlease deploy them first and link them while deploying "OnlyNormalLib"` + ); + }); + + it("should throw if there are libraries that are not needed", async function () { + const ctorLibContract = await this.hre.viem.deployContract( + "contracts/WithLibs.sol:ConstructorLib" + ); + + await expect( + this.hre.viem.deployContract("NormalLib", [], { + libraries: { + ConstructorLib: ctorLibContract.address, + }, + }) + ).to.be.rejectedWith( + `The library name "ConstructorLib" was linked but it's not referenced by the "NormalLib" contract.` + ); + + const numberLibContract = await this.hre.viem.deployContract( + "NormalLib" + ); + + await expect( + this.hre.viem.deployContract("OnlyConstructorLib", [], { + libraries: { + ConstructorLib: ctorLibContract.address, + NormalLib: numberLibContract.address, + }, + }) + ).to.be.rejectedWith( + `The library name "NormalLib" was linked but it's not referenced by the "OnlyConstructorLib" contract.` + ); + }); + + it("should throw if there are too ambiguous libraries linked", async function () { + const externalCtorLibContract = await this.hre.viem.deployContract( + "contracts/ConstructorLib.sol:ConstructorLib" + ); + const ctorLibContract = await this.hre.viem.deployContract( + "contracts/WithLibs.sol:ConstructorLib" + ); + + await expect( + this.hre.viem.deployContract("BothConstructorLibs", [1n], { + libraries: { + ConstructorLib: ctorLibContract.address, + }, + }) + ).to.be.rejectedWith( + `The library name "ConstructorLib" is ambiguous for the contract "BothConstructorLibs". +It may resolve to one of the following libraries: + +\t* contracts/ConstructorLib.sol:ConstructorLib, +\t* contracts/WithLibs.sol:ConstructorLib + +To fix this, choose one of these fully qualified library names and replace where appropriate.` + ); + + await expect( + this.hre.viem.deployContract("BothConstructorLibs", [1n], { + libraries: { + "contracts/ConstructorLib.sol:ConstructorLib": + externalCtorLibContract.address, + ConstructorLib: ctorLibContract.address, + }, + }) + ).to.be + .rejectedWith(`The library name "ConstructorLib" is ambiguous for the contract "BothConstructorLibs". +It may resolve to one of the following libraries: + +\t* contracts/ConstructorLib.sol:ConstructorLib, +\t* contracts/WithLibs.sol:ConstructorLib + +To fix this, choose one of these fully qualified library names and replace where appropriate.`); + + const contract = await this.hre.viem.deployContract( + "BothConstructorLibs", + [2n], + { + libraries: { + "contracts/ConstructorLib.sol:ConstructorLib": + externalCtorLibContract.address, + "contracts/WithLibs.sol:ConstructorLib": ctorLibContract.address, + }, + } + ); + + await expect(contract.read.getNumber([])).to.eventually.equal(64n); + }); + }); + + describe("sendDeploymentTransaction", function () { + it("should return the contract and the deployment transaction", async function () { + const publicClient = await this.hre.viem.getPublicClient(); + const { contract, deploymentTransaction } = + await this.hre.viem.sendDeploymentTransaction( + "WithoutConstructorArgs" + ); + assert.exists(contract); + assert.exists(deploymentTransaction); + + const { contractAddress } = + await publicClient.waitForTransactionReceipt({ + hash: deploymentTransaction.hash, + }); + assert.equal(contract.address, getAddress(contractAddress!)); + + await contract.write.setData([50n]); + const data = await contract.read.getData(); + assert.equal(data, 50n); + }); + }); + + it("should return the contract with linked libraries and the deployment transaction", async function () { + const publicClient = await this.hre.viem.getPublicClient(); + const normalLib = await this.hre.viem.sendDeploymentTransaction( + "NormalLib", + [] + ); + + const { contractAddress: libContractAddress } = + await publicClient.waitForTransactionReceipt({ + hash: normalLib.deploymentTransaction.hash, + }); + + assert.isNotNull( + libContractAddress, + "library contract should be deployed" + ); + + const { contract, deploymentTransaction } = + await this.hre.viem.sendDeploymentTransaction("OnlyNormalLib", [], { + libraries: { NormalLib: libContractAddress! }, + }); + assert.exists(contract); + assert.exists(deploymentTransaction); + + const { contractAddress } = await publicClient.waitForTransactionReceipt({ + hash: deploymentTransaction.hash, + }); + assert.equal(contract.address, getAddress(contractAddress!)); + + await expect(contract.read.getNumber([50n])).to.eventually.equal(100n); + }); + }); + + describe("Contract type generation", function () { + useEnvironment("type-generation"); + + before(async function () { + await this.hre.run(TASK_COMPILE, { quiet: true }); + }); + + after(async function () { + await this.hre.run(TASK_CLEAN); + }); + + it("should generate artifacts.d.ts", async function () { + const snapshotPath = path.join("snapshots", "artifacts.d.ts"); + const generatedFilePath = path.join("artifacts", "artifacts.d.ts"); + + await assertSnapshotMatch(snapshotPath, generatedFilePath); + }); + + it("should generate contracts/A.sol/A.d.ts", async function () { + const snapshotPath = path.join( + "snapshots", + "contracts", + "A.sol", + "A.d.ts" + ); + const generatedFilePath = path.join( + "artifacts", + "contracts", + "A.sol", + "A.d.ts" + ); + + await assertSnapshotMatch(snapshotPath, generatedFilePath); + }); + + it("should generate contracts/A.sol/B.d.ts", async function () { + const snapshotPath = path.join( + "snapshots", + "contracts", + "A.sol", + "B.d.ts" + ); + const generatedFilePath = path.join( + "artifacts", + "contracts", + "A.sol", + "B.d.ts" + ); + + await assertSnapshotMatch(snapshotPath, generatedFilePath); + }); + + it("should generate contracts/A.sol/artifacts.d.ts", async function () { + const snapshotPath = path.join( + "snapshots", + "contracts", + "A.sol", + "artifacts.d.ts" + ); + const generatedFilePath = path.join( + "artifacts", + "contracts", + "A.sol", + "artifacts.d.ts" + ); + + await assertSnapshotMatch(snapshotPath, generatedFilePath); + }); + + it("should generate contracts/C.sol/B.d.ts", async function () { + const snapshotPath = path.join( + "snapshots", + "contracts", + "C.sol", + "B.d.ts" + ); + const generatedFilePath = path.join( + "artifacts", + "contracts", + "C.sol", + "B.d.ts" + ); + + await assertSnapshotMatch(snapshotPath, generatedFilePath); + }); + + it("should generate contracts/C.sol/C.d.ts", async function () { + const snapshotPath = path.join( + "snapshots", + "contracts", + "C.sol", + "C.d.ts" + ); + const generatedFilePath = path.join( + "artifacts", + "contracts", + "C.sol", + "C.d.ts" + ); + + await assertSnapshotMatch(snapshotPath, generatedFilePath); + }); + + it("should generate contracts/C.sol/artifacts.d.ts", async function () { + const snapshotPath = path.join( + "snapshots", + "contracts", + "C.sol", + "artifacts.d.ts" + ); + const generatedFilePath = path.join( + "artifacts", + "contracts", + "C.sol", + "artifacts.d.ts" + ); + + await assertSnapshotMatch(snapshotPath, generatedFilePath); + }); + }); +}); diff --git a/packages/hardhat-viem/test/mocks/provider.ts b/packages/hardhat-viem/test/mocks/provider.ts new file mode 100644 index 0000000000..d04ef70040 --- /dev/null +++ b/packages/hardhat-viem/test/mocks/provider.ts @@ -0,0 +1,29 @@ +import type { + EthereumProvider, + RequestArguments, + JsonRpcRequest, + JsonRpcResponse, +} from "hardhat/types"; + +import EventEmitter from "events"; + +export class EthereumMockedProvider + extends EventEmitter + implements EthereumProvider +{ + public calledCount = 0; + + public async request(_args: RequestArguments): Promise { + this.calledCount++; + throw new Error(); + } + + public async send(_method: string, _params: any[] = []) {} + + public sendAsync( + _payload: JsonRpcRequest, + callback: (error: any, response: JsonRpcResponse) => void + ) { + callback(null, {} as JsonRpcRequest); // this is here just to finish the "async" operation + } +} diff --git a/packages/hardhat-viem/test/setup.ts b/packages/hardhat-viem/test/setup.ts new file mode 100644 index 0000000000..1c993d01e0 --- /dev/null +++ b/packages/hardhat-viem/test/setup.ts @@ -0,0 +1,6 @@ +import chai from "chai"; +import chaiAsPromised from "chai-as-promised"; + +chai.use(chaiAsPromised); + +chai.config.truncateThreshold = 0; diff --git a/packages/hardhat-viem/test/update-snapshots.ts b/packages/hardhat-viem/test/update-snapshots.ts new file mode 100644 index 0000000000..03540b8a57 --- /dev/null +++ b/packages/hardhat-viem/test/update-snapshots.ts @@ -0,0 +1,53 @@ +import path from "path"; +import fs from "fs"; + +import { TASK_COMPILE, TASK_CLEAN } from "hardhat/builtin-tasks/task-names"; +import { resetHardhatContext } from "hardhat/plugins-testing"; + +const snapshotPartialPaths = [ + "artifacts.d.ts", + path.join("contracts", "A.sol", "A.d.ts"), + path.join("contracts", "A.sol", "B.d.ts"), + path.join("contracts", "A.sol", "artifacts.d.ts"), + path.join("contracts", "C.sol", "B.d.ts"), + path.join("contracts", "C.sol", "C.d.ts"), + path.join("contracts", "C.sol", "artifacts.d.ts"), +]; + +const originalCwd = process.cwd(); + +async function updateSnapshots() { + process.chdir(path.join(__dirname, "fixture-projects", "type-generation")); + process.env.HARDHAT_NETWORK = "hardhat"; + + const hre = require("hardhat"); + await hre.run(TASK_COMPILE, { quiet: true }); + + snapshotPartialPaths.forEach((partialPath) => { + const snapshotPath = path.join(process.cwd(), "snapshots", partialPath); + const generatedFilePath = path.join( + process.cwd(), + "artifacts", + partialPath + ); + + fs.copyFileSync(generatedFilePath, snapshotPath); + }); + + await hre.run(TASK_CLEAN); + + process.chdir(path.resolve(`${__dirname}/..`)); + resetHardhatContext(); + delete process.env.HARDHAT_NETWORK; + + console.log("Snapshots updated!"); +} + +updateSnapshots() + .catch((error) => { + console.error(error); + process.exitCode = 1; + }) + .finally(() => { + process.chdir(originalCwd); + }); diff --git a/packages/hardhat-viem/tsconfig.json b/packages/hardhat-viem/tsconfig.json new file mode 100644 index 0000000000..65ecfc33b9 --- /dev/null +++ b/packages/hardhat-viem/tsconfig.json @@ -0,0 +1,15 @@ +{ + "extends": "../../config/typescript/tsconfig.json", + "compilerOptions": { + "outDir": "./build-test", + "rootDirs": ["./test"], + "composite": true + }, + "include": ["./test/**/*.ts"], + "exclude": ["./node_modules", "./test/**/hardhat.config.ts"], + "references": [ + { + "path": "./src" + } + ] +} diff --git a/packages/hardhat-vyper/.eslintrc.js b/packages/hardhat-vyper/.eslintrc.js index 889740f226..c6de07705a 100644 --- a/packages/hardhat-vyper/.eslintrc.js +++ b/packages/hardhat-vyper/.eslintrc.js @@ -1,7 +1,24 @@ +const { + slowImportsCommonIgnoredModules, +} = require("../../config/eslint/constants"); + module.exports = { extends: [`${__dirname}/../../config/eslint/eslintrc.js`], parserOptions: { project: `${__dirname}/tsconfig.json`, sourceType: "module", }, + overrides: [ + { + files: ["src/index.ts"], + rules: { + "@nomicfoundation/slow-imports/no-top-level-external-import": [ + "error", + { + ignoreModules: [...slowImportsCommonIgnoredModules], + }, + ], + }, + }, + ], }; diff --git a/packages/hardhat-vyper/.gitignore b/packages/hardhat-vyper/.gitignore index c00d7e7296..4aca21f18d 100644 --- a/packages/hardhat-vyper/.gitignore +++ b/packages/hardhat-vyper/.gitignore @@ -15,10 +15,6 @@ # Logs logs *.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json @@ -57,21 +53,15 @@ jspm_packages/ # TypeScript v1 declaration files typings/ -# Optional npm cache directory -.npm - # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history -# Output of 'npm pack' +# Output of 'pnpm pack' *.tgz -# Yarn Integrity file -.yarn-integrity - # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/packages/hardhat-vyper/.mocharc.json b/packages/hardhat-vyper/.mocharc.json index d2b0c6d38f..b21e04d8b4 100644 --- a/packages/hardhat-vyper/.mocharc.json +++ b/packages/hardhat-vyper/.mocharc.json @@ -1,5 +1,5 @@ { "require": "ts-node/register/files", "ignore": ["test/fixture-projects/**/*"], - "timeout": 25000 + "timeout": 40000 } diff --git a/packages/hardhat-vyper/CHANGELOG.md b/packages/hardhat-vyper/CHANGELOG.md index 3381fa1be6..aa0e4c5e0e 100644 --- a/packages/hardhat-vyper/CHANGELOG.md +++ b/packages/hardhat-vyper/CHANGELOG.md @@ -1,5 +1,35 @@ # @nomiclabs/hardhat-vyper +## 3.0.8 + +### Patch Changes + +- efa905d: Fix for corrupted Hardhat peer dependency version from pnpm. + +## 3.0.7 + +### Patch Changes + +- 1f9f8e0: Support Vyper 0.4.0's new output identifiers (Thanks, @kiriyaga-txfusion!) + +## 3.0.6 + +### Patch Changes + +- f0e6389: Added support for vyper settings 'evmVersion' and 'optimize' + +## 3.0.5 + +### Patch Changes + +- 2f73386b1: Fixed a problem with the Vyper compilers downloader + +## 3.0.4 + +### Patch Changes + +- 03745576c: Added a check to validate that the Brownie code does not contain the directive `#@ if mode == "test":` because we do not support this feature. + ## 3.0.3 ### Patch Changes diff --git a/packages/hardhat-vyper/LICENSE b/packages/hardhat-vyper/LICENSE index 3b8858c555..3b7e8c7eab 100644 --- a/packages/hardhat-vyper/LICENSE +++ b/packages/hardhat-vyper/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Nomic Labs LLC +Copyright (c) 2023 Nomic Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/packages/hardhat-vyper/README.md b/packages/hardhat-vyper/README.md index 66c74d3259..dd421b6742 100644 --- a/packages/hardhat-vyper/README.md +++ b/packages/hardhat-vyper/README.md @@ -58,12 +58,23 @@ module.exports = { }; ``` -You can also configure multiple versions of the Vyper compiler: +You can also configure multiple versions of the Vyper compiler, as well as the compiler settings evmVersion and optimize. See the [Vyper docs](https://docs.vyperlang.org/en/v0.3.10/compiling-a-contract.html) for more info. ```js module.exports = { vyper: { - compilers: [{ version: "0.2.1" }, { version: "0.3.0" }], + compilers: [ + { + version: "0.2.1", + }, + { + version: "0.3.10", + settings: { + evmVersion: "paris", + optimize: "gas", + }, + }, + ], }, }; ``` @@ -72,6 +83,22 @@ module.exports = { There are no additional steps you need to take for this plugin to work. +## Test directives + +Brownie allows you to use the test directive `#@ if mode == "test":` to specify when a portion of code should be included only for testing purposes. + +Example: + +```py +#@ if mode == "test": +@external +def _mint_for_testing(_to: address, _token_id: uint256): + self._mint(_to, _token_id) +#@ endif +``` + +We do NOT support this feature. An error will be thrown every time that, when compiling a contract, the directive `#@ if mode == "test":` is found. + ### Additional notes The oldest vyper version supported by this plugin is 0.2.0. Versions older than this will not work and will throw an error. diff --git a/packages/hardhat-vyper/package.json b/packages/hardhat-vyper/package.json index 64b3656a33..234c771654 100644 --- a/packages/hardhat-vyper/package.json +++ b/packages/hardhat-vyper/package.json @@ -1,6 +1,6 @@ { "name": "@nomiclabs/hardhat-vyper", - "version": "3.0.3", + "version": "3.0.8", "description": "Hardhat plugin to develop smart contracts in Vyper", "repository": "github:nomiclabs/hardhat", "homepage": "https://github.com/nomiclabs/hardhat/tree/main/packages/hardhat-vyper", @@ -16,13 +16,14 @@ "vyper" ], "scripts": { - "lint": "yarn prettier --check && yarn eslint", - "lint:fix": "yarn prettier --write && yarn eslint --fix", + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", "prettier": "prettier \"**/*.{js,md,json}\"", + "pretest": "cd ../.. && pnpm build", "test": "mocha --recursive \"test/**/*.ts\"", "build": "tsc --build .", - "prepublishOnly": "yarn build", + "prepublishOnly": "pnpm build", "clean": "rimraf dist" }, "files": [ @@ -39,27 +40,33 @@ "semver": "^6.3.0" }, "devDependencies": { + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", "@types/chai": "^4.2.0", + "@types/chai-as-promised": "^7.1.3", + "@types/debug": "^4.1.4", "@types/fs-extra": "^5.1.0", "@types/lodash": "^4.14.123", "@types/mocha": ">=9.1.0", - "@types/node": "^14.0.0", - "@typescript-eslint/eslint-plugin": "5.53.0", - "@typescript-eslint/parser": "5.53.0", + "@types/node": "^18.0.0", + "@types/semver": "^6.0.2", + "@typescript-eslint/eslint-plugin": "5.61.0", + "@typescript-eslint/parser": "5.61.0", "chai": "^4.2.0", - "eslint": "^7.29.0", + "chai-as-promised": "^7.1.1", + "eslint": "^8.44.0", "eslint-config-prettier": "8.3.0", - "eslint-plugin-import": "2.24.1", - "eslint-plugin-no-only-tests": "3.0.0", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-mocha": "10.4.1", "eslint-plugin-prettier": "3.4.0", - "hardhat": "^2.8.3", + "hardhat": "workspace:^2.8.3", "mocha": "^10.0.0", "prettier": "2.4.1", "rimraf": "^3.0.2", "ts-node": "^10.8.0", - "typescript": "~4.7.4" + "typescript": "~5.0.0" }, "peerDependencies": { - "hardhat": "^2.8.3" + "hardhat": "workspace:^2.8.3" } } diff --git a/packages/hardhat-vyper/src/compiler.ts b/packages/hardhat-vyper/src/compiler.ts index bf5f5b211f..7d529a6527 100644 --- a/packages/hardhat-vyper/src/compiler.ts +++ b/packages/hardhat-vyper/src/compiler.ts @@ -1,4 +1,7 @@ import { exec } from "child_process"; +import semver from "semver"; +import { VyperSettings } from "./types"; +import { VyperPluginError } from "./util"; export class Compiler { constructor(private _pathToVyper: string) {} @@ -6,11 +9,21 @@ export class Compiler { /** * * @param inputPaths array of paths to contracts to be compiled + * @param compilerVersion the version of the Vyper compiler + * @param settings the Vyper settings to use during compilation */ - public async compile(inputPaths: string[]) { + public async compile( + inputPaths: string[], + compilerVersion: string = "", + settings: VyperSettings = {} + ) { const output: string = await new Promise((resolve, reject) => { + const settingsCmd = getSettingsCmd(compilerVersion, settings); + const process = exec( - `${this._pathToVyper} -f combined_json ${inputPaths.join(" ")}`, + `${this._pathToVyper} ${settingsCmd} -f combined_json ${inputPaths.join( + " " + )}`, { maxBuffer: 1024 * 1024 * 500, }, @@ -28,3 +41,72 @@ export class Compiler { return JSON.parse(output); } } + +function getSettingsCmd( + compilerVersion: string, + settings: VyperSettings +): string { + let settingsStr = + settings.evmVersion !== undefined + ? `--evm-version ${settings.evmVersion} ` + : ""; + + settingsStr += getOptimize(compilerVersion, settings.optimize); + + return settingsStr; +} + +function getOptimize( + compilerVersion: string, + optimize: string | boolean | undefined +): string { + if (optimize === undefined) { + return ""; + } + + if (compilerVersion === "") { + throw new VyperPluginError( + "The 'compilerVersion' parameter must be set when the setting 'optimize' is set." + ); + } + + if (typeof optimize === "boolean") { + if (optimize) { + if ( + semver.gte(compilerVersion, "0.3.10") || + semver.lte(compilerVersion, "0.3.0") + ) { + throw new VyperPluginError( + `The 'optimize' setting with value 'true' is not supported for versions of the Vyper compiler older than or equal to 0.3.0 or newer than or equal to 0.3.10. You are currently using version ${compilerVersion}.` + ); + } + + // The optimizer is enabled by default + return ""; + } else { + if (semver.lte(compilerVersion, "0.3.0")) { + throw new VyperPluginError( + `The 'optimize' setting with value 'false' is not supported for versions of the Vyper compiler older than or equal to 0.3.0. You are currently using version ${compilerVersion}.` + ); + } + + return semver.lt(compilerVersion, "0.3.10") + ? "--no-optimize" + : "--optimize none"; + } + } + + if (typeof optimize === "string") { + if (semver.gte(compilerVersion, "0.3.10")) { + return `--optimize ${optimize}`; + } + + throw new VyperPluginError( + `The 'optimize' setting, when specified as a string value, is available only starting from the Vyper compiler version 0.3.10. You are currently using version ${compilerVersion}.` + ); + } + + throw new VyperPluginError( + `The 'optimize' setting has an invalid type value: ${typeof optimize}. Type should be either string or boolean.` + ); +} diff --git a/packages/hardhat-vyper/src/constants.ts b/packages/hardhat-vyper/src/constants.ts index a6093d25c8..f7b9dfffcc 100644 --- a/packages/hardhat-vyper/src/constants.ts +++ b/packages/hardhat-vyper/src/constants.ts @@ -3,3 +3,4 @@ export const ARTIFACT_FORMAT_VERSION = "hh-vyper-artifact-1"; export const DEBUG_NAMESPACE = "hardhat:plugin:vyper"; export const CACHE_FORMAT_VERSION = "hh-vy-cache-1"; export const VYPER_FILES_CACHE_FILENAME = "vyper-files-cache.json"; +export const OUTPUT_BREAKABLE_VYPER_VERSION = "0.4.0"; diff --git a/packages/hardhat-vyper/src/downloader.ts b/packages/hardhat-vyper/src/downloader.ts index 84dc489cf0..b645d02870 100644 --- a/packages/hardhat-vyper/src/downloader.ts +++ b/packages/hardhat-vyper/src/downloader.ts @@ -127,8 +127,10 @@ export class CompilerDownloader { } private _findVersionRelease(version: string): CompilerRelease | undefined { - return this.compilersList.find((release) => - semver.eq(release.tag_name, version) + return this.compilersList.find( + (release) => + semver.valid(release.tag_name) !== null && + semver.eq(release.tag_name, version) ); } diff --git a/packages/hardhat-vyper/src/index.ts b/packages/hardhat-vyper/src/index.ts index 25365027e7..002fef7a36 100644 --- a/packages/hardhat-vyper/src/index.ts +++ b/packages/hardhat-vyper/src/index.ts @@ -1,13 +1,13 @@ import type { Artifacts as ArtifactsImpl } from "hardhat/internal/artifacts"; import type { Artifacts } from "hardhat/types/artifacts"; -import type { VyperOutput, VyperBuild } from "./types"; +import type { VyperFilesCache as VyperFilesCacheT } from "./cache"; +import type { VyperOutput, VyperBuild, VyperSettings } from "./types"; +import type { ResolvedFile } from "./resolver"; import * as os from "os"; import fsExtra from "fs-extra"; import semver from "semver"; -import { getCompilersDir } from "hardhat/internal/util/global-dir"; -import { localPathToSourceName } from "hardhat/utils/source-names"; import { getFullyQualifiedName } from "hardhat/utils/contract-names"; import { TASK_COMPILE_GET_COMPILATION_TASKS } from "hardhat/builtin-tasks/task-names"; import { extendConfig, subtask, types } from "hardhat/config"; @@ -23,12 +23,12 @@ import { TASK_COMPILE_VYPER_LOG_DOWNLOAD_COMPILER_END, TASK_COMPILE_VYPER_LOG_COMPILATION_RESULT, } from "./task-names"; -import { DEFAULT_VYPER_VERSION } from "./constants"; -import { VyperFilesCache, getVyperFilesCachePath } from "./cache"; +import { + DEFAULT_VYPER_VERSION, + OUTPUT_BREAKABLE_VYPER_VERSION, +} from "./constants"; import { Compiler } from "./compiler"; import { CompilerDownloader } from "./downloader"; -import { Parser } from "./parser"; -import { ResolvedFile, Resolver } from "./resolver"; import { assertPluginInvariant, getArtifactFromVyperOutput, @@ -72,6 +72,9 @@ subtask(TASK_COMPILE_VYPER_GET_SOURCE_NAMES) { sourcePaths }: { sourcePaths: string[] }, { config } ): Promise => { + const { localPathToSourceName } = await import( + "hardhat/utils/source-names" + ); const sourceNames = await Promise.all( sourcePaths.map((p) => localPathToSourceName(config.paths.root, p)) ); @@ -100,6 +103,9 @@ subtask(TASK_COMPILE_VYPER_GET_BUILD) { quiet, vyperVersion }: { quiet: boolean; vyperVersion: string }, { run } ): Promise => { + const { getCompilersDir } = await import( + "hardhat/internal/util/global-dir" + ); const compilersCache = await getCompilersDir(); const downloader = new CompilerDownloader(compilersCache); @@ -185,13 +191,21 @@ subtask(TASK_COMPILE_VYPER_RUN_BINARY) async ({ inputPaths, vyperPath, + vyperVersion, + settings, }: { inputPaths: string[]; vyperPath: string; + vyperVersion?: string; + settings?: VyperSettings; }): Promise => { const compiler = new Compiler(vyperPath); - const { version, ...contracts } = await compiler.compile(inputPaths); + const { version, ...contracts } = await compiler.compile( + inputPaths, + vyperVersion, + settings + ); return { version, @@ -204,6 +218,12 @@ subtask(TASK_COMPILE_VYPER) .addParam("quiet", undefined, undefined, types.boolean) .setAction( async ({ quiet }: { quiet: boolean }, { artifacts, config, run }) => { + const { VyperFilesCache, getVyperFilesCachePath } = await import( + "./cache" + ); + const { Parser } = await import("./parser"); + const { Resolver } = await import("./resolver"); + const sourcePaths: string[] = await run( TASK_COMPILE_VYPER_GET_SOURCE_PATHS ); @@ -240,36 +260,53 @@ subtask(TASK_COMPILE_VYPER) ({ version }) => version ); - const versionGroups: Record = {}; + const versionsToSettings = Object.fromEntries( + config.vyper.compilers.map(({ version, settings }) => [ + version, + settings, + ]) + ); + + const versionGroups: Record< + string, + { files: ResolvedFile[]; settings: VyperSettings } + > = {}; const unmatchedFiles: ResolvedFile[] = []; for (const file of resolvedFiles) { - const hasChanged = vyperFilesCache.hasFileChanged( - file.absolutePath, - file.contentHash, - { version: file.content.versionPragma } - ); - - if (!hasChanged) continue; - const maxSatisfyingVersion = semver.maxSatisfying( configuredVersions, file.content.versionPragma ); - // check if there are files that don't match any configured compiler - // version + // check if there are files that don't match any configured compiler version if (maxSatisfyingVersion === null) { unmatchedFiles.push(file); continue; } + const settings = versionsToSettings[maxSatisfyingVersion] ?? {}; + + const hasChanged = vyperFilesCache.hasFileChanged( + file.absolutePath, + file.contentHash, + { + version: maxSatisfyingVersion, + settings, + } + ); + + if (!hasChanged) continue; + if (versionGroups[maxSatisfyingVersion] === undefined) { - versionGroups[maxSatisfyingVersion] = [file]; + versionGroups[maxSatisfyingVersion] = { + files: [file], + settings, + }; continue; } - versionGroups[maxSatisfyingVersion].push(file); + versionGroups[maxSatisfyingVersion].files.push(file); } if (unmatchedFiles.length > 0) { @@ -288,7 +325,9 @@ ${list}` ); } - for (const [vyperVersion, files] of Object.entries(versionGroups)) { + for (const [vyperVersion, { files, settings }] of Object.entries( + versionGroups + )) { const vyperBuild: VyperBuild = await run(TASK_COMPILE_VYPER_GET_BUILD, { quiet, vyperVersion, @@ -303,13 +342,29 @@ ${list}` { inputPaths: files.map(({ absolutePath }) => absolutePath), vyperPath: vyperBuild.compilerPath, + vyperVersion, + settings, } ); - for (const [sourceName, output] of Object.entries(contracts)) { + const { localPathToSourceName } = await import( + "hardhat/utils/source-names" + ); + + for (const [contractSourceIdentifier, output] of Object.entries( + contracts + )) { + const sourceName = semver.gte( + vyperVersion, + OUTPUT_BREAKABLE_VYPER_VERSION + ) + ? await localPathToSourceName( + config.paths.root, + contractSourceIdentifier + ) + : contractSourceIdentifier; const artifact = getArtifactFromVyperOutput(sourceName, output); await artifacts.saveArtifactAndDebugFile(artifact); - const file = files.find((f) => f.sourceName === sourceName); assertPluginInvariant( file !== undefined, @@ -320,7 +375,10 @@ ${list}` lastModificationDate: file.lastModificationDate.valueOf(), contentHash: file.contentHash, sourceName: file.sourceName, - vyperConfig: { version }, + vyperConfig: { + version, + settings, + }, versionPragma: file.content.versionPragma, artifacts: [artifact.contractName], }); @@ -348,10 +406,10 @@ ${list}` * disk, we remove it from the cache to force it to be recompiled. */ async function invalidateCacheMissingArtifacts( - vyperFilesCache: VyperFilesCache, + vyperFilesCache: VyperFilesCacheT, artifacts: Artifacts, resolvedFiles: ResolvedFile[] -): Promise { +): Promise { for (const file of resolvedFiles) { const cacheEntry = vyperFilesCache.getEntry(file.absolutePath); diff --git a/packages/hardhat-vyper/src/parser.ts b/packages/hardhat-vyper/src/parser.ts index 31eaf93f64..f3af0bfb45 100644 --- a/packages/hardhat-vyper/src/parser.ts +++ b/packages/hardhat-vyper/src/parser.ts @@ -1,4 +1,5 @@ import { VyperFilesCache } from "./cache"; +import { VyperPluginError } from "./util"; interface ParsedData { versionPragma: string; @@ -16,6 +17,8 @@ export class Parser { absolutePath: string, contentHash: string ): ParsedData { + this._validateTestModeNotUsed(fileContent, absolutePath); + const cacheResult = this._getFromCache(absolutePath, contentHash); if (cacheResult !== null) { @@ -31,6 +34,16 @@ export class Parser { return result; } + private _validateTestModeNotUsed(fileContent: string, absolutePath: string) { + if (fileContent.includes('#@ if mode == "test":')) { + throw new VyperPluginError( + `We found a test directive in the file at path ${absolutePath}.` + + ` Test directives are a Brownie feature not supported by Hardhat.` + + ` Learn more at https://hardhat.org/hardhat-runner/plugins/nomiclabs-hardhat-vyper#test-directives` + ); + } + } + private _getFromCache( absolutePath: string, contentHash: string diff --git a/packages/hardhat-vyper/src/types.ts b/packages/hardhat-vyper/src/types.ts index 8a17cd4c16..5eaad0b65d 100644 --- a/packages/hardhat-vyper/src/types.ts +++ b/packages/hardhat-vyper/src/types.ts @@ -1,7 +1,13 @@ export type VyperUserConfig = string | VyperConfig | MultiVyperConfig; +export interface VyperSettings { + evmVersion?: string; + optimize?: string | boolean; +} + export interface VyperConfig { version: string; + settings?: VyperSettings; } export interface MultiVyperConfig { diff --git a/packages/hardhat-vyper/test/fixture-projects/.gitignore b/packages/hardhat-vyper/test/fixture-projects/.gitignore index 1a65e437ab..64036ac854 100644 --- a/packages/hardhat-vyper/test/fixture-projects/.gitignore +++ b/packages/hardhat-vyper/test/fixture-projects/.gitignore @@ -1,2 +1,2 @@ -/*/cache -/*/artifacts +/**/cache +/**/artifacts diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-single-file-test-directive/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-single-file-test-directive/contracts/A.vy new file mode 100644 index 0000000000..267ea38508 --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-single-file-test-directive/contracts/A.vy @@ -0,0 +1,7 @@ +# @version 0.3.0 + +#@ if mode == "test": +@external +def test() -> int128: + return 42 +#@ endif \ No newline at end of file diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-single-file-test-directive/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-single-file-test-directive/hardhat.config.js new file mode 100644 index 0000000000..6ab888d875 --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-single-file-test-directive/hardhat.config.js @@ -0,0 +1,5 @@ +require("../../../src/index"); + +module.exports = { + vyper: "0.3.0", +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-invalid-type/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-invalid-type/contracts/A.vy new file mode 100644 index 0000000000..748ebc927a --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-invalid-type/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.9 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-invalid-type/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-invalid-type/hardhat.config.js new file mode 100644 index 0000000000..e031582d90 --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-invalid-type/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.9", + settings: { + evmVersion: "paris", + optimize: 12, + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions/contracts/A.vy new file mode 100644 index 0000000000..2f6a0a54db --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.10 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions/hardhat.config.js new file mode 100644 index 0000000000..e59e652644 --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.10", + settings: { + evmVersion: "paris", + optimize: false, + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions-after-0.3.0/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions-after-0.3.0/contracts/A.vy new file mode 100644 index 0000000000..748ebc927a --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions-after-0.3.0/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.9 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions-after-0.3.0/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions-after-0.3.0/hardhat.config.js new file mode 100644 index 0000000000..a1f69ac41c --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions-after-0.3.0/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.9", + settings: { + evmVersion: "paris", + optimize: false, + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions/contracts/A.vy new file mode 100644 index 0000000000..14de3134ac --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.0 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions/hardhat.config.js new file mode 100644 index 0000000000..4527da42e7 --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.0", + settings: { + evmVersion: "istanbul", + optimize: false, + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-true/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-true/contracts/A.vy new file mode 100644 index 0000000000..748ebc927a --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-true/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.9 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-true/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-true/hardhat.config.js new file mode 100644 index 0000000000..965f42bb5a --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-set-to-true/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.9", + settings: { + evmVersion: "paris", + optimize: true, + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-string-not-available-old-versions/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-string-not-available-old-versions/contracts/A.vy new file mode 100644 index 0000000000..748ebc927a --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-string-not-available-old-versions/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.9 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-string-not-available-old-versions/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-string-not-available-old-versions/hardhat.config.js new file mode 100644 index 0000000000..a9eb741f4d --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-string-not-available-old-versions/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.9", + settings: { + evmVersion: "paris", + optimize: "true", + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-new-versions/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-new-versions/contracts/A.vy new file mode 100644 index 0000000000..2f6a0a54db --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-new-versions/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.10 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-new-versions/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-new-versions/hardhat.config.js new file mode 100644 index 0000000000..de9ea2595a --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-new-versions/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.10", + settings: { + evmVersion: "paris", + optimize: true, + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-old-versions/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-old-versions/contracts/A.vy new file mode 100644 index 0000000000..14de3134ac --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-old-versions/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.0 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-old-versions/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-old-versions/hardhat.config.js new file mode 100644 index 0000000000..1fa88e8c40 --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-settings-option-variants/optimize-true-not-available-old-versions/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.0", + settings: { + evmVersion: "paris", + optimize: true, + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-output-breakable-version/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-output-breakable-version/contracts/A.vy new file mode 100644 index 0000000000..365dbc66db --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-output-breakable-version/contracts/A.vy @@ -0,0 +1,8 @@ +# pragma version ~=0.4.0 + +IMMUTABLE_1: public(immutable(String[4])) + +@deploy +@payable +def __init__(): + IMMUTABLE_1 = "A" \ No newline at end of file diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-output-breakable-version/contracts/B.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-output-breakable-version/contracts/B.vy new file mode 100644 index 0000000000..835f229d0a --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-output-breakable-version/contracts/B.vy @@ -0,0 +1,8 @@ +# pragma version ~=0.4.0 + +IMMUTABLE_1: public(immutable(String[4])) + +@deploy +@payable +def __init__(): + IMMUTABLE_1 = "B" diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-output-breakable-version/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-output-breakable-version/hardhat.config.js new file mode 100644 index 0000000000..77ced97a60 --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-output-breakable-version/hardhat.config.js @@ -0,0 +1,15 @@ +require("../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.4.0", + settings: { + evmVersion: "paris", + optimize: "gas", + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/contracts/A.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/contracts/A.vy new file mode 100644 index 0000000000..25f7f170c6 --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/contracts/A.vy @@ -0,0 +1,5 @@ +# @version 0.3.8 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/contracts/B.vy b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/contracts/B.vy new file mode 100644 index 0000000000..2f6a0a54db --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/contracts/B.vy @@ -0,0 +1,5 @@ +# @version 0.3.10 + +@external +def test() -> int128: + return 42 diff --git a/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/hardhat.config.js b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/hardhat.config.js new file mode 100644 index 0000000000..620d5eb0a2 --- /dev/null +++ b/packages/hardhat-vyper/test/fixture-projects/compilation-with-vyper-settings/hardhat.config.js @@ -0,0 +1,21 @@ +require("../../../src/index"); + +module.exports = { + vyper: { + compilers: [ + { + version: "0.3.10", + settings: { + evmVersion: "paris", + optimize: "gas", + }, + }, + { + version: "0.3.8", + settings: { + evmVersion: "shanghai", + }, + }, + ], + }, +}; diff --git a/packages/hardhat-vyper/test/tests.ts b/packages/hardhat-vyper/test/tests.ts index 0657361633..13116203a5 100644 --- a/packages/hardhat-vyper/test/tests.ts +++ b/packages/hardhat-vyper/test/tests.ts @@ -1,9 +1,11 @@ -import { assert } from "chai"; +import { assert, expect, use } from "chai"; +import chaiAsPromised from "chai-as-promised"; import * as fsExtra from "fs-extra"; import path from "path"; import { TASK_COMPILE } from "hardhat/builtin-tasks/task-names"; +import fs from "node:fs"; import { VYPER_FILES_CACHE_FILENAME } from "../src/constants"; import { useEnvironment, @@ -12,6 +14,8 @@ import { expectVyperErrorAsync, } from "./helpers"; +use(chaiAsPromised); + describe("Vyper plugin", function () { beforeEach(function () { fsExtra.removeSync("artifacts"); @@ -41,6 +45,179 @@ describe("Vyper plugin", function () { }); }); + describe("vyper settings", function () { + describe("compilation with different settings", function () { + useFixtureProject("compilation-with-vyper-settings"); + useEnvironment(); + + it("should compile and emit artifacts", async function () { + await this.env.run(TASK_COMPILE); + + assertFileExists(path.join("artifacts", "contracts", "A.vy", "A.json")); + assertFileExists(path.join("artifacts", "contracts", "B.vy", "B.json")); + }); + }); + + describe("optimize, as boolean type, can always be set to false in versions >= 0.3.10 (flag --optimize none)", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-set-to-false-always-available-new-versions" + ); + useEnvironment(); + + it("should compile successfully", async function () { + await this.env.run(TASK_COMPILE); + assertFileExists(path.join("artifacts", "contracts", "A.vy", "A.json")); + }); + }); + + describe("optimize, as boolean type, can always be set to false in versions 0.3.0 < v < 0.3.10 (flag --no-optimize)", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-set-to-false-always-available-old-versions-after-0.3.0" + ); + useEnvironment(); + + it("should compile successfully", async function () { + await this.env.run(TASK_COMPILE); + assertFileExists(path.join("artifacts", "contracts", "A.vy", "A.json")); + }); + }); + + describe("optimize, as boolean type, cannot be set to false in versions <= 0.3.0", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-set-to-false-not-available-old-versions" + ); + useEnvironment(); + + it("should fail the compilation", async function () { + await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( + Error, + "The 'optimize' setting with value 'false' is not supported for versions of the Vyper compiler older than or equal to 0.3.0. You are currently using version 0.3.0." + ); + }); + }); + + describe("optimize setting set to true in supported versions", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-set-to-true" + ); + useEnvironment(); + + it("should compile successfully", async function () { + await this.env.run(TASK_COMPILE); + assertFileExists(path.join("artifacts", "contracts", "A.vy", "A.json")); + }); + }); + + describe("optimize set to true is not available for versions >= 0.3.10", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-true-not-available-new-versions" + ); + useEnvironment(); + + it("should fail the compilation", async function () { + await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( + Error, + "The 'optimize' setting with value 'true' is not supported for versions of the Vyper compiler older than or equal to 0.3.0 or newer than or equal to 0.3.10. You are currently using version 0.3.10." + ); + }); + }); + + describe("optimize set to true is not available for versions <= 0.3.0", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-true-not-available-old-versions" + ); + useEnvironment(); + + it("should fail the compilation", async function () { + await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( + Error, + "The 'optimize' setting with value 'true' is not supported for versions of the Vyper compiler older than or equal to 0.3.0 or newer than or equal to 0.3.10. You are currently using version 0.3.0." + ); + }); + }); + + describe("optimize setting cannot be a string for version < 0.3.10", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-string-not-available-old-versions" + ); + useEnvironment(); + + it("should fail the compilation", async function () { + await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( + Error, + "The 'optimize' setting, when specified as a string value, is available only starting from the Vyper compiler version 0.3.10. You are currently using version 0.3.9." + ); + }); + }); + + describe("optimize setting must be a string or boolean type", function () { + useFixtureProject( + "compilation-with-settings-option-variants/optimize-invalid-type" + ); + useEnvironment(); + + it("should fail the compilation", async function () { + await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( + Error, + "The 'optimize' setting has an invalid type value: number. Type should be either string or boolean." + ); + }); + }); + }); + + describe("caching mechanism", function () { + describe("caching mechanism without vyper settings", function () { + useFixtureProject("compilation-single-file"); + useEnvironment(); + + it("should not re-compile the contract because of the cache", async function () { + await this.env.run(TASK_COMPILE); + + const stats1 = fs.statSync( + path.join("artifacts", "contracts", "A.vy", "A.json") + ); + + // it should not compile again so the contract should not be modified + await this.env.run(TASK_COMPILE); + + const stats2 = fs.statSync( + path.join("artifacts", "contracts", "A.vy", "A.json") + ); + + assert.equal(stats1.mtimeMs, stats2.mtimeMs); + }); + }); + + describe("caching mechanism with vyper settings", function () { + useFixtureProject("compilation-with-vyper-settings"); + useEnvironment(); + + it("should not re-compile the contract because of the cache", async function () { + await this.env.run(TASK_COMPILE); + + const stats1A = fs.statSync( + path.join("artifacts", "contracts", "A.vy", "A.json") + ); + const stats1B = fs.statSync( + path.join("artifacts", "contracts", "B.vy", "B.json") + ); + + // it should not compile again so the contracts should not be modified + await this.env.run(TASK_COMPILE); + + const stats2A = fs.statSync( + path.join("artifacts", "contracts", "A.vy", "A.json") + ); + const stats2B = fs.statSync( + path.join("artifacts", "contracts", "B.vy", "B.json") + ); + + assert.equal(stats1A.mtimeMs, stats2A.mtimeMs); + assert.equal(stats1B.mtimeMs, stats2B.mtimeMs); + }); + }); + }); + describe("old versions of vyper", function () { useFixtureProject("old-vyper-versions"); @@ -65,7 +242,7 @@ describe("Vyper plugin", function () { }); }); - describe("Mixed language", async function () { + describe("Mixed language", function () { useFixtureProject("mixed-language"); useEnvironment(); @@ -107,4 +284,37 @@ describe("Vyper plugin", function () { ); }); }); + + describe("project should not compile", function () { + useFixtureProject("compilation-single-file-test-directive"); + useEnvironment(); + + it("should throw an error because a test directive is present in the source file", async function () { + const filePath = path.join( + __dirname, + "fixture-projects", + "compilation-single-file-test-directive", + "contracts", + "A.vy" + ); + + await expect(this.env.run(TASK_COMPILE)).to.be.rejectedWith( + `We found a test directive in the file at path ${filePath}.` + + ` Test directives are a Brownie feature not supported by Hardhat.` + + ` Learn more at https://hardhat.org/hardhat-runner/plugins/nomiclabs-hardhat-vyper#test-directives` + ); + }); + }); + + describe("compile project with different ouput identifiers returned from the vyper compiler", function () { + useFixtureProject("compilation-with-vyper-output-breakable-version"); + useEnvironment(); + + it("Should successfully compile the contracts for versions >= 0.4.0", async function () { + await this.env.run(TASK_COMPILE); + + assert.equal(this.env.artifacts.readArtifactSync("A").contractName, "A"); + assert.equal(this.env.artifacts.readArtifactSync("B").contractName, "B"); + }); + }); }); diff --git a/packages/hardhat-web3-legacy/.eslintrc.js b/packages/hardhat-web3-legacy/.eslintrc.js index 889740f226..c6de07705a 100644 --- a/packages/hardhat-web3-legacy/.eslintrc.js +++ b/packages/hardhat-web3-legacy/.eslintrc.js @@ -1,7 +1,24 @@ +const { + slowImportsCommonIgnoredModules, +} = require("../../config/eslint/constants"); + module.exports = { extends: [`${__dirname}/../../config/eslint/eslintrc.js`], parserOptions: { project: `${__dirname}/tsconfig.json`, sourceType: "module", }, + overrides: [ + { + files: ["src/index.ts"], + rules: { + "@nomicfoundation/slow-imports/no-top-level-external-import": [ + "error", + { + ignoreModules: [...slowImportsCommonIgnoredModules], + }, + ], + }, + }, + ], }; diff --git a/packages/hardhat-web3-legacy/.gitignore b/packages/hardhat-web3-legacy/.gitignore index c00d7e7296..4aca21f18d 100644 --- a/packages/hardhat-web3-legacy/.gitignore +++ b/packages/hardhat-web3-legacy/.gitignore @@ -15,10 +15,6 @@ # Logs logs *.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json @@ -57,21 +53,15 @@ jspm_packages/ # TypeScript v1 declaration files typings/ -# Optional npm cache directory -.npm - # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history -# Output of 'npm pack' +# Output of 'pnpm pack' *.tgz -# Yarn Integrity file -.yarn-integrity - # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/packages/hardhat-web3-legacy/LICENSE b/packages/hardhat-web3-legacy/LICENSE index 3b8858c555..3b7e8c7eab 100644 --- a/packages/hardhat-web3-legacy/LICENSE +++ b/packages/hardhat-web3-legacy/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Nomic Labs LLC +Copyright (c) 2023 Nomic Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/packages/hardhat-web3-legacy/package.json b/packages/hardhat-web3-legacy/package.json index 4ba78198b6..f2fe38269a 100644 --- a/packages/hardhat-web3-legacy/package.json +++ b/packages/hardhat-web3-legacy/package.json @@ -17,13 +17,14 @@ "web3.js" ], "scripts": { - "lint": "yarn prettier --check && yarn eslint", - "lint:fix": "yarn prettier --write && yarn eslint --fix", + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", "prettier": "prettier \"**/*.{js,md,json}\"", + "pretest": "cd ../.. && pnpm build", "test": "mocha --recursive \"test/**/*.ts\" --exit", "build": "tsc --build .", - "prepublishOnly": "yarn build", + "prepublishOnly": "pnpm build", "clean": "rimraf dist" }, "files": [ @@ -33,27 +34,29 @@ "README.md" ], "devDependencies": { + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", "@types/chai": "^4.2.0", "@types/mocha": ">=9.1.0", - "@types/node": "^14.0.0", - "@typescript-eslint/eslint-plugin": "5.53.0", - "@typescript-eslint/parser": "5.53.0", + "@types/node": "^18.0.0", + "@typescript-eslint/eslint-plugin": "5.61.0", + "@typescript-eslint/parser": "5.61.0", "chai": "^4.2.0", - "eslint": "^7.29.0", + "eslint": "^8.44.0", "eslint-config-prettier": "8.3.0", - "eslint-plugin-import": "2.24.1", - "eslint-plugin-no-only-tests": "3.0.0", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-mocha": "10.4.1", "eslint-plugin-prettier": "3.4.0", - "hardhat": "^2.0.0", + "hardhat": "workspace:^2.0.0", "mocha": "^10.0.0", "prettier": "2.4.1", "rimraf": "^3.0.2", "ts-node": "^10.8.0", - "typescript": "~4.7.4", + "typescript": "~5.0.0", "web3": "^0.20.0" }, "peerDependencies": { - "hardhat": "^2.0.0", + "hardhat": "workspace:^2.0.0", "web3": "^0.20.0" } } diff --git a/packages/hardhat-web3-legacy/src/index.ts b/packages/hardhat-web3-legacy/src/index.ts index fdb0d20f83..3eb444d700 100644 --- a/packages/hardhat-web3-legacy/src/index.ts +++ b/packages/hardhat-web3-legacy/src/index.ts @@ -1,7 +1,8 @@ +import type { promisifyWeb3 as PromisifyWeb3T } from "./pweb3"; + import { extendEnvironment } from "hardhat/config"; import { lazyFunction, lazyObject } from "hardhat/plugins"; -import { promisifyWeb3 } from "./pweb3"; import "./type-extensions"; import { Web3HTTPProviderAdapter } from "./web3-provider-adapter"; @@ -11,5 +12,8 @@ extendEnvironment((env) => { const Web3 = require("web3"); return new Web3(new Web3HTTPProviderAdapter(env.network.provider)); }); + const { promisifyWeb3 } = require("./pweb3") as { + promisifyWeb3: typeof PromisifyWeb3T; + }; env.pweb3 = lazyObject(() => promisifyWeb3(env.web3)); }); diff --git a/packages/hardhat-web3-legacy/src/web3.d.ts b/packages/hardhat-web3-legacy/src/web3.d.ts new file mode 100644 index 0000000000..993160c5a1 --- /dev/null +++ b/packages/hardhat-web3-legacy/src/web3.d.ts @@ -0,0 +1 @@ +declare module "web3"; diff --git a/packages/hardhat-web3-legacy/test/pweb3.ts b/packages/hardhat-web3-legacy/test/pweb3.ts index 4a06bf8a0a..f8facfff2a 100644 --- a/packages/hardhat-web3-legacy/test/pweb3.ts +++ b/packages/hardhat-web3-legacy/test/pweb3.ts @@ -64,17 +64,21 @@ describe("pweb3", () => { assert.equal(await test.constantFunction(), 1); }); - it("Should give the same result as calling web3 but promisified", (done) => { - web3.eth.getAccounts((error: Error | null, expectedAccounts?: string[]) => { - const promise = pweb3.eth.getAccounts(); - assert.instanceOf(promise, Promise); - promise - .then( - (actualAccounts: string[]) => - assert.deepEqual(actualAccounts, expectedAccounts), - (_pweb3Error: Error) => assert.instanceOf(error, Error) - ) - .then(done); + it("Should give the same result as calling web3 but promisified", async () => { + const actualAccounts = await pweb3.eth.getAccounts(); + + return new Promise((resolve, reject) => { + web3.eth.getAccounts( + (error: Error | null, expectedAccounts?: string[]) => { + if (error !== null) { + reject(error); + return; + } + + assert.deepEqual(actualAccounts, expectedAccounts); + resolve(); + } + ); }); }); }); diff --git a/packages/hardhat-web3-legacy/test/web3-provider-adapter.ts b/packages/hardhat-web3-legacy/test/web3-provider-adapter.ts index d38aded886..b10f3e7e1d 100644 --- a/packages/hardhat-web3-legacy/test/web3-provider-adapter.ts +++ b/packages/hardhat-web3-legacy/test/web3-provider-adapter.ts @@ -53,7 +53,7 @@ describe("Web3 provider adapter", function () { assert.isTrue(adaptedProvider.isConnected()); }); - it("Should return the same as the real provider for sigle requests", function (done) { + it("Should return the same as the real provider for single requests", function (done) { const request = createJsonRpcRequest("eth_accounts"); realWeb3Provider.sendAsync( request, diff --git a/packages/hardhat-web3-v4/.eslintrc.js b/packages/hardhat-web3-v4/.eslintrc.js new file mode 100644 index 0000000000..889740f226 --- /dev/null +++ b/packages/hardhat-web3-v4/.eslintrc.js @@ -0,0 +1,7 @@ +module.exports = { + extends: [`${__dirname}/../../config/eslint/eslintrc.js`], + parserOptions: { + project: `${__dirname}/tsconfig.json`, + sourceType: "module", + }, +}; diff --git a/packages/hardhat-web3-v4/.gitignore b/packages/hardhat-web3-v4/.gitignore new file mode 100644 index 0000000000..bc1256a4fe --- /dev/null +++ b/packages/hardhat-web3-v4/.gitignore @@ -0,0 +1,97 @@ +# Node modules +/node_modules + +# Compilation output +/build-test/ +/dist + +# Code coverage artifacts +/coverage +/.nyc_output + +# Below is Github's node gitignore template, +# ignoring the node_modules part, as it'd ignore every node_modules, and we have some for testing + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* + +# Diagnostic reports (https://nodejs.org/api/report.html) +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +#node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless/ + +# FuseBox cache +.fusebox/ + +# DynamoDB Local files +.dynamodb/ + +artifacts +cache \ No newline at end of file diff --git a/packages/hardhat-web3-v4/.mocharc.json b/packages/hardhat-web3-v4/.mocharc.json new file mode 100644 index 0000000000..901e40db33 --- /dev/null +++ b/packages/hardhat-web3-v4/.mocharc.json @@ -0,0 +1,6 @@ +{ + "require": "ts-node/register/files", + "file": "../common/run-with-hardhat.js", + "ignore": ["test/fixture-projects/**/*"], + "timeout": 10000 +} diff --git a/packages/hardhat-web3-v4/.prettierignore b/packages/hardhat-web3-v4/.prettierignore new file mode 100644 index 0000000000..37cbd4e3f5 --- /dev/null +++ b/packages/hardhat-web3-v4/.prettierignore @@ -0,0 +1,5 @@ +/node_modules +/dist +/test/fixture-projects/**/artifacts +/test/fixture-projects/**/cache +CHANGELOG.md diff --git a/packages/hardhat-web3-v4/LICENSE b/packages/hardhat-web3-v4/LICENSE new file mode 100644 index 0000000000..3b7e8c7eab --- /dev/null +++ b/packages/hardhat-web3-v4/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Nomic Foundation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/hardhat-web3-v4/README.md b/packages/hardhat-web3-v4/README.md new file mode 100644 index 0000000000..3b389ebed7 --- /dev/null +++ b/packages/hardhat-web3-v4/README.md @@ -0,0 +1,59 @@ +[![npm](https://img.shields.io/npm/v/@nomicfoundation/hardhat-web3-v4.svg)](https://www.npmjs.com/package/@nomicfoundation/hardhat-web3-v4) [![hardhat](https://hardhat.org/buidler-plugin-badge.svg?1)](https://hardhat.org) + +# hardhat-web3-v4 + +_This plugin is a collaboration between the Nomic Foundation and [ChainSafe](https://chainsafe.io/)_ + +Integrate [Web3.js](https://github.com/ethereum/web3.js) `4.x` into [Hardhat](https://hardhat.org). + +## What + +This plugin brings to Hardhat the Web3 module and an initialized instance of Web3. + +# Installation + +```bash +npm install --save-dev @nomicfoundation/hardhat-web3-v4 'web3@4' +``` + +And add the following statement to your `hardhat.config.js`: + +```js +require("@nomicfoundation/hardhat-web3-v4"); +``` + +Or, if you are using TypeScript, add this to your `hardhat.config.ts`: + +```js +import "@nomicfoundation/hardhat-web3-v4"; +``` + +By default, contract invocations will not be typesafe. Consider installing [@chainsafe/hardhat-ts-artifact-plugin](https://www.npmjs.com/package/@chainsafe/hardhat-ts-artifact-plugin) to obtain available contract methods and events. Read more about inferring types [here](https://docs.web3js.org/guides/smart_contracts/infer_contract_types/). + +## Tasks + +This plugin creates no additional tasks. + +## Environment extensions + +This plugin adds the following elements to the `HardhatRuntimeEnvironment`: + +- `Web3`: The Web3.js module. +- `web3`: An instantiated Web3.js object connected to the selected network. + +## Usage + +Install it and access Web3.js through the Hardhat Runtime Environment anywhere you need it (tasks, scripts, tests, etc). For example, in your `hardhat.config.js`: + +```js +require("@nomicfoundation/hardhat-web3-v4"); + +// task action function receives the Hardhat Runtime Environment as second argument +task("accounts", "Prints accounts", async (_, { web3 }) => { + console.log(await web3.eth.getAccounts()); +}); +``` + +And then run `npx hardhat accounts` to try it. + +Read the documentation on the [Hardhat Runtime Environment](https://hardhat.org/hardhat-runner/docs/advanced/hardhat-runtime-environment) to learn how to access the HRE in different ways to use Web3.js from anywhere the HRE is accessible. diff --git a/packages/hardhat-web3-v4/package.json b/packages/hardhat-web3-v4/package.json new file mode 100644 index 0000000000..acde1b606f --- /dev/null +++ b/packages/hardhat-web3-v4/package.json @@ -0,0 +1,63 @@ +{ + "name": "@nomicfoundation/hardhat-web3-v4", + "version": "1.0.0", + "author": "Nomic Foundation", + "license": "MIT", + "homepage": "https://github.com/nomicfoundation/hardhat/tree/main/packages/hardhat-web3-v4", + "repository": "github:nomicfoundation/hardhat", + "main": "dist/src/index.js", + "types": "dist/src/index.d.ts", + "description": "Hardhat plugin for using Web3 4.x", + "keywords": [ + "ethereum", + "smart-contracts", + "hardhat", + "hardhat-plugin", + "web3", + "web3.js" + ], + "scripts": { + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", + "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", + "prettier": "prettier \"**/*.{js,md,json}\"", + "test": "mocha --recursive \"test/**/*.ts\" --exit && node web3-lazy-object-tests/when-accessing-web3-class.js && node web3-lazy-object-tests/when-accessing-web3-object.js && node web3-lazy-object-tests/when-requiring-web3-module.js", + "build": "tsc --build .", + "prepublishOnly": "pnpm build", + "clean": "rimraf dist" + }, + "files": [ + "dist/src/", + "src/", + "LICENSE", + "README.md" + ], + "devDependencies": { + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", + "@types/chai": "^4.2.0", + "@types/chai-as-promised": "^7.1.3", + "@types/mocha": ">=9.1.0", + "@types/node": "^18.0.0", + "@typescript-eslint/eslint-plugin": "5.61.0", + "@typescript-eslint/parser": "5.61.0", + "chai": "^4.2.0", + "chai-as-promised": "^7.1.1", + "eslint": "^8.44.0", + "eslint-config-prettier": "8.3.0", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-mocha": "10.4.1", + "eslint-plugin-prettier": "3.4.0", + "hardhat": "workspace:^2.0.0", + "mocha": "^10.0.0", + "prettier": "2.4.1", + "rimraf": "^3.0.2", + "ts-node": "^10.8.0", + "typescript": "~5.0.0", + "web3": "^4.0.1" + }, + "peerDependencies": { + "hardhat": "workspace:^2.0.0", + "web3": "^4.0.1" + } +} diff --git a/packages/hardhat-web3-v4/src/index.ts b/packages/hardhat-web3-v4/src/index.ts new file mode 100644 index 0000000000..4b27f5bb17 --- /dev/null +++ b/packages/hardhat-web3-v4/src/index.ts @@ -0,0 +1,12 @@ +import { extendEnvironment } from "hardhat/config"; +import { lazyFunction, lazyObject } from "hardhat/plugins"; + +import "./type-extensions"; + +extendEnvironment((env) => { + env.Web3 = lazyFunction(() => require("web3").Web3); + env.web3 = lazyObject(() => { + const Web3 = require("web3").Web3; + return new Web3(env.network.provider); + }); +}); diff --git a/packages/hardhat-web3-v4/src/type-extensions.ts b/packages/hardhat-web3-v4/src/type-extensions.ts new file mode 100644 index 0000000000..4353372f1a --- /dev/null +++ b/packages/hardhat-web3-v4/src/type-extensions.ts @@ -0,0 +1,10 @@ +import type * as Web3 from "web3"; + +import "hardhat/types/runtime"; + +declare module "hardhat/types/runtime" { + interface HardhatRuntimeEnvironment { + Web3: typeof Web3; + web3: Web3.Web3; + } +} diff --git a/packages/hardhat-web3-v4/test/.eslintrc.js b/packages/hardhat-web3-v4/test/.eslintrc.js new file mode 100644 index 0000000000..12ee5882f1 --- /dev/null +++ b/packages/hardhat-web3-v4/test/.eslintrc.js @@ -0,0 +1,11 @@ +module.exports = { + extends: [`${__dirname}/../.eslintrc.js`], + rules: { + "import/no-extraneous-dependencies": [ + "error", + { + devDependencies: true, + }, + ], + }, +}; diff --git a/packages/hardhat-web3-v4/test/fixture-projects/hardhat-project/contracts/Greeter.sol b/packages/hardhat-web3-v4/test/fixture-projects/hardhat-project/contracts/Greeter.sol new file mode 100644 index 0000000000..d7c9b9490c --- /dev/null +++ b/packages/hardhat-web3-v4/test/fixture-projects/hardhat-project/contracts/Greeter.sol @@ -0,0 +1,22 @@ +pragma solidity ^0.5.1; + +contract Greeter { + + string greeting; + + event GreetingUpdated(string greeting); + + constructor() public { + greeting = "Hi"; + } + + function setGreeting(string memory _greeting) public { + greeting = _greeting; + emit GreetingUpdated(_greeting); + } + + function greet() public view returns (string memory) { + return greeting; + } + +} diff --git a/packages/hardhat-web3-v4/test/fixture-projects/hardhat-project/hardhat.config.js b/packages/hardhat-web3-v4/test/fixture-projects/hardhat-project/hardhat.config.js new file mode 100644 index 0000000000..d851e726c8 --- /dev/null +++ b/packages/hardhat-web3-v4/test/fixture-projects/hardhat-project/hardhat.config.js @@ -0,0 +1,5 @@ +require("../../../src/index"); + +module.exports = { + solidity: "0.5.15", +}; diff --git a/packages/hardhat-web3-v4/test/helpers.ts b/packages/hardhat-web3-v4/test/helpers.ts new file mode 100644 index 0000000000..c3781481ee --- /dev/null +++ b/packages/hardhat-web3-v4/test/helpers.ts @@ -0,0 +1,27 @@ +import { resetHardhatContext } from "hardhat/plugins-testing"; +import { HardhatRuntimeEnvironment } from "hardhat/types"; +import { TASK_COMPILE } from "hardhat/builtin-tasks/task-names"; +import path from "path"; + +declare module "mocha" { + interface Context { + env: HardhatRuntimeEnvironment; + } +} + +export function useEnvironment( + fixtureProjectName: string, + networkName = "localhost" +) { + beforeEach("Loading hardhat environment", async function () { + process.chdir(path.join(__dirname, "fixture-projects", fixtureProjectName)); + process.env.HARDHAT_NETWORK = networkName; + + this.env = require("hardhat"); + await this.env.run(TASK_COMPILE); + }); + + afterEach("Resetting hardhat", function () { + resetHardhatContext(); + }); +} diff --git a/packages/hardhat-web3-v4/test/index.ts b/packages/hardhat-web3-v4/test/index.ts new file mode 100644 index 0000000000..6488c6ddb2 --- /dev/null +++ b/packages/hardhat-web3-v4/test/index.ts @@ -0,0 +1,47 @@ +import chai from "chai"; +import chaiAsPromised from "chai-as-promised"; + +import { Contract } from "web3"; +import { useEnvironment } from "./helpers"; + +chai.use(chaiAsPromised); + +describe("Web3 plugin", function () { + describe("ganache", function () { + useEnvironment("hardhat-project", "localhost"); + + describe("contracts", function () { + it("should deploy", async function () { + const artifact = this.env.artifacts.readArtifactSync("Greeter"); + const Greeter = new Contract(artifact.abi, this.env.web3); + const response = Greeter.deploy({ + data: artifact.bytecode, + }).send({ + from: (await this.env.web3.eth.getAccounts())[0], + }); + await new Promise((resolve) => + response.on("receipt", () => resolve()) + ); + }); + }); + }); + describe("hardhat", function () { + useEnvironment("hardhat-project", "hardhat"); + + describe("contract", function () { + it("should deploy", async function () { + const artifact = this.env.artifacts.readArtifactSync("Greeter"); + const Greeter = new Contract(artifact.abi, this.env.web3); + const from = (await this.env.web3.eth.getAccounts())[0]; + const response = Greeter.deploy({ + data: artifact.bytecode, + }).send({ + from, + }); + await new Promise((resolve) => + response.on("receipt", () => resolve()) + ); + }); + }); + }); +}); diff --git a/packages/hardhat-web3-v4/tsconfig.json b/packages/hardhat-web3-v4/tsconfig.json new file mode 100644 index 0000000000..f3ad7b97c6 --- /dev/null +++ b/packages/hardhat-web3-v4/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../../config/typescript/tsconfig.json", + "compilerOptions": { + "outDir": "./dist", + "composite": true + }, + "exclude": ["./dist", "./node_modules", "./test/**/hardhat.config.ts"], + "references": [ + { + "path": "../hardhat-core/src" + } + ] +} diff --git a/packages/hardhat-web3-v4/web3-lazy-object-tests/when-accessing-web3-class.js b/packages/hardhat-web3-v4/web3-lazy-object-tests/when-accessing-web3-class.js new file mode 100644 index 0000000000..83656c3640 --- /dev/null +++ b/packages/hardhat-web3-v4/web3-lazy-object-tests/when-accessing-web3-class.js @@ -0,0 +1,6 @@ +const { lazyFunction, lazyObject } = require("hardhat/plugins"); + +global.Web3 = lazyFunction(() => require("web3").Web3); +global.web3 = lazyObject(() => new global.Web3()); + +console.log(Web3.version); diff --git a/packages/hardhat-web3-v4/web3-lazy-object-tests/when-accessing-web3-object.js b/packages/hardhat-web3-v4/web3-lazy-object-tests/when-accessing-web3-object.js new file mode 100644 index 0000000000..82d7f4a09f --- /dev/null +++ b/packages/hardhat-web3-v4/web3-lazy-object-tests/when-accessing-web3-object.js @@ -0,0 +1,6 @@ +const { lazyFunction, lazyObject } = require("hardhat/plugins"); + +global.Web3 = lazyFunction(() => require("web3").Web3); +global.web3 = lazyObject(() => new global.Web3()); + +console.log(global.web3.eth.getAccounts.name); diff --git a/packages/hardhat-web3-v4/web3-lazy-object-tests/when-requiring-web3-module.js b/packages/hardhat-web3-v4/web3-lazy-object-tests/when-requiring-web3-module.js new file mode 100644 index 0000000000..94e7a65943 --- /dev/null +++ b/packages/hardhat-web3-v4/web3-lazy-object-tests/when-requiring-web3-module.js @@ -0,0 +1,6 @@ +const { lazyFunction, lazyObject } = require("hardhat/plugins"); + +global.Web3 = lazyFunction(() => require("web3")); +global.web3 = lazyObject(() => new global.Web3()); + +require("web3"); diff --git a/packages/hardhat-web3/.eslintrc.js b/packages/hardhat-web3/.eslintrc.js index 889740f226..c6de07705a 100644 --- a/packages/hardhat-web3/.eslintrc.js +++ b/packages/hardhat-web3/.eslintrc.js @@ -1,7 +1,24 @@ +const { + slowImportsCommonIgnoredModules, +} = require("../../config/eslint/constants"); + module.exports = { extends: [`${__dirname}/../../config/eslint/eslintrc.js`], parserOptions: { project: `${__dirname}/tsconfig.json`, sourceType: "module", }, + overrides: [ + { + files: ["src/index.ts"], + rules: { + "@nomicfoundation/slow-imports/no-top-level-external-import": [ + "error", + { + ignoreModules: [...slowImportsCommonIgnoredModules], + }, + ], + }, + }, + ], }; diff --git a/packages/hardhat-web3/.gitignore b/packages/hardhat-web3/.gitignore index c00d7e7296..4aca21f18d 100644 --- a/packages/hardhat-web3/.gitignore +++ b/packages/hardhat-web3/.gitignore @@ -15,10 +15,6 @@ # Logs logs *.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -lerna-debug.log* # Diagnostic reports (https://nodejs.org/api/report.html) report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json @@ -57,21 +53,15 @@ jspm_packages/ # TypeScript v1 declaration files typings/ -# Optional npm cache directory -.npm - # Optional eslint cache .eslintcache # Optional REPL history .node_repl_history -# Output of 'npm pack' +# Output of 'pnpm pack' *.tgz -# Yarn Integrity file -.yarn-integrity - # parcel-bundler cache (https://parceljs.org/) .cache diff --git a/packages/hardhat-web3/CHANGELOG.md b/packages/hardhat-web3/CHANGELOG.md new file mode 100644 index 0000000000..739ce46de0 --- /dev/null +++ b/packages/hardhat-web3/CHANGELOG.md @@ -0,0 +1,7 @@ +# @nomiclabs/hardhat-web3 + +## 2.0.1 + +### Patch Changes + +- c016446: Fix a dependency error in hardhat-web3 diff --git a/packages/hardhat-web3/LICENSE b/packages/hardhat-web3/LICENSE index 3b8858c555..3b7e8c7eab 100644 --- a/packages/hardhat-web3/LICENSE +++ b/packages/hardhat-web3/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Nomic Labs LLC +Copyright (c) 2023 Nomic Foundation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/packages/hardhat-web3/README.md b/packages/hardhat-web3/README.md index 364e495058..3112587936 100644 --- a/packages/hardhat-web3/README.md +++ b/packages/hardhat-web3/README.md @@ -11,7 +11,7 @@ This plugin brings to Hardhat the Web3 module and an initialized instance of Web # Installation ```bash -npm install --save-dev @nomiclabs/hardhat-web3 web3 +npm install --save-dev @nomiclabs/hardhat-web3 'web3@^1.0.0-beta.36' ``` And add the following statement to your `hardhat.config.js`: diff --git a/packages/hardhat-web3/package.json b/packages/hardhat-web3/package.json index 99ffc8bf24..1a842565d6 100644 --- a/packages/hardhat-web3/package.json +++ b/packages/hardhat-web3/package.json @@ -1,6 +1,6 @@ { "name": "@nomiclabs/hardhat-web3", - "version": "2.0.0", + "version": "2.0.1", "author": "Nomic Labs LLC", "license": "MIT", "homepage": "https://github.com/nomiclabs/hardhat/tree/main/packages/hardhat-web3", @@ -17,13 +17,14 @@ "web3.js" ], "scripts": { - "lint": "yarn prettier --check && yarn eslint", - "lint:fix": "yarn prettier --write && yarn eslint --fix", + "lint": "pnpm prettier --check && pnpm eslint", + "lint:fix": "pnpm prettier --write && pnpm eslint --fix", "eslint": "eslint 'src/**/*.ts' 'test/**/*.ts'", "prettier": "prettier \"**/*.{js,md,json}\"", + "pretest": "cd ../.. && pnpm build", "test": "mocha --recursive \"test/**/*.ts\" --exit && node web3-lazy-object-tests/when-accessing-web3-class.js && node web3-lazy-object-tests/when-accessing-web3-object.js && node web3-lazy-object-tests/when-requiring-web3-module.js", "build": "tsc --build .", - "prepublishOnly": "yarn build", + "prepublishOnly": "pnpm build", "clean": "rimraf dist" }, "files": [ @@ -33,30 +34,31 @@ "README.md" ], "devDependencies": { + "@nomicfoundation/eslint-plugin-hardhat-internal-rules": "workspace:^", + "@nomicfoundation/eslint-plugin-slow-imports": "workspace:^", "@types/chai": "^4.2.0", "@types/mocha": ">=9.1.0", - "@types/node": "^14.0.0", - "@typescript-eslint/eslint-plugin": "5.53.0", - "@typescript-eslint/parser": "5.53.0", + "@types/node": "^18.0.0", + "@typescript-eslint/eslint-plugin": "5.61.0", + "@typescript-eslint/parser": "5.61.0", "chai": "^4.2.0", - "eslint": "^7.29.0", + "eslint": "^8.44.0", "eslint-config-prettier": "8.3.0", - "eslint-plugin-import": "2.24.1", - "eslint-plugin-no-only-tests": "3.0.0", + "eslint-plugin-import": "2.27.5", + "eslint-plugin-mocha": "10.4.1", "eslint-plugin-prettier": "3.4.0", - "hardhat": "^2.0.0", + "hardhat": "workspace:^2.0.0", "mocha": "^10.0.0", "prettier": "2.4.1", "rimraf": "^3.0.2", + "sha3": "^2.1.4", "ts-node": "^10.8.0", - "typescript": "~4.7.4", + "typescript": "~5.0.0", "web3": "^1.0.0-beta.36" }, "peerDependencies": { - "hardhat": "^2.0.0", + "hardhat": "workspace:^2.0.0", "web3": "^1.0.0-beta.36" }, - "dependencies": { - "@types/bignumber.js": "^5.0.0" - } + "dependencies": {} } diff --git a/packages/hardhat-web3/test/web3-provider-adapter.ts b/packages/hardhat-web3/test/web3-provider-adapter.ts index 044142d49b..498967e7f9 100644 --- a/packages/hardhat-web3/test/web3-provider-adapter.ts +++ b/packages/hardhat-web3/test/web3-provider-adapter.ts @@ -39,7 +39,7 @@ describe("Web3 provider adapter", function () { assert.isTrue(adaptedProvider.isConnected()); }); - it("Should return the same as the real provider for sigle requests", function (done) { + it("Should return the same as the real provider for single requests", function (done) { const request = createJsonRpcRequest("eth_accounts"); realWeb3Provider.send( request, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000000..0d519665e1 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,16799 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + devDependencies: + '@changesets/cli': + specifier: ^2.16.0 + version: 2.27.9 + '@open-rpc/typings': + specifier: ^1.12.1 + version: 1.12.4 + hardhat: + specifier: workspace:* + version: link:packages/hardhat-core + prettier: + specifier: 2.4.1 + version: 2.4.1 + shelljs: + specifier: ^0.8.5 + version: 0.8.5 + typescript: + specifier: ~5.0.0 + version: 5.0.4 + + packages/common: + devDependencies: + detect-port: + specifier: ^1.3.0 + version: 1.6.1 + ganache-cli: + specifier: ^6.12.2 + version: 6.12.2 + prettier: + specifier: 2.4.1 + version: 2.4.1 + + packages/eslint-plugin-hardhat-internal-rules: + dependencies: + '@typescript-eslint/utils': + specifier: ^5.61.0 + version: 5.62.0(eslint@8.57.1)(typescript@5.3.3) + requireindex: + specifier: ^1.2.0 + version: 1.2.0 + devDependencies: + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-doc-generator: + specifier: ^1.0.0 + version: 1.7.1(eslint@8.57.1)(typescript@5.3.3) + eslint-plugin-eslint-plugin: + specifier: ^5.0.0 + version: 5.5.1(eslint@8.57.1) + eslint-plugin-n: + specifier: ^16.6.2 + version: 16.6.2(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) + mocha: + specifier: ^10.0.0 + version: 10.7.3 + + packages/eslint-plugin-slow-imports: + dependencies: + eslint-module-utils: + specifier: ^2.8.0 + version: 2.12.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) + requireindex: + specifier: ^1.2.0 + version: 1.2.0 + devDependencies: + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-doc-generator: + specifier: ^1.0.0 + version: 1.7.1(eslint@8.57.1)(typescript@5.3.3) + eslint-plugin-eslint-plugin: + specifier: ^5.0.0 + version: 5.5.1(eslint@8.57.1) + eslint-plugin-n: + specifier: ^16.6.2 + version: 16.6.2(eslint@8.57.1) + mocha: + specifier: ^10.0.0 + version: 10.7.3 + + packages/hardhat-chai-matchers: + dependencies: + '@types/chai-as-promised': + specifier: ^7.1.3 + version: 7.1.8 + chai-as-promised: + specifier: ^7.1.1 + version: 7.1.2(chai@4.5.0) + deep-eql: + specifier: ^4.0.1 + version: 4.1.4 + ordinal: + specifier: ^1.0.3 + version: 1.0.3 + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@nomicfoundation/hardhat-chai-matchers': + specifier: workspace:* + version: 'link:' + '@nomicfoundation/hardhat-ethers': + specifier: workspace:^3.0.0 + version: link:../hardhat-ethers + '@types/bn.js': + specifier: ^5.1.0 + version: 5.1.6 + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + bignumber.js: + specifier: ^9.0.2 + version: 9.1.2 + bn.js: + specifier: ^5.1.0 + version: 5.2.1 + chai: + specifier: ^4.2.0 + version: 4.5.0 + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + ethers: + specifier: ^6.1.0 + version: 6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + get-port: + specifier: ^5.1.1 + version: 5.1.1 + hardhat: + specifier: workspace:^2.9.4 + version: link:../hardhat-core + mocha: + specifier: ^10.0.0 + version: 10.7.3 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + + packages/hardhat-core: + dependencies: + '@ethereumjs/util': + specifier: ^9.1.0 + version: 9.1.0 + '@ethersproject/abi': + specifier: ^5.1.2 + version: 5.7.0 + '@nomicfoundation/edr': + specifier: ^0.11.0 + version: 0.11.0 + '@nomicfoundation/solidity-analyzer': + specifier: ^0.1.0 + version: 0.1.2 + '@sentry/node': + specifier: ^5.18.1 + version: 5.30.0 + '@types/bn.js': + specifier: ^5.1.0 + version: 5.1.6 + '@types/lru-cache': + specifier: ^5.1.0 + version: 5.1.1 + adm-zip: + specifier: ^0.4.16 + version: 0.4.16 + aggregate-error: + specifier: ^3.0.0 + version: 3.1.0 + ansi-escapes: + specifier: ^4.3.0 + version: 4.3.2 + boxen: + specifier: ^5.1.2 + version: 5.1.2 + chokidar: + specifier: ^4.0.0 + version: 4.0.1 + ci-info: + specifier: ^2.0.0 + version: 2.0.0 + debug: + specifier: ^4.1.1 + version: 4.3.7(supports-color@5.5.0) + enquirer: + specifier: ^2.3.0 + version: 2.4.1 + env-paths: + specifier: ^2.2.0 + version: 2.2.1 + ethereum-cryptography: + specifier: ^1.0.3 + version: 1.2.0 + find-up: + specifier: ^5.0.0 + version: 5.0.0 + fp-ts: + specifier: 1.19.3 + version: 1.19.3 + fs-extra: + specifier: ^7.0.1 + version: 7.0.1 + immutable: + specifier: ^4.0.0-rc.12 + version: 4.3.7 + io-ts: + specifier: 1.10.4 + version: 1.10.4 + json-stream-stringify: + specifier: ^3.1.4 + version: 3.1.6 + keccak: + specifier: ^3.0.2 + version: 3.0.4 + lodash: + specifier: ^4.17.11 + version: 4.17.21 + micro-eth-signer: + specifier: ^0.14.0 + version: 0.14.0 + mnemonist: + specifier: ^0.38.0 + version: 0.38.5 + mocha: + specifier: ^10.0.0 + version: 10.7.3 + p-map: + specifier: ^4.0.0 + version: 4.0.0 + picocolors: + specifier: ^1.1.0 + version: 1.1.0 + raw-body: + specifier: ^2.4.1 + version: 2.5.2 + resolve: + specifier: 1.17.0 + version: 1.17.0 + semver: + specifier: ^6.3.0 + version: 6.3.1 + solc: + specifier: 0.8.26 + version: 0.8.26(debug@4.3.7) + source-map-support: + specifier: ^0.5.13 + version: 0.5.21 + stacktrace-parser: + specifier: ^0.1.10 + version: 0.1.10 + tinyglobby: + specifier: ^0.2.6 + version: 0.2.6 + tsort: + specifier: 0.0.1 + version: 0.0.1 + undici: + specifier: ^5.14.0 + version: 5.28.4 + uuid: + specifier: ^8.3.2 + version: 8.3.2 + ws: + specifier: ^7.4.6 + version: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@types/async-eventemitter': + specifier: ^0.2.1 + version: 0.2.4 + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/chai-as-promised': + specifier: ^7.1.3 + version: 7.1.8 + '@types/ci-info': + specifier: ^2.0.0 + version: 2.0.0 + '@types/debug': + specifier: ^4.1.4 + version: 4.1.12 + '@types/fs-extra': + specifier: ^5.1.0 + version: 5.1.0 + '@types/keccak': + specifier: ^3.0.1 + version: 3.0.5 + '@types/lodash': + specifier: ^4.14.123 + version: 4.17.12 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@types/resolve': + specifier: ^1.17.1 + version: 1.20.6 + '@types/semver': + specifier: ^6.0.2 + version: 6.2.7 + '@types/sinon': + specifier: ^9.0.8 + version: 9.0.11 + '@types/uuid': + specifier: ^8.3.1 + version: 8.3.4 + '@types/ws': + specifier: ^7.2.1 + version: 7.4.7 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + bignumber.js: + specifier: ^9.0.2 + version: 9.1.2 + bn.js: + specifier: ^5.1.0 + version: 5.2.1 + chai: + specifier: ^4.2.0 + version: 4.5.0 + chai-as-promised: + specifier: ^7.1.1 + version: 7.1.2(chai@4.5.0) + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + ethers: + specifier: ^6.1.0 + version: 6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ethers-v5: + specifier: npm:ethers@5 + version: ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + sinon: + specifier: ^9.0.0 + version: 9.2.4 + time-require: + specifier: ^0.1.2 + version: 0.1.2 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + + packages/hardhat-ethers: + dependencies: + debug: + specifier: ^4.1.1 + version: 4.3.7(supports-color@5.5.0) + lodash.isequal: + specifier: ^4.5.0 + version: 4.5.0 + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/chai-as-promised': + specifier: ^7.1.3 + version: 7.1.8 + '@types/debug': + specifier: ^4.1.4 + version: 4.1.12 + '@types/lodash.isequal': + specifier: ^4.5.6 + version: 4.5.8 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@types/sinon': + specifier: ^9.0.8 + version: 9.0.11 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.2.0 + version: 4.5.0 + chai-as-promised: + specifier: ^7.1.1 + version: 7.1.2(chai@4.5.0) + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + ethers: + specifier: ^6.1.0 + version: 6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + hardhat: + specifier: workspace:^2.0.0 + version: link:../hardhat-core + mocha: + specifier: ^10.0.0 + version: 10.7.3 + picocolors: + specifier: ^1.1.0 + version: 1.1.0 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + sinon: + specifier: ^9.0.0 + version: 9.2.4 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + + packages/hardhat-foundry: + dependencies: + picocolors: + specifier: ^1.1.0 + version: 1.1.0 + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.2.0 + version: 4.5.0 + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + hardhat: + specifier: workspace:^2.17.2 + version: link:../hardhat-core + mocha: + specifier: ^10.0.0 + version: 10.7.3 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + + packages/hardhat-ignition: + dependencies: + '@nomicfoundation/ignition-core': + specifier: workspace:^ + version: link:../hardhat-ignition-core + '@nomicfoundation/ignition-ui': + specifier: workspace:^ + version: link:../hardhat-ignition-ui + chalk: + specifier: ^4.0.0 + version: 4.1.2 + debug: + specifier: ^4.3.2 + version: 4.3.7(supports-color@5.5.0) + fs-extra: + specifier: ^10.0.0 + version: 10.1.0 + json5: + specifier: ^2.2.3 + version: 2.2.3 + prompts: + specifier: ^2.4.2 + version: 2.4.2 + devDependencies: + '@istanbuljs/nyc-config-typescript': + specifier: 1.0.2 + version: 1.0.2(nyc@15.1.0) + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/hardhat-network-helpers': + specifier: workspace:^1.0.9 + version: link:../hardhat-network-helpers + '@nomicfoundation/hardhat-verify': + specifier: workspace:^2.0.1 + version: link:../hardhat-verify + '@types/chai': + specifier: ^4.2.22 + version: 4.3.20 + '@types/chai-as-promised': + specifier: ^7.1.4 + version: 7.1.8 + '@types/debug': + specifier: ^4.1.7 + version: 4.1.12 + '@types/fs-extra': + specifier: ^9.0.13 + version: 9.0.13 + '@types/mocha': + specifier: 9.1.1 + version: 9.1.1 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@types/prompts': + specifier: ^2.4.2 + version: 2.4.9 + '@types/sinon': + specifier: ^10.0.13 + version: 10.0.20 + '@typescript-eslint/eslint-plugin': + specifier: ^5.57.1 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/experimental-utils': + specifier: ^5.62.0 + version: 5.62.0(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: ^5.57.1 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.3.4 + version: 4.5.0 + chai-as-promised: + specifier: 7.1.1 + version: 7.1.1(chai@4.5.0) + eslint: + specifier: ^8.38.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-import-resolver-typescript: + specifier: ^3.5.5 + version: 3.7.0(eslint-plugin-import@2.29.0)(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.29.0 + version: 2.29.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) + eslint-plugin-mocha: + specifier: ^9.0.0 + version: 9.0.0(eslint@8.57.1) + eslint-plugin-no-only-tests: + specifier: 3.1.0 + version: 3.1.0 + eslint-plugin-prettier: + specifier: 4.0.0 + version: 4.0.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) + hardhat: + specifier: workspace:^2.18.0 + version: link:../hardhat-core + mocha: + specifier: ^9.1.3 + version: 9.2.2 + nyc: + specifier: 15.1.0 + version: 15.1.0 + prettier: + specifier: 2.8.8 + version: 2.8.8 + rimraf: + specifier: 3.0.2 + version: 3.0.2 + sinon: + specifier: ^14.0.0 + version: 14.0.2 + ts-node: + specifier: 10.9.1 + version: 10.9.1(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ^5.0.2 + version: 5.0.4 + viem: + specifier: ^2.7.6 + version: 2.21.34(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8) + + packages/hardhat-ignition-core: + dependencies: + '@ethersproject/address': + specifier: 5.6.1 + version: 5.6.1 + '@nomicfoundation/solidity-analyzer': + specifier: ^0.1.1 + version: 0.1.2 + cbor: + specifier: ^9.0.0 + version: 9.0.2 + debug: + specifier: ^4.3.2 + version: 4.3.7(supports-color@5.5.0) + ethers: + specifier: ^6.7.0 + version: 6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + fs-extra: + specifier: ^10.0.0 + version: 10.1.0 + immer: + specifier: 10.0.2 + version: 10.0.2 + lodash: + specifier: 4.17.21 + version: 4.17.21 + ndjson: + specifier: 2.0.0 + version: 2.0.0 + devDependencies: + '@istanbuljs/nyc-config-typescript': + specifier: 1.0.2 + version: 1.0.2(nyc@15.1.0) + '@microsoft/api-extractor': + specifier: 7.40.1 + version: 7.40.1(@types/node@18.19.59) + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@types/chai': + specifier: ^4.2.22 + version: 4.3.20 + '@types/chai-as-promised': + specifier: ^7.1.5 + version: 7.1.8 + '@types/debug': + specifier: ^4.1.7 + version: 4.1.12 + '@types/fs-extra': + specifier: ^9.0.13 + version: 9.0.13 + '@types/lodash': + specifier: ^4.14.123 + version: 4.17.12 + '@types/mocha': + specifier: 9.1.1 + version: 9.1.1 + '@types/ndjson': + specifier: 2.0.1 + version: 2.0.1 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@typescript-eslint/eslint-plugin': + specifier: ^5.57.1 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/experimental-utils': + specifier: ^5.62.0 + version: 5.62.0(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: ^5.57.1 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.3.4 + version: 4.5.0 + chai-as-promised: + specifier: 7.1.1 + version: 7.1.1(chai@4.5.0) + eslint: + specifier: ^8.38.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-import-resolver-typescript: + specifier: ^3.5.5 + version: 3.7.0(eslint-plugin-import@2.29.0)(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.29.0 + version: 2.29.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) + eslint-plugin-mocha: + specifier: ^9.0.0 + version: 9.0.0(eslint@8.57.1) + eslint-plugin-no-only-tests: + specifier: 3.1.0 + version: 3.1.0 + eslint-plugin-prettier: + specifier: 4.0.0 + version: 4.0.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) + hardhat: + specifier: workspace:^2.18.0 + version: link:../hardhat-core + mocha: + specifier: ^9.1.3 + version: 9.2.2 + nyc: + specifier: 15.1.0 + version: 15.1.0 + prettier: + specifier: 2.8.8 + version: 2.8.8 + rimraf: + specifier: 3.0.2 + version: 3.0.2 + ts-node: + specifier: 10.9.1 + version: 10.9.1(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ^5.0.2 + version: 5.0.4 + + packages/hardhat-ignition-ethers: + devDependencies: + '@istanbuljs/nyc-config-typescript': + specifier: 1.0.2 + version: 1.0.2(nyc@15.1.0) + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/hardhat-ethers': + specifier: workspace:^3.0.4 + version: link:../hardhat-ethers + '@nomicfoundation/hardhat-ignition': + specifier: workspace:^ + version: link:../hardhat-ignition + '@nomicfoundation/ignition-core': + specifier: workspace:^ + version: link:../hardhat-ignition-core + '@types/chai': + specifier: ^4.2.22 + version: 4.3.20 + '@types/chai-as-promised': + specifier: ^7.1.4 + version: 7.1.8 + '@types/mocha': + specifier: 9.1.1 + version: 9.1.1 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@types/sinon': + specifier: ^10.0.13 + version: 10.0.20 + '@typescript-eslint/eslint-plugin': + specifier: ^5.57.1 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/experimental-utils': + specifier: ^5.62.0 + version: 5.62.0(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: ^5.57.1 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.3.4 + version: 4.5.0 + chai-as-promised: + specifier: 7.1.1 + version: 7.1.1(chai@4.5.0) + eslint: + specifier: ^8.38.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-import-resolver-typescript: + specifier: ^3.5.5 + version: 3.7.0(eslint-plugin-import@2.29.0)(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.29.0 + version: 2.29.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) + eslint-plugin-mocha: + specifier: ^9.0.0 + version: 9.0.0(eslint@8.57.1) + eslint-plugin-no-only-tests: + specifier: 3.1.0 + version: 3.1.0 + eslint-plugin-prettier: + specifier: 4.0.0 + version: 4.0.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) + ethers: + specifier: ^6.7.0 + version: 6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + hardhat: + specifier: workspace:^2.18.0 + version: link:../hardhat-core + mocha: + specifier: ^9.1.3 + version: 9.2.2 + nyc: + specifier: 15.1.0 + version: 15.1.0 + prettier: + specifier: 2.8.8 + version: 2.8.8 + rimraf: + specifier: 3.0.2 + version: 3.0.2 + sinon: + specifier: ^14.0.0 + version: 14.0.2 + ts-node: + specifier: 10.9.1 + version: 10.9.1(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ^5.0.2 + version: 5.0.4 + + packages/hardhat-ignition-ui: + devDependencies: + '@fontsource/roboto': + specifier: ^5.0.8 + version: 5.1.1 + '@nomicfoundation/ignition-core': + specifier: workspace:^ + version: link:../hardhat-ignition-core + '@types/chai': + specifier: ^4.2.22 + version: 4.3.20 + '@types/chai-as-promised': + specifier: ^7.1.5 + version: 7.1.8 + '@types/mocha': + specifier: 9.1.1 + version: 9.1.1 + '@types/react': + specifier: ^18.0.28 + version: 18.3.18 + '@types/react-dom': + specifier: ^18.0.11 + version: 18.3.5(@types/react@18.3.18) + '@types/styled-components': + specifier: 5.1.26 + version: 5.1.26 + '@typescript-eslint/parser': + specifier: ^5.57.1 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + '@vitejs/plugin-react': + specifier: ^4.0.0 + version: 4.3.4(vite@5.4.17(@types/node@22.7.5)) + chai: + specifier: ^4.3.4 + version: 4.5.0 + chai-as-promised: + specifier: 7.1.1 + version: 7.1.1(chai@4.5.0) + eslint: + specifier: ^8.38.0 + version: 8.57.1 + eslint-plugin-react-hooks: + specifier: ^4.6.0 + version: 4.6.2(eslint@8.57.1) + eslint-plugin-react-refresh: + specifier: ^0.3.4 + version: 0.3.5(eslint@8.57.1) + mermaid: + specifier: 10.9.3 + version: 10.9.3 + mocha: + specifier: ^9.1.3 + version: 9.2.2 + react: + specifier: ^18.2.0 + version: 18.3.1 + react-dom: + specifier: ^18.2.0 + version: 18.3.1(react@18.3.1) + react-router-dom: + specifier: 6.11.0 + version: 6.11.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-tooltip: + specifier: ^5.21.4 + version: 5.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + styled-components: + specifier: 5.3.10 + version: 5.3.10(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1) + svg-pan-zoom: + specifier: ^3.6.1 + version: 3.6.2 + ts-node: + specifier: 10.9.1 + version: 10.9.1(@types/node@22.7.5)(typescript@5.0.4) + typescript: + specifier: ^5.0.2 + version: 5.0.4 + vite: + specifier: ^5.4.17 + version: 5.4.17(@types/node@22.7.5) + vite-plugin-singlefile: + specifier: ^2.0.1 + version: 2.1.0(rollup@4.39.0)(vite@5.4.17(@types/node@22.7.5)) + + packages/hardhat-ignition-viem: + devDependencies: + '@istanbuljs/nyc-config-typescript': + specifier: 1.0.2 + version: 1.0.2(nyc@15.1.0) + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/hardhat-ignition': + specifier: workspace:^ + version: link:../hardhat-ignition + '@nomicfoundation/hardhat-viem': + specifier: workspace:^2.0.0 + version: link:../hardhat-viem + '@nomicfoundation/ignition-core': + specifier: workspace:^ + version: link:../hardhat-ignition-core + '@types/chai': + specifier: ^4.2.22 + version: 4.3.20 + '@types/chai-as-promised': + specifier: ^7.1.4 + version: 7.1.8 + '@types/mocha': + specifier: 9.1.1 + version: 9.1.1 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@types/sinon': + specifier: ^10.0.13 + version: 10.0.20 + '@typescript-eslint/eslint-plugin': + specifier: ^5.57.1 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/experimental-utils': + specifier: ^5.62.0 + version: 5.62.0(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: ^5.57.1 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.3.4 + version: 4.5.0 + chai-as-promised: + specifier: 7.1.1 + version: 7.1.1(chai@4.5.0) + eslint: + specifier: ^8.38.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-import-resolver-typescript: + specifier: ^3.5.5 + version: 3.7.0(eslint-plugin-import@2.29.0)(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.29.0 + version: 2.29.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) + eslint-plugin-mocha: + specifier: ^9.0.0 + version: 9.0.0(eslint@8.57.1) + eslint-plugin-no-only-tests: + specifier: 3.1.0 + version: 3.1.0 + eslint-plugin-prettier: + specifier: 4.0.0 + version: 4.0.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) + hardhat: + specifier: workspace:^2.18.0 + version: link:../hardhat-core + mocha: + specifier: ^9.1.3 + version: 9.2.2 + nyc: + specifier: 15.1.0 + version: 15.1.0 + prettier: + specifier: 2.8.8 + version: 2.8.8 + rimraf: + specifier: 3.0.2 + version: 3.0.2 + sinon: + specifier: ^14.0.0 + version: 14.0.2 + ts-node: + specifier: 10.9.1 + version: 10.9.1(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ^5.0.2 + version: 5.0.4 + viem: + specifier: ^2.7.6 + version: 2.21.34(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8) + + packages/hardhat-ledger: + dependencies: + '@ethereumjs/util': + specifier: ^9.1.0 + version: 9.1.0 + '@ledgerhq/errors': + specifier: ^6.12.6 + version: 6.19.1 + '@ledgerhq/hw-app-eth': + specifier: 6.33.6 + version: 6.33.6(debug@4.3.7) + '@ledgerhq/hw-transport': + specifier: ^6.28.4 + version: 6.31.4 + '@ledgerhq/hw-transport-node-hid': + specifier: ^6.27.13 + version: 6.29.5 + chalk: + specifier: ^2.4.2 + version: 2.4.2 + debug: + specifier: ^4.1.1 + version: 4.3.7(supports-color@5.5.0) + env-paths: + specifier: ^2.2.0 + version: 2.2.1 + ethers: + specifier: ^6.1.0 + version: 6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + fs-extra: + specifier: ^7.0.1 + version: 7.0.1 + io-ts: + specifier: 1.10.4 + version: 1.10.4 + ora: + specifier: ^5.4.1 + version: 5.4.1 + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/fs-extra': + specifier: ^5.1.0 + version: 5.1.0 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@types/sinon': + specifier: ^9.0.8 + version: 9.0.11 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.2.0 + version: 4.5.0 + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + hardhat: + specifier: workspace:^2.16.0 + version: link:../hardhat-core + mocha: + specifier: ^10.0.0 + version: 10.7.3 + nyc: + specifier: ^15.1.0 + version: 15.1.0 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + sinon: + specifier: ^9.0.0 + version: 9.2.4 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + + packages/hardhat-network-helpers: + dependencies: + ethereumjs-util: + specifier: ^7.1.4 + version: 7.1.5 + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/chai-as-promised': + specifier: ^7.1.3 + version: 7.1.8 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.2.0 + version: 4.5.0 + chai-as-promised: + specifier: ^7.1.1 + version: 7.1.2(chai@4.5.0) + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + ethers-v5: + specifier: npm:ethers@5 + version: ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + hardhat: + specifier: workspace:^2.9.5 + version: link:../hardhat-core + mocha: + specifier: ^10.0.0 + version: 10.7.3 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + + packages/hardhat-shorthand: + dependencies: + '@fvictorio/tabtab': + specifier: ^0.0.3 + version: 0.0.3 + debug: + specifier: ^4.1.1 + version: 4.3.7(supports-color@5.5.0) + semver: + specifier: ^6.3.0 + version: 6.3.1 + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/debug': + specifier: ^4.1.4 + version: 4.1.12 + '@types/fs-extra': + specifier: ^5.1.0 + version: 5.1.0 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@types/semver': + specifier: ^6.0.2 + version: 6.2.7 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.2.0 + version: 4.5.0 + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + hardhat: + specifier: workspace:^2.0.0 + version: link:../hardhat-core + mocha: + specifier: ^10.0.0 + version: 10.7.3 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + + packages/hardhat-solhint: + dependencies: + solhint: + specifier: ^5.0.2 + version: 5.0.3(typescript@5.0.4) + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/fs-extra': + specifier: ^5.1.0 + version: 5.1.0 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@types/sinon': + specifier: ^9.0.8 + version: 9.0.11 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.2.0 + version: 4.5.0 + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + fs-extra: + specifier: ^7.0.1 + version: 7.0.1 + hardhat: + specifier: workspace:^2.0.0 + version: link:../hardhat-core + mocha: + specifier: ^10.0.0 + version: 10.7.3 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + sinon: + specifier: ^9.0.0 + version: 9.2.4 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + + packages/hardhat-solpp: + dependencies: + fs-extra: + specifier: ^7.0.1 + version: 7.0.1 + solpp: + specifier: ^0.11.5 + version: 0.11.5 + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/fs-extra': + specifier: ^5.1.0 + version: 5.1.0 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.2.0 + version: 4.5.0 + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + hardhat: + specifier: workspace:^2.0.0 + version: link:../hardhat-core + mocha: + specifier: ^10.0.0 + version: 10.7.3 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + + packages/hardhat-toolbox: + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@nomicfoundation/hardhat-chai-matchers': + specifier: workspace:^2.0.0 + version: link:../hardhat-chai-matchers + '@nomicfoundation/hardhat-ethers': + specifier: workspace:^3.0.0 + version: link:../hardhat-ethers + '@nomicfoundation/hardhat-ignition-ethers': + specifier: workspace:^0.15.0 + version: link:../hardhat-ignition-ethers + '@nomicfoundation/hardhat-network-helpers': + specifier: workspace:^1.0.0 + version: link:../hardhat-network-helpers + '@nomicfoundation/hardhat-verify': + specifier: workspace:^2.0.0 + version: link:../hardhat-verify + '@typechain/ethers-v6': + specifier: ^0.5.0 + version: 0.5.1(ethers@6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.0.4))(typescript@5.0.4) + '@typechain/hardhat': + specifier: ^9.0.0 + version: 9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.0.4))(typescript@5.0.4))(ethers@6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@packages+hardhat-core)(typechain@8.3.2(typescript@5.0.4)) + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.4.1 + version: 4.5.0 + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + ethers: + specifier: ^6.4.0 + version: 6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + hardhat: + specifier: workspace:^2.11.0 + version: link:../hardhat-core + hardhat-gas-reporter: + specifier: ^1.0.8 + version: 1.0.10(bufferutil@4.0.8)(hardhat@packages+hardhat-core)(utf-8-validate@5.0.10) + mocha: + specifier: ^10.0.0 + version: 10.7.3 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + solidity-coverage: + specifier: ^0.8.1 + version: 0.8.13(hardhat@packages+hardhat-core) + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typechain: + specifier: ^8.3.1 + version: 8.3.2(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + + packages/hardhat-toolbox-viem: + dependencies: + chai-as-promised: + specifier: ^7.1.1 + version: 7.1.2(chai@4.5.0) + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@nomicfoundation/hardhat-ignition-viem': + specifier: workspace:^0.15.0 + version: link:../hardhat-ignition-viem + '@nomicfoundation/hardhat-network-helpers': + specifier: workspace:^1.0.0 + version: link:../hardhat-network-helpers + '@nomicfoundation/hardhat-verify': + specifier: workspace:^2.0.0 + version: link:../hardhat-verify + '@nomicfoundation/hardhat-viem': + specifier: workspace:^2.0.0 + version: link:../hardhat-viem + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/chai-as-promised': + specifier: ^7.1.6 + version: 7.1.8 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.2.0 + version: 4.5.0 + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + hardhat: + specifier: workspace:^2.11.0 + version: link:../hardhat-core + hardhat-gas-reporter: + specifier: ^1.0.8 + version: 1.0.10(bufferutil@4.0.8)(hardhat@packages+hardhat-core)(utf-8-validate@5.0.10) + mocha: + specifier: ^10.0.0 + version: 10.7.3 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + solidity-coverage: + specifier: ^0.8.1 + version: 0.8.13(hardhat@packages+hardhat-core) + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.4 + version: 5.0.4 + viem: + specifier: ^2.7.6 + version: 2.21.34(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8) + + packages/hardhat-truffle4: + dependencies: + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + chai: + specifier: ^4.2.0 + version: 4.5.0 + ethereumjs-util: + specifier: ^7.1.4 + version: 7.1.5 + fs-extra: + specifier: ^7.0.1 + version: 7.0.1 + truffle-contract: + specifier: ^3.0.7 + version: 3.0.8 + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@nomiclabs/hardhat-web3-legacy': + specifier: workspace:^2.0.0 + version: link:../hardhat-web3-legacy + '@types/fs-extra': + specifier: ^5.1.0 + version: 5.1.0 + '@types/glob': + specifier: ^7.1.1 + version: 7.2.0 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + hardhat: + specifier: workspace:^2.6.4 + version: link:../hardhat-core + mocha: + specifier: ^10.0.0 + version: 10.7.3 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + web3: + specifier: ^0.20.0 + version: 0.20.7 + + packages/hardhat-truffle5: + dependencies: + '@nomiclabs/truffle-contract': + specifier: ^4.2.23 + version: 4.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)(web3-core-helpers@1.10.4)(web3-core-promievent@1.10.4)(web3-eth-abi@1.10.4)(web3-utils@1.10.4)(web3@1.10.4(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + chai: + specifier: ^4.2.0 + version: 4.5.0 + ethereumjs-util: + specifier: ^7.1.4 + version: 7.1.5 + fs-extra: + specifier: ^7.0.1 + version: 7.0.1 + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@nomiclabs/hardhat-web3': + specifier: workspace:^2.0.0 + version: link:../hardhat-web3 + '@types/fs-extra': + specifier: ^5.1.0 + version: 5.1.0 + '@types/glob': + specifier: ^7.1.1 + version: 7.2.0 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + hardhat: + specifier: workspace:^2.6.4 + version: link:../hardhat-core + mocha: + specifier: ^10.0.0 + version: 10.7.3 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + web3: + specifier: ^1.0.0-beta.36 + version: 1.10.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-eth-abi: + specifier: 1.10.4 + version: 1.10.4 + web3-utils: + specifier: 1.10.4 + version: 1.10.4 + + packages/hardhat-verify: + dependencies: + '@ethersproject/abi': + specifier: ^5.1.2 + version: 5.7.0 + '@ethersproject/address': + specifier: ^5.0.2 + version: 5.7.0 + cbor: + specifier: ^8.1.0 + version: 8.1.0 + debug: + specifier: ^4.1.1 + version: 4.3.7(supports-color@5.5.0) + lodash.clonedeep: + specifier: ^4.5.0 + version: 4.5.0 + picocolors: + specifier: ^1.1.0 + version: 1.1.0 + semver: + specifier: ^6.3.0 + version: 6.3.1 + table: + specifier: ^6.8.0 + version: 6.8.2 + undici: + specifier: ^5.14.0 + version: 5.28.4 + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@nomicfoundation/hardhat-ethers': + specifier: workspace:^3.0.0 + version: link:../hardhat-ethers + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/chai-as-promised': + specifier: ^7.1.3 + version: 7.1.8 + '@types/debug': + specifier: ^4.1.4 + version: 4.1.12 + '@types/lodash.clonedeep': + specifier: ^4.5.7 + version: 4.5.9 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@types/semver': + specifier: ^6.0.2 + version: 6.2.7 + '@types/sinon': + specifier: ^9.0.8 + version: 9.0.11 + '@types/sinon-chai': + specifier: ^3.2.9 + version: 3.2.12 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.2.0 + version: 4.5.0 + chai-as-promised: + specifier: ^7.1.1 + version: 7.1.2(chai@4.5.0) + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + ethers: + specifier: ^5.0.0 + version: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + hardhat: + specifier: workspace:^2.0.4 + version: link:../hardhat-core + mocha: + specifier: ^10.0.0 + version: 10.7.3 + nyc: + specifier: ^15.1.0 + version: 15.1.0 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + sinon: + specifier: ^9.0.0 + version: 9.2.4 + sinon-chai: + specifier: ^3.7.0 + version: 3.7.0(chai@4.5.0)(sinon@9.2.4) + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + + packages/hardhat-viem: + dependencies: + abitype: + specifier: ^0.9.8 + version: 0.9.10(typescript@5.0.4)(zod@3.23.8) + lodash.memoize: + specifier: ^4.1.2 + version: 4.1.2 + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/chai-as-promised': + specifier: ^7.1.3 + version: 7.1.8 + '@types/lodash': + specifier: ^4.14.123 + version: 4.17.12 + '@types/lodash.memoize': + specifier: ^4.1.7 + version: 4.1.9 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@types/sinon': + specifier: ^9.0.8 + version: 9.0.11 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.2.0 + version: 4.5.0 + chai-as-promised: + specifier: ^7.1.1 + version: 7.1.2(chai@4.5.0) + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + hardhat: + specifier: workspace:^2.17.0 + version: link:../hardhat-core + jest-diff: + specifier: ^29.7.0 + version: 29.7.0 + mocha: + specifier: ^10.0.0 + version: 10.7.3 + nyc: + specifier: ^15.1.0 + version: 15.1.0 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + sinon: + specifier: ^9.0.0 + version: 9.2.4 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + viem: + specifier: ^2.7.6 + version: 2.21.34(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8) + + packages/hardhat-vyper: + dependencies: + debug: + specifier: ^4.1.1 + version: 4.3.7(supports-color@5.5.0) + fs-extra: + specifier: ^7.0.1 + version: 7.0.1 + io-ts: + specifier: 1.10.4 + version: 1.10.4 + lodash: + specifier: ^4.17.11 + version: 4.17.21 + semver: + specifier: ^6.3.0 + version: 6.3.1 + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/chai-as-promised': + specifier: ^7.1.3 + version: 7.1.8 + '@types/debug': + specifier: ^4.1.4 + version: 4.1.12 + '@types/fs-extra': + specifier: ^5.1.0 + version: 5.1.0 + '@types/lodash': + specifier: ^4.14.123 + version: 4.17.12 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@types/semver': + specifier: ^6.0.2 + version: 6.2.7 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.2.0 + version: 4.5.0 + chai-as-promised: + specifier: ^7.1.1 + version: 7.1.2(chai@4.5.0) + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + hardhat: + specifier: workspace:^2.8.3 + version: link:../hardhat-core + mocha: + specifier: ^10.0.0 + version: 10.7.3 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + + packages/hardhat-web3: + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.2.0 + version: 4.5.0 + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + hardhat: + specifier: workspace:^2.0.0 + version: link:../hardhat-core + mocha: + specifier: ^10.0.0 + version: 10.7.3 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + sha3: + specifier: ^2.1.4 + version: 2.1.4 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + web3: + specifier: ^1.0.0-beta.36 + version: 1.10.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + + packages/hardhat-web3-legacy: + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.2.0 + version: 4.5.0 + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + hardhat: + specifier: workspace:^2.0.0 + version: link:../hardhat-core + mocha: + specifier: ^10.0.0 + version: 10.7.3 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + web3: + specifier: ^0.20.0 + version: 0.20.7 + + packages/hardhat-web3-v4: + devDependencies: + '@nomicfoundation/eslint-plugin-hardhat-internal-rules': + specifier: workspace:^ + version: link:../eslint-plugin-hardhat-internal-rules + '@nomicfoundation/eslint-plugin-slow-imports': + specifier: workspace:^ + version: link:../eslint-plugin-slow-imports + '@types/chai': + specifier: ^4.2.0 + version: 4.3.20 + '@types/chai-as-promised': + specifier: ^7.1.3 + version: 7.1.8 + '@types/mocha': + specifier: '>=9.1.0' + version: 10.0.9 + '@types/node': + specifier: ^18.0.0 + version: 18.19.59 + '@typescript-eslint/eslint-plugin': + specifier: 5.61.0 + version: 5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/parser': + specifier: 5.61.0 + version: 5.61.0(eslint@8.57.1)(typescript@5.0.4) + chai: + specifier: ^4.2.0 + version: 4.5.0 + chai-as-promised: + specifier: ^7.1.1 + version: 7.1.2(chai@4.5.0) + eslint: + specifier: ^8.44.0 + version: 8.57.1 + eslint-config-prettier: + specifier: 8.3.0 + version: 8.3.0(eslint@8.57.1) + eslint-plugin-import: + specifier: 2.27.5 + version: 2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1) + eslint-plugin-mocha: + specifier: 10.4.1 + version: 10.4.1(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 3.4.0 + version: 3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1) + hardhat: + specifier: workspace:^2.0.0 + version: link:../hardhat-core + mocha: + specifier: ^10.0.0 + version: 10.7.3 + prettier: + specifier: 2.4.1 + version: 2.4.1 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + ts-node: + specifier: ^10.8.0 + version: 10.9.2(@types/node@18.19.59)(typescript@5.0.4) + typescript: + specifier: ~5.0.0 + version: 5.0.4 + web3: + specifier: ^4.0.1 + version: 4.14.0(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8) + +packages: + + '@adraffy/ens-normalize@1.10.1': + resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} + + '@adraffy/ens-normalize@1.11.0': + resolution: {integrity: sha512-/3DDPKHqqIqxUULp8yP4zODUY1i+2xvVWsv8A79xGWdCAG+8sb0hRh0Rk2QyOJUnnbyPUAZYcpBuRe3nS2OIUg==} + + '@ampproject/remapping@2.3.0': + resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==} + engines: {node: '>=6.0.0'} + + '@babel/code-frame@7.25.9': + resolution: {integrity: sha512-z88xeGxnzehn2sqZ8UdGQEvYErF1odv2CftxInpSYJt6uHuPe9YjahKZITGs3l5LeI9d2ROG+obuDAoSlqbNfQ==} + engines: {node: '>=6.9.0'} + + '@babel/code-frame@7.26.2': + resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.25.9': + resolution: {integrity: sha512-yD+hEuJ/+wAJ4Ox2/rpNv5HIuPG82x3ZlQvYVn8iYCprdxzE7P1udpGF1jyjQVBU4dgznN+k2h103vxZ7NdPyw==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.25.9': + resolution: {integrity: sha512-WYvQviPw+Qyib0v92AwNIrdLISTp7RfDkM7bPqBvpbnhY4wq8HvHBZREVdYDXk98C8BkOIVnHAY3yvj7AVISxQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.26.0': + resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.25.9': + resolution: {integrity: sha512-omlUGkr5EaoIJrhLf9CJ0TvjBRpd9+AXRG//0GEQ9THSo8wPiTlbpy1/Ow8ZTrbXpjd9FHXfbFQx32I04ht0FA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.26.5': + resolution: {integrity: sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.25.9': + resolution: {integrity: sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.25.9': + resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.25.9': + resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.25.9': + resolution: {integrity: sha512-TvLZY/F3+GvdRYFZFyxMvnsKi+4oJdgZzU3BoGN9Uc2d9C6zfNwJcKKhjqLAhK8i46mv93jsO74fDh3ih6rpHA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-module-transforms@7.26.0': + resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-plugin-utils@7.26.5': + resolution: {integrity: sha512-RS+jZcRdZdRFzMyr+wcsaqOmld1/EqTghfaBGQQd/WnRdzdlvSZ//kF7U8VQTxf1ynZ4cjUcYgjVGx13ewNPMg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-simple-access@7.25.9': + resolution: {integrity: sha512-c6WHXuiaRsJTyHYLJV75t9IqsmTbItYfdj99PnzYGQZkYKvan5/2jKJ7gu31J3/BJ/A18grImSPModuyG/Eo0Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.25.9': + resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.25.9': + resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.25.9': + resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.25.9': + resolution: {integrity: sha512-oKWp3+usOJSzDZOucZUAMayhPz/xVjzymyDzUN8dk0Wd3RWMlGLXi07UCQ/CgQVb8LvXx3XBajJH4XGgkt7H7g==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.26.0': + resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==} + engines: {node: '>=6.9.0'} + + '@babel/highlight@7.25.9': + resolution: {integrity: sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.25.9': + resolution: {integrity: sha512-aI3jjAAO1fh7vY/pBGsn1i9LDbRP43+asrRlkPuTXW5yHXtd1NgTEMudbBoDDxrf1daEEfPJqR+JBMakzrR4Dg==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/parser@7.26.5': + resolution: {integrity: sha512-SRJ4jYmXRqV1/Xc+TIVG84WjHBXKlxO9sHQnA2Pf12QQEAp1LOh6kDzNHXcUnbH1QI0FDoPPVOt+vyUDucxpaw==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-syntax-jsx@7.25.9': + resolution: {integrity: sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-self@7.25.9': + resolution: {integrity: sha512-y8quW6p0WHkEhmErnfe58r7x0A70uKphQm8Sp8cV7tjNQwK56sNVK0M73LK3WuYmsuyrftut4xAkjjgU0twaMg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-source@7.25.9': + resolution: {integrity: sha512-+iqjT8xmXhhYv4/uiYd8FNQsraMFZIfxVSqxxVSZP0WbbSAWvBXAul0m/zu+7Vv4O/3WtApy9pmaTMiumEZgfg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.25.9': + resolution: {integrity: sha512-4zpTHZ9Cm6L9L+uIqghQX8ZXg8HKFcjYO3qHoO8zTmRm6HQUJ8SSJ+KRvbMBZn0EGVlT4DRYeQ/6hjlyXBh+Kg==} + engines: {node: '>=6.9.0'} + + '@babel/template@7.25.9': + resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.25.9': + resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.25.9': + resolution: {integrity: sha512-OwS2CM5KocvQ/k7dFJa8i5bNGJP0hXWfVCfDkqRFP1IreH1JDC7wG6eCYCi0+McbfT8OR/kNqsI0UU0xP9H6PQ==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.26.5': + resolution: {integrity: sha512-L6mZmwFDK6Cjh1nRCLXpa6no13ZIioJDz7mdkzHv399pThrTa/k0nUlNaenOeh2kWu/iaOQYElEpKPUswUa9Vg==} + engines: {node: '>=6.9.0'} + + '@braintree/sanitize-url@6.0.4': + resolution: {integrity: sha512-s3jaWicZd0pkP0jf5ysyHUI/RE7MHos6qlToFcGWXVp+ykHOy77OUMrfbgJ9it2C5bow7OIQwYYaHjk9XlBQ2A==} + + '@changesets/apply-release-plan@7.0.5': + resolution: {integrity: sha512-1cWCk+ZshEkSVEZrm2fSj1Gz8sYvxgUL4Q78+1ZZqeqfuevPTPk033/yUZ3df8BKMohkqqHfzj0HOOrG0KtXTw==} + + '@changesets/assemble-release-plan@6.0.4': + resolution: {integrity: sha512-nqICnvmrwWj4w2x0fOhVj2QEGdlUuwVAwESrUo5HLzWMI1rE5SWfsr9ln+rDqWB6RQ2ZyaMZHUcU7/IRaUJS+Q==} + + '@changesets/changelog-git@0.2.0': + resolution: {integrity: sha512-bHOx97iFI4OClIT35Lok3sJAwM31VbUM++gnMBV16fdbtBhgYu4dxsphBF/0AZZsyAHMrnM0yFcj5gZM1py6uQ==} + + '@changesets/cli@2.27.9': + resolution: {integrity: sha512-q42a/ZbDnxPpCb5Wkm6tMVIxgeI9C/bexntzTeCFBrQEdpisQqk8kCHllYZMDjYtEc1ZzumbMJAG8H0Z4rdvjg==} + hasBin: true + + '@changesets/config@3.0.3': + resolution: {integrity: sha512-vqgQZMyIcuIpw9nqFIpTSNyc/wgm/Lu1zKN5vECy74u95Qx/Wa9g27HdgO4NkVAaq+BGA8wUc/qvbvVNs93n6A==} + + '@changesets/errors@0.2.0': + resolution: {integrity: sha512-6BLOQUscTpZeGljvyQXlWOItQyU71kCdGz7Pi8H8zdw6BI0g3m43iL4xKUVPWtG+qrrL9DTjpdn8eYuCQSRpow==} + + '@changesets/get-dependents-graph@2.1.2': + resolution: {integrity: sha512-sgcHRkiBY9i4zWYBwlVyAjEM9sAzs4wYVwJUdnbDLnVG3QwAaia1Mk5P8M7kraTOZN+vBET7n8KyB0YXCbFRLQ==} + + '@changesets/get-release-plan@4.0.4': + resolution: {integrity: sha512-SicG/S67JmPTrdcc9Vpu0wSQt7IiuN0dc8iR5VScnnTVPfIaLvKmEGRvIaF0kcn8u5ZqLbormZNTO77bCEvyWw==} + + '@changesets/get-version-range-type@0.4.0': + resolution: {integrity: sha512-hwawtob9DryoGTpixy1D3ZXbGgJu1Rhr+ySH2PvTLHvkZuQ7sRT4oQwMh0hbqZH1weAooedEjRsbrWcGLCeyVQ==} + + '@changesets/git@3.0.1': + resolution: {integrity: sha512-pdgHcYBLCPcLd82aRcuO0kxCDbw/yISlOtkmwmE8Odo1L6hSiZrBOsRl84eYG7DRCab/iHnOkWqExqc4wxk2LQ==} + + '@changesets/logger@0.1.1': + resolution: {integrity: sha512-OQtR36ZlnuTxKqoW4Sv6x5YIhOmClRd5pWsjZsddYxpWs517R0HkyiefQPIytCVh4ZcC5x9XaG8KTdd5iRQUfg==} + + '@changesets/parse@0.4.0': + resolution: {integrity: sha512-TS/9KG2CdGXS27S+QxbZXgr8uPsP4yNJYb4BC2/NeFUj80Rni3TeD2qwWmabymxmrLo7JEsytXH1FbpKTbvivw==} + + '@changesets/pre@2.0.1': + resolution: {integrity: sha512-vvBJ/If4jKM4tPz9JdY2kGOgWmCowUYOi5Ycv8dyLnEE8FgpYYUo1mgJZxcdtGGP3aG8rAQulGLyyXGSLkIMTQ==} + + '@changesets/read@0.6.1': + resolution: {integrity: sha512-jYMbyXQk3nwP25nRzQQGa1nKLY0KfoOV7VLgwucI0bUO8t8ZLCr6LZmgjXsiKuRDc+5A6doKPr9w2d+FEJ55zQ==} + + '@changesets/should-skip-package@0.1.1': + resolution: {integrity: sha512-H9LjLbF6mMHLtJIc/eHR9Na+MifJ3VxtgP/Y+XLn4BF7tDTEN1HNYtH6QMcjP1uxp9sjaFYmW8xqloaCi/ckTg==} + + '@changesets/types@4.1.0': + resolution: {integrity: sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw==} + + '@changesets/types@6.0.0': + resolution: {integrity: sha512-b1UkfNulgKoWfqyHtzKS5fOZYSJO+77adgL7DLRDr+/7jhChN+QcHnbjiQVOz/U+Ts3PGNySq7diAItzDgugfQ==} + + '@changesets/write@0.3.2': + resolution: {integrity: sha512-kDxDrPNpUgsjDbWBvUo27PzKX4gqeKOlhibaOXDJA6kuBisGqNHv/HwGJrAu8U/dSf8ZEFIeHIPtvSlZI1kULw==} + + '@cspotcode/source-map-support@0.8.1': + resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} + engines: {node: '>=12'} + + '@emotion/is-prop-valid@1.3.1': + resolution: {integrity: sha512-/ACwoqx7XQi9knQs/G0qKvv5teDMhD7bXYns9N/wM8ah8iNb8jZ2uNO0YOgiq2o2poIvVtJS2YALasQuMSQ7Kw==} + + '@emotion/memoize@0.9.0': + resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} + + '@emotion/stylis@0.8.5': + resolution: {integrity: sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==} + + '@emotion/unitless@0.7.5': + resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==} + + '@ensdomains/address-encoder@0.1.9': + resolution: {integrity: sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg==} + + '@ensdomains/ens@0.4.5': + resolution: {integrity: sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw==} + deprecated: Please use @ensdomains/ens-contracts + + '@ensdomains/ensjs@2.1.0': + resolution: {integrity: sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog==} + + '@ensdomains/resolver@0.2.4': + resolution: {integrity: sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA==} + deprecated: Please use @ensdomains/ens-contracts + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.4.0': + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.11.1': + resolution: {integrity: sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@ethereumjs/common@2.5.0': + resolution: {integrity: sha512-DEHjW6e38o+JmB/NO3GZBpW4lpaiBpkFgXF6jLcJ6gETBYpEyaA5nTimsWBUJR3Vmtm/didUEbNjajskugZORg==} + + '@ethereumjs/common@2.6.5': + resolution: {integrity: sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA==} + + '@ethereumjs/rlp@4.0.1': + resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==} + engines: {node: '>=14'} + hasBin: true + + '@ethereumjs/rlp@5.0.2': + resolution: {integrity: sha512-DziebCdg4JpGlEqEdGgXmjqcFoJi+JGulUXwEjsZGAscAQ7MyD/7LE/GVCP29vEQxKc7AAwjT3A2ywHp2xfoCA==} + engines: {node: '>=18'} + hasBin: true + + '@ethereumjs/tx@3.3.2': + resolution: {integrity: sha512-6AaJhwg4ucmwTvw/1qLaZUX5miWrwZ4nLOUsKyb/HtzS3BMw/CasKhdi1ims9mBKeK9sOJCH4qGKOBGyJCeeog==} + + '@ethereumjs/tx@3.5.2': + resolution: {integrity: sha512-gQDNJWKrSDGu2w7w0PzVXVBNMzb7wwdDOmOqczmhNjqFxFuIbhVJDwiGEnxFNC2/b8ifcZzY7MLcluizohRzNw==} + + '@ethereumjs/util@8.1.0': + resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} + engines: {node: '>=14'} + + '@ethereumjs/util@9.1.0': + resolution: {integrity: sha512-XBEKsYqLGXLah9PNJbgdkigthkG7TAGvlD/sH12beMXEyHDyigfcbdvHhmLyDWgDyOJn4QwiQUaF7yeuhnjdog==} + engines: {node: '>=18'} + + '@ethersproject/abi@5.7.0': + resolution: {integrity: sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA==} + + '@ethersproject/abstract-provider@5.7.0': + resolution: {integrity: sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw==} + + '@ethersproject/abstract-signer@5.7.0': + resolution: {integrity: sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ==} + + '@ethersproject/address@5.6.1': + resolution: {integrity: sha512-uOgF0kS5MJv9ZvCz7x6T2EXJSzotiybApn4XlOgoTX0xdtyVIJ7pF+6cGPxiEq/dpBiTfMiw7Yc81JcwhSYA0Q==} + + '@ethersproject/address@5.7.0': + resolution: {integrity: sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA==} + + '@ethersproject/base64@5.7.0': + resolution: {integrity: sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ==} + + '@ethersproject/basex@5.7.0': + resolution: {integrity: sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw==} + + '@ethersproject/bignumber@5.7.0': + resolution: {integrity: sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw==} + + '@ethersproject/bytes@5.7.0': + resolution: {integrity: sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A==} + + '@ethersproject/constants@5.7.0': + resolution: {integrity: sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA==} + + '@ethersproject/contracts@5.7.0': + resolution: {integrity: sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg==} + + '@ethersproject/hash@5.7.0': + resolution: {integrity: sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g==} + + '@ethersproject/hdnode@5.7.0': + resolution: {integrity: sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg==} + + '@ethersproject/json-wallets@5.7.0': + resolution: {integrity: sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g==} + + '@ethersproject/keccak256@5.7.0': + resolution: {integrity: sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg==} + + '@ethersproject/logger@5.7.0': + resolution: {integrity: sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig==} + + '@ethersproject/networks@5.7.1': + resolution: {integrity: sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ==} + + '@ethersproject/pbkdf2@5.7.0': + resolution: {integrity: sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw==} + + '@ethersproject/properties@5.7.0': + resolution: {integrity: sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw==} + + '@ethersproject/providers@5.7.2': + resolution: {integrity: sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg==} + + '@ethersproject/random@5.7.0': + resolution: {integrity: sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ==} + + '@ethersproject/rlp@5.7.0': + resolution: {integrity: sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w==} + + '@ethersproject/sha2@5.7.0': + resolution: {integrity: sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw==} + + '@ethersproject/signing-key@5.7.0': + resolution: {integrity: sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q==} + + '@ethersproject/solidity@5.7.0': + resolution: {integrity: sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA==} + + '@ethersproject/strings@5.7.0': + resolution: {integrity: sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg==} + + '@ethersproject/transactions@5.7.0': + resolution: {integrity: sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ==} + + '@ethersproject/units@5.7.0': + resolution: {integrity: sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg==} + + '@ethersproject/wallet@5.7.0': + resolution: {integrity: sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA==} + + '@ethersproject/web@5.7.1': + resolution: {integrity: sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w==} + + '@ethersproject/wordlists@5.7.0': + resolution: {integrity: sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA==} + + '@fastify/busboy@2.1.1': + resolution: {integrity: sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==} + engines: {node: '>=14'} + + '@floating-ui/core@1.6.9': + resolution: {integrity: sha512-uMXCuQ3BItDUbAMhIXw7UPXRfAlOAvZzdK9BWpE60MCn+Svt3aLn9jsPTi/WNGlRUu2uI0v5S7JiIUsbsvh3fw==} + + '@floating-ui/dom@1.6.13': + resolution: {integrity: sha512-umqzocjDgNRGTuO7Q8CU32dkHkECqI8ZdMZ5Swb6QAM0t5rnlrN3lGo1hdpscRd3WS8T6DKYK4ephgIH9iRh3w==} + + '@floating-ui/utils@0.2.9': + resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==} + + '@fontsource/roboto@5.1.1': + resolution: {integrity: sha512-XwVVXtERDQIM7HPUIbyDe0FP4SRovpjF7zMI8M7pbqFp3ahLJsJTd18h+E6pkar6UbV3btbwkKjYARr5M+SQow==} + + '@fvictorio/tabtab@0.0.3': + resolution: {integrity: sha512-bT/BSy8MJThrTebqTCjXRnGSgZWthHLigZ4k2AvfNtC79vPyBS1myaxw8gRU6RxIcdDD3HBtm7pOsOoyC086Zg==} + engines: {node: '>=10'} + + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/nyc-config-typescript@1.0.2': + resolution: {integrity: sha512-iKGIyMoyJuFnJRSVTZ78POIRvNnwZaWIf8vG4ZS3rQq58MMDrqEX2nnzx0R28V2X8JvmKYiqY9FP2hlJsm8A0w==} + engines: {node: '>=8'} + peerDependencies: + nyc: '>=15' + + '@istanbuljs/schema@0.1.3': + resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} + engines: {node: '>=8'} + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.5': + resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==} + engines: {node: '>=6.0.0'} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/set-array@1.2.1': + resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==} + engines: {node: '>=6.0.0'} + + '@jridgewell/sourcemap-codec@1.5.0': + resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + + '@jridgewell/trace-mapping@0.3.25': + resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + + '@jridgewell/trace-mapping@0.3.9': + resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} + + '@json-schema-spec/json-pointer@0.1.2': + resolution: {integrity: sha512-BYY7IavBjwsWWSmVcMz2A9mKiDD9RvacnsItgmy1xV8cmgbtxFfKmKMtkVpD7pYtkx4mIW4800yZBXueVFIWPw==} + + '@json-schema-tools/dereferencer@1.6.3': + resolution: {integrity: sha512-NoQkj6hx9Joqbd/GZAOHSGtE6R+OzlnOcDfyidmx8e/CUv1Q+Z6/fmZo2wwCQWiwP1pnGYc95iKwp8M7XlV7wQ==} + + '@json-schema-tools/meta-schema@1.7.5': + resolution: {integrity: sha512-8Hy6tuMC2BQdK7O4ilLovFB9t0j5o0L/sQTuWeg2CNYpITmPiFTRiG7Yb/jYd483D8784kxLFJ0dT+T4O2hNmw==} + + '@json-schema-tools/reference-resolver@1.2.6': + resolution: {integrity: sha512-4QZu5ROb5EpLSvV+buzk8WR30W+dffSNaKqD3VGFYJ3y0BLDi2OHoSz5e6NKcLYTyUYXV8IKxocNOszeVBJI4Q==} + + '@json-schema-tools/referencer@1.1.3': + resolution: {integrity: sha512-p2JU7GpHn1kMyP7gnB2Wnki+OnifsSi75Uj5PxqIg2pT4fqh+BM3rEEZKpaET4xv0ZszG46CCI9eEvs68v2rXg==} + + '@json-schema-tools/titleizer@1.0.9': + resolution: {integrity: sha512-Gwg3YTP5P+3Q+OnvEcthTnsup3AsEkxZCrRLXoWppdjtSzRnsWxtvmpKdGLbVcocPC7Sh3aqJ7Arp85Ii6q2GA==} + + '@json-schema-tools/transpiler@1.10.5': + resolution: {integrity: sha512-uRm43U8wKWQV8czvvkJYwcUERpQC+azKmqbd7RhV1gWx7s1t0frLtrWqGbXh9xMcgdtF7+Tkiwex48nW5EnX1w==} + + '@json-schema-tools/traverse@1.10.4': + resolution: {integrity: sha512-9e42zjhLIxzBONroNC4SGsTqdB877tzwH2S6lqgTav9K24kWJR9vNieeMVSuyqnY8FlclH21D8wsm/tuD9WA9Q==} + + '@ledgerhq/cryptoassets@9.13.0': + resolution: {integrity: sha512-MzGJyc48OGU/FLYGYwEJyfOgbJzlR8XJ9Oo6XpNpNUM1/E5NDqvD72V0D+0uWIJYN3e2NtyqHXShLZDu7P95YA==} + + '@ledgerhq/devices@8.4.4': + resolution: {integrity: sha512-sz/ryhe/R687RHtevIE9RlKaV8kkKykUV4k29e7GAVwzHX1gqG+O75cu1NCJUHLbp3eABV5FdvZejqRUlLis9A==} + + '@ledgerhq/domain-service@1.2.9': + resolution: {integrity: sha512-65mlt+DBIs4osuUlljLelMCyG+a2VmWQPw5ppV4J50vPnkqfi8KAM+AiLbv9BHOfCTTaYyKjcVIWp/tHi82M3A==} + + '@ledgerhq/errors@6.19.1': + resolution: {integrity: sha512-75yK7Nnit/Gp7gdrJAz0ipp31CCgncRp+evWt6QawQEtQKYEDfGo10QywgrrBBixeRxwnMy1DP6g2oCWRf1bjw==} + + '@ledgerhq/hw-app-eth@6.33.6': + resolution: {integrity: sha512-QzYvr5FNEWWd70Vg04A2i8CY0mtPgJrrX7/KePabjXrR8NjDyJ5Ej8qSQPBTp2dkR4TGiz5Y7+HIcWpdgYzjzg==} + + '@ledgerhq/hw-transport-mocker@6.29.4': + resolution: {integrity: sha512-CLDIpQ/eqU8qrCYGY9MyHa+oMgqs6PuNkWtqbcaS4AzNx8L/9bv7y8CZwCjxX6oB/2ZEq42RlL6oZ6Ou3oHnoQ==} + + '@ledgerhq/hw-transport-node-hid-noevents@6.30.5': + resolution: {integrity: sha512-nOPbhFU87LgLERVAQ+HhxV8E8c+7d8ptllkgiJUc4QwL2z9zkIOAEtgdvCaZ066Oi9XGnln/GF1oAgByYnYDPw==} + + '@ledgerhq/hw-transport-node-hid@6.29.5': + resolution: {integrity: sha512-2bAp4K50V1kdCufU9JdQPcw4aLyvA+yQRJU/X39B+PC+rnis40gEbqNh0henhzv876sXdbNk6G/MkDWXpwDIow==} + + '@ledgerhq/hw-transport@6.31.4': + resolution: {integrity: sha512-6c1ir/cXWJm5dCWdq55NPgCJ3UuKuuxRvf//Xs36Bq9BwkV2YaRQhZITAkads83l07NAdR16hkTWqqpwFMaI6A==} + + '@ledgerhq/logs@6.12.0': + resolution: {integrity: sha512-ExDoj1QV5eC6TEbMdLUMMk9cfvNKhhv5gXol4SmULRVCx/3iyCPhJ74nsb3S0Vb+/f+XujBEj3vQn5+cwS0fNA==} + + '@ledgerhq/types-live@6.52.3': + resolution: {integrity: sha512-llIY2MPNedMFb+sm5T7o5ffbpR+avucVpksWMY6NcArKja9pwK24rJeZyJXP7HDzS7rcTQjBNFLqrjX2hnaZyA==} + + '@manypkg/find-root@1.1.0': + resolution: {integrity: sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA==} + + '@manypkg/get-packages@1.1.3': + resolution: {integrity: sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A==} + + '@microsoft/api-extractor-model@7.28.9': + resolution: {integrity: sha512-lM77dV+VO46MGp5lu4stUBnO3jyr+CrDzU+DtapcOQEZUqJxPYUoK5zjeD+gRZ9ckgGMZC94ch6FBkpmsjwQgw==} + + '@microsoft/api-extractor@7.40.1': + resolution: {integrity: sha512-xHn2Zkh6s5JIjP94SG6VtIlIeRJcASgfZpDKV+bgoddMt1X4ujSZFOz7uEGNYNO7mEtdVOvpNKBpC4CDytD8KQ==} + hasBin: true + + '@microsoft/tsdoc-config@0.16.2': + resolution: {integrity: sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==} + + '@microsoft/tsdoc@0.14.2': + resolution: {integrity: sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==} + + '@noble/curves@1.2.0': + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + + '@noble/curves@1.4.2': + resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} + + '@noble/curves@1.6.0': + resolution: {integrity: sha512-TlaHRXDehJuRNR9TfZDNQ45mMEd5dwUwmicsafcIX4SsNiqnCHKjE/1alYPd/lDRVhxdhUAlv8uEhMCI5zjIJQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.8.1': + resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.2.0': + resolution: {integrity: sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ==} + + '@noble/hashes@1.3.2': + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@noble/hashes@1.5.0': + resolution: {integrity: sha512-1j6kQFb7QRru7eKN3ZDvRcP13rugwdxZqCjbiAVZfIJwgj2A65UmT4TgARXGlXgnRkORLTDTrO19ZErt7+QXgA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.7.1': + resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/secp256k1@1.7.1': + resolution: {integrity: sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw==} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@nomicfoundation/edr-darwin-arm64@0.11.0': + resolution: {integrity: sha512-aYTVdcSs27XG7ayTzvZ4Yn9z/ABSaUwicrtrYK2NR8IH0ik4N4bWzo/qH8rax6rewVLbHUkGyGYnsy5ZN4iiMw==} + engines: {node: '>= 18'} + + '@nomicfoundation/edr-darwin-x64@0.11.0': + resolution: {integrity: sha512-RxX7UYgvJrfcyT/uHUn44Nsy1XaoW+Q1khKMdHKxeW7BrgIi+Lz+siz3bX5vhSoAnKilDPhIVLrnC8zxQhjR2A==} + engines: {node: '>= 18'} + + '@nomicfoundation/edr-linux-arm64-gnu@0.11.0': + resolution: {integrity: sha512-J0j+rs0s11FuSipt/ymqrFmpJ7c0FSz1/+FohCIlUXDxFv//+1R/8lkGPjEYFmy8DPpk/iO8mcpqHTGckREbqA==} + engines: {node: '>= 18'} + + '@nomicfoundation/edr-linux-arm64-musl@0.11.0': + resolution: {integrity: sha512-4r32zkGMN7WT/CMEuW0VjbuEdIeCskHNDMW4SSgQSJOE/N9L1KSLJCSsAbPD3aYE+e4WRDTyOwmuLjeUTcLZKQ==} + engines: {node: '>= 18'} + + '@nomicfoundation/edr-linux-x64-gnu@0.11.0': + resolution: {integrity: sha512-SmdncQHLYtVNWLIMyGaY6LpAfamzTDe3fxjkirmJv3CWR5tcEyC6LMui/GsIVnJzXeNJBXAzwl8hTUAxHTM6kQ==} + engines: {node: '>= 18'} + + '@nomicfoundation/edr-linux-x64-musl@0.11.0': + resolution: {integrity: sha512-w6hUqpn/trwiH6SRuRGysj37LsQVCX5XDCA3Xi81sbOaLhbHrNvK9TXWyZmcuzbdTKQQW6VNywcSxDdOiChcJg==} + engines: {node: '>= 18'} + + '@nomicfoundation/edr-win32-x64-msvc@0.11.0': + resolution: {integrity: sha512-BLmULjRKoH9BsX+c4Na2ypV7NGeJ+M6Zpqj/faPOwleVscDdSr/IhriyPaXCe8dyfwbge7lWsbekiADtPSnB2Q==} + engines: {node: '>= 18'} + + '@nomicfoundation/edr@0.11.0': + resolution: {integrity: sha512-36WERf8ldvyHR6UAbcYsa+vpbW7tCrJGBwF4gXSsb8+STj1n66Hz85Y/O7B9+8AauX3PhglvV5dKl91tk43mWw==} + engines: {node: '>= 18'} + + '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2': + resolution: {integrity: sha512-JaqcWPDZENCvm++lFFGjrDd8mxtf+CtLd2MiXvMNTBD33dContTZ9TWETwNFwg7JTJT5Q9HEecH7FA+HTSsIUw==} + engines: {node: '>= 12'} + + '@nomicfoundation/solidity-analyzer-darwin-x64@0.1.2': + resolution: {integrity: sha512-fZNmVztrSXC03e9RONBT+CiksSeYcxI1wlzqyr0L7hsQlK1fzV+f04g2JtQ1c/Fe74ZwdV6aQBdd6Uwl1052sw==} + engines: {node: '>= 12'} + + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.2': + resolution: {integrity: sha512-3d54oc+9ZVBuB6nbp8wHylk4xh0N0Gc+bk+/uJae+rUgbOBwQSfuGIbAZt1wBXs5REkSmynEGcqx6DutoK0tPA==} + engines: {node: '>= 12'} + + '@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.2': + resolution: {integrity: sha512-iDJfR2qf55vgsg7BtJa7iPiFAsYf2d0Tv/0B+vhtnI16+wfQeTbP7teookbGvAo0eJo7aLLm0xfS/GTkvHIucA==} + engines: {node: '>= 12'} + + '@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.2': + resolution: {integrity: sha512-9dlHMAt5/2cpWyuJ9fQNOUXFB/vgSFORg1jpjX1Mh9hJ/MfZXlDdHQ+DpFCs32Zk5pxRBb07yGvSHk9/fezL+g==} + engines: {node: '>= 12'} + + '@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.2': + resolution: {integrity: sha512-GzzVeeJob3lfrSlDKQw2bRJ8rBf6mEYaWY+gW0JnTDHINA0s2gPR4km5RLIj1xeZZOYz4zRw+AEeYgLRqB2NXg==} + engines: {node: '>= 12'} + + '@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.2': + resolution: {integrity: sha512-Fdjli4DCcFHb4Zgsz0uEJXZ2K7VEO+w5KVv7HmT7WO10iODdU9csC2az4jrhEsRtiR9Gfd74FlG0NYlw1BMdyA==} + engines: {node: '>= 12'} + + '@nomicfoundation/solidity-analyzer@0.1.2': + resolution: {integrity: sha512-q4n32/FNKIhQ3zQGGw5CvPF6GTvDCpYwIf7bEY/dZTZbgfDsHyjJwURxUJf3VQuuJj+fDIFl4+KkBVbw4Ef6jA==} + engines: {node: '>= 12'} + + '@nomiclabs/truffle-contract@4.5.10': + resolution: {integrity: sha512-nF/6InFV+0hUvutyFgsdOMCoYlr//2fJbRER4itxYtQtc4/O1biTwZIKRu+5l2J5Sq6LU2WX7vZHtDgQdhWxIQ==} + peerDependencies: + web3: ^1.2.1 + web3-core-helpers: ^1.2.1 + web3-core-promievent: ^1.2.1 + web3-eth-abi: ^1.2.1 + web3-utils: ^1.2.1 + + '@open-rpc/meta-schema@1.14.9': + resolution: {integrity: sha512-2/CbDzOVpcaSnMs28TsRv8MKJwJi0TTYFlQ6q6qobAH26oIuhYgcZooKf4l71emgntU6MMcFQCA0h4mJ4dBCdA==} + + '@open-rpc/schema-utils-js@2.0.2': + resolution: {integrity: sha512-0Fb8zx09Ijt8yZB5Cd1dXpjZmWjTlxzQP/B2x5CXpbs1z9Pu0E//GV0Ncp6uBMlovPvMc7ohWWyLKNwJzZMA8Q==} + + '@open-rpc/typings@1.12.4': + resolution: {integrity: sha512-WadzXP6rXSQT51BgsmVT5OVxWS9+DWSsn8ebhtFBKb60Z3S8KA0wo5wiM7AQIrhNb4qfcQqk6HpYo6Fmpum4ew==} + hasBin: true + + '@pnpm/config.env-replace@1.1.0': + resolution: {integrity: sha512-htyl8TWnKL7K/ESFa1oW2UB5lVDxuF5DpM7tBi6Hu2LNL3mWkIzNLG6N4zoCUP1lCKNxWy/3iu8mS8MvToGd6w==} + engines: {node: '>=12.22.0'} + + '@pnpm/network.ca-file@1.0.2': + resolution: {integrity: sha512-YcPQ8a0jwYU9bTdJDpXjMi7Brhkr1mXsXrUJvjqM2mQDgkRiz8jFaQGOdaLxgjtUfQgZhKy/O3cG/YwmgKaxLA==} + engines: {node: '>=12.22.0'} + + '@pnpm/npm-conf@2.3.1': + resolution: {integrity: sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==} + engines: {node: '>=12'} + + '@remix-run/router@1.6.0': + resolution: {integrity: sha512-N13NRw3T2+6Xi9J//3CGLsK2OqC8NMme3d/YX+nh05K9YHWGcv8DycHJrqGScSP4T75o8IN6nqIMhVFU8ohg8w==} + engines: {node: '>=14'} + + '@rollup/rollup-android-arm-eabi@4.39.0': + resolution: {integrity: sha512-lGVys55Qb00Wvh8DMAocp5kIcaNzEFTmGhfFd88LfaogYTRKrdxgtlO5H6S49v2Nd8R2C6wLOal0qv6/kCkOwA==} + cpu: [arm] + os: [android] + + '@rollup/rollup-android-arm64@4.39.0': + resolution: {integrity: sha512-It9+M1zE31KWfqh/0cJLrrsCPiF72PoJjIChLX+rEcujVRCb4NLQ5QzFkzIZW8Kn8FTbvGQBY5TkKBau3S8cCQ==} + cpu: [arm64] + os: [android] + + '@rollup/rollup-darwin-arm64@4.39.0': + resolution: {integrity: sha512-lXQnhpFDOKDXiGxsU9/l8UEGGM65comrQuZ+lDcGUx+9YQ9dKpF3rSEGepyeR5AHZ0b5RgiligsBhWZfSSQh8Q==} + cpu: [arm64] + os: [darwin] + + '@rollup/rollup-darwin-x64@4.39.0': + resolution: {integrity: sha512-mKXpNZLvtEbgu6WCkNij7CGycdw9cJi2k9v0noMb++Vab12GZjFgUXD69ilAbBh034Zwn95c2PNSz9xM7KYEAQ==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.39.0': + resolution: {integrity: sha512-jivRRlh2Lod/KvDZx2zUR+I4iBfHcu2V/BA2vasUtdtTN2Uk3jfcZczLa81ESHZHPHy4ih3T/W5rPFZ/hX7RtQ==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.39.0': + resolution: {integrity: sha512-8RXIWvYIRK9nO+bhVz8DwLBepcptw633gv/QT4015CpJ0Ht8punmoHU/DuEd3iw9Hr8UwUV+t+VNNuZIWYeY7Q==} + cpu: [x64] + os: [freebsd] + + '@rollup/rollup-linux-arm-gnueabihf@4.39.0': + resolution: {integrity: sha512-mz5POx5Zu58f2xAG5RaRRhp3IZDK7zXGk5sdEDj4o96HeaXhlUwmLFzNlc4hCQi5sGdR12VDgEUqVSHer0lI9g==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm-musleabihf@4.39.0': + resolution: {integrity: sha512-+YDwhM6gUAyakl0CD+bMFpdmwIoRDzZYaTWV3SDRBGkMU/VpIBYXXEvkEcTagw/7VVkL2vA29zU4UVy1mP0/Yw==} + cpu: [arm] + os: [linux] + + '@rollup/rollup-linux-arm64-gnu@4.39.0': + resolution: {integrity: sha512-EKf7iF7aK36eEChvlgxGnk7pdJfzfQbNvGV/+l98iiMwU23MwvmV0Ty3pJ0p5WQfm3JRHOytSIqD9LB7Bq7xdQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-arm64-musl@4.39.0': + resolution: {integrity: sha512-vYanR6MtqC7Z2SNr8gzVnzUul09Wi1kZqJaek3KcIlI/wq5Xtq4ZPIZ0Mr/st/sv/NnaPwy/D4yXg5x0B3aUUA==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loongarch64-gnu@4.39.0': + resolution: {integrity: sha512-NMRUT40+h0FBa5fb+cpxtZoGAggRem16ocVKIv5gDB5uLDgBIwrIsXlGqYbLwW8YyO3WVTk1FkFDjMETYlDqiw==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': + resolution: {integrity: sha512-0pCNnmxgduJ3YRt+D+kJ6Ai/r+TaePu9ZLENl+ZDV/CdVczXl95CbIiwwswu4L+K7uOIGf6tMo2vm8uadRaICQ==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-riscv64-gnu@4.39.0': + resolution: {integrity: sha512-t7j5Zhr7S4bBtksT73bO6c3Qa2AV/HqiGlj9+KB3gNF5upcVkx+HLgxTm8DK4OkzsOYqbdqbLKwvGMhylJCPhQ==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.39.0': + resolution: {integrity: sha512-m6cwI86IvQ7M93MQ2RF5SP8tUjD39Y7rjb1qjHgYh28uAPVU8+k/xYWvxRO3/tBN2pZkSMa5RjnPuUIbrwVxeA==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-s390x-gnu@4.39.0': + resolution: {integrity: sha512-iRDJd2ebMunnk2rsSBYlsptCyuINvxUfGwOUldjv5M4tpa93K8tFMeYGpNk2+Nxl+OBJnBzy2/JCscGeO507kA==} + cpu: [s390x] + os: [linux] + + '@rollup/rollup-linux-x64-gnu@4.39.0': + resolution: {integrity: sha512-t9jqYw27R6Lx0XKfEFe5vUeEJ5pF3SGIM6gTfONSMb7DuG6z6wfj2yjcoZxHg129veTqU7+wOhY6GX8wmf90dA==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-linux-x64-musl@4.39.0': + resolution: {integrity: sha512-ThFdkrFDP55AIsIZDKSBWEt/JcWlCzydbZHinZ0F/r1h83qbGeenCt/G/wG2O0reuENDD2tawfAj2s8VK7Bugg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-win32-arm64-msvc@4.39.0': + resolution: {integrity: sha512-jDrLm6yUtbOg2TYB3sBF3acUnAwsIksEYjLeHL+TJv9jg+TmTwdyjnDex27jqEMakNKf3RwwPahDIt7QXCSqRQ==} + cpu: [arm64] + os: [win32] + + '@rollup/rollup-win32-ia32-msvc@4.39.0': + resolution: {integrity: sha512-6w9uMuza+LbLCVoNKL5FSLE7yvYkq9laSd09bwS0tMjkwXrmib/4KmoJcrKhLWHvw19mwU+33ndC69T7weNNjQ==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-msvc@4.39.0': + resolution: {integrity: sha512-yAkUOkIKZlK5dl7u6dg897doBgLXmUHhIINM2c+sND3DZwnrdQkkSiDh7N75Ll4mM4dxSkYfXqU9fW3lLkMFug==} + cpu: [x64] + os: [win32] + + '@rushstack/node-core-library@3.66.0': + resolution: {integrity: sha512-nXyddNe3T9Ph14TrIfjtLZ+GDzC7HL/wF+ZKC18qmRVtz2xXLd1ZzreVgiAgGDwn8ZUWZ/7q//gQJk96iWjSrg==} + peerDependencies: + '@types/node': '*' + peerDependenciesMeta: + '@types/node': + optional: true + + '@rushstack/rig-package@0.5.1': + resolution: {integrity: sha512-pXRYSe29TjRw7rqxD4WS3HN/sRSbfr+tJs4a9uuaSIBAITbUggygdhuG0VrO0EO+QqH91GhYMN4S6KRtOEmGVA==} + + '@rushstack/ts-command-line@4.17.1': + resolution: {integrity: sha512-2jweO1O57BYP5qdBGl6apJLB+aRIn5ccIRTPDyULh0KMwVzFqWtw6IZWt1qtUoZD/pD2RNkIOosH6Cq45rIYeg==} + + '@scure/base@1.1.9': + resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==} + + '@scure/base@1.2.4': + resolution: {integrity: sha512-5Yy9czTO47mqz+/J8GM6GIId4umdCk1wc1q8rKERQulIoc8VP9pzDcghv10Tl2E7R96ZUx/PhND3ESYUQX8NuQ==} + + '@scure/bip32@1.1.5': + resolution: {integrity: sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw==} + + '@scure/bip32@1.4.0': + resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} + + '@scure/bip32@1.5.0': + resolution: {integrity: sha512-8EnFYkqEQdnkuGBVpCzKxyIwDCBLDVj3oiX0EKUFre/tOjL/Hqba1D6n/8RcmaQy4f95qQFrO2A8Sr6ybh4NRw==} + + '@scure/bip39@1.1.1': + resolution: {integrity: sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg==} + + '@scure/bip39@1.3.0': + resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + + '@scure/bip39@1.4.0': + resolution: {integrity: sha512-BEEm6p8IueV/ZTfQLp/0vhw4NPnT9oWf5+28nvmeUICjP99f4vr2d+qc7AVGDDtwRep6ifR43Yed9ERVmiITzw==} + + '@sentry/core@5.30.0': + resolution: {integrity: sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg==} + engines: {node: '>=6'} + + '@sentry/hub@5.30.0': + resolution: {integrity: sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ==} + engines: {node: '>=6'} + + '@sentry/minimal@5.30.0': + resolution: {integrity: sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw==} + engines: {node: '>=6'} + + '@sentry/node@5.30.0': + resolution: {integrity: sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg==} + engines: {node: '>=6'} + + '@sentry/tracing@5.30.0': + resolution: {integrity: sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw==} + engines: {node: '>=6'} + + '@sentry/types@5.30.0': + resolution: {integrity: sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw==} + engines: {node: '>=6'} + + '@sentry/utils@5.30.0': + resolution: {integrity: sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww==} + engines: {node: '>=6'} + + '@sinclair/typebox@0.27.8': + resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} + + '@sindresorhus/is@4.6.0': + resolution: {integrity: sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==} + engines: {node: '>=10'} + + '@sindresorhus/is@5.6.0': + resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} + engines: {node: '>=14.16'} + + '@sinonjs/commons@1.8.6': + resolution: {integrity: sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==} + + '@sinonjs/commons@2.0.0': + resolution: {integrity: sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==} + + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@11.3.1': + resolution: {integrity: sha512-EVJO7nW5M/F5Tur0Rf2z/QoMo+1Ia963RiMtapiQrEWvY0iBUvADo8Beegwjpnle5BHkyHuoxSTW3jF43H1XRA==} + + '@sinonjs/fake-timers@6.0.1': + resolution: {integrity: sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==} + + '@sinonjs/fake-timers@9.1.2': + resolution: {integrity: sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==} + + '@sinonjs/samsam@5.3.1': + resolution: {integrity: sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==} + + '@sinonjs/samsam@7.0.1': + resolution: {integrity: sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==} + + '@sinonjs/text-encoding@0.7.3': + resolution: {integrity: sha512-DE427ROAphMQzU4ENbliGYrBSYPXF+TtLg9S8vzeA+OF4ZKzoDdzfL8sxuMUGS/lgRhM6j1URSk9ghf7Xo1tyA==} + + '@solidity-parser/parser@0.14.5': + resolution: {integrity: sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg==} + + '@solidity-parser/parser@0.18.0': + resolution: {integrity: sha512-yfORGUIPgLck41qyN7nbwJRAx17/jAIXCTanHOJZhB6PJ1iAk/84b/xlsVKFSyNyLXIj0dhppoE0+CRws7wlzA==} + + '@szmarczak/http-timer@4.0.6': + resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} + engines: {node: '>=10'} + + '@szmarczak/http-timer@5.0.1': + resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} + engines: {node: '>=14.16'} + + '@truffle/abi-utils@1.0.3': + resolution: {integrity: sha512-AWhs01HCShaVKjml7Z4AbVREr/u4oiWxCcoR7Cktm0mEvtT04pvnxW5xB/cI4znRkrbPdFQlFt67kgrAjesYkw==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/blockchain-utils@0.1.9': + resolution: {integrity: sha512-RHfumgbIVo68Rv9ofDYfynjnYZIfP/f1vZy4RoqkfYAO+fqfc58PDRzB1WAGq2U6GPuOnipOJxQhnqNnffORZg==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/codec@0.17.3': + resolution: {integrity: sha512-Ko/+dsnntNyrJa57jUD9u4qx9nQby+H4GsUO6yjiCPSX0TQnEHK08XWqBSg0WdmCH2+h0y1nr2CXSx8gbZapxg==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/compile-common@0.9.8': + resolution: {integrity: sha512-DTpiyo32t/YhLI1spn84D3MHYHrnoVqO+Gp7ZHrYNwDs86mAxtNiH5lsVzSb8cPgiqlvNsRCU9nm9R0YmKMTBQ==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/contract-schema@3.4.16': + resolution: {integrity: sha512-g0WNYR/J327DqtJPI70ubS19K1Fth/1wxt2jFqLsPmz5cGZVjCwuhiie+LfBde4/Mc9QR8G+L3wtmT5cyoBxAg==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/debug-utils@6.0.57': + resolution: {integrity: sha512-Q6oI7zLaeNLB69ixjwZk2UZEWBY6b2OD1sjLMGDKBGR7GaHYiw96GLR2PFgPH1uwEeLmV4N78LYaQCrDsHbNeA==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/error@0.1.1': + resolution: {integrity: sha512-sE7c9IHIGdbK4YayH4BC8i8qMjoAOeg6nUXUDZZp8wlU21/EMpaG+CLx+KqcIPyR+GSWIW3Dm0PXkr2nlggFDA==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/error@0.2.2': + resolution: {integrity: sha512-TqbzJ0O8DHh34cu8gDujnYl4dUl6o2DE4PR6iokbybvnIm/L2xl6+Gv1VC+YJS45xfH83Yo3/Zyg/9Oq8/xZWg==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@truffle/interface-adapter@0.5.37': + resolution: {integrity: sha512-lPH9MDgU+7sNDlJSClwyOwPCfuOimqsCx0HfGkznL3mcFRymc1pukAR1k17zn7ErHqBwJjiKAZ6Ri72KkS+IWw==} + engines: {node: ^16.20 || ^18.16 || >=20} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + '@trufflesuite/chromafi@3.0.0': + resolution: {integrity: sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ==} + + '@tsconfig/node10@1.0.11': + resolution: {integrity: sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==} + + '@tsconfig/node12@1.0.11': + resolution: {integrity: sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==} + + '@tsconfig/node14@1.0.3': + resolution: {integrity: sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==} + + '@tsconfig/node16@1.0.4': + resolution: {integrity: sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==} + + '@typechain/ethers-v6@0.5.1': + resolution: {integrity: sha512-F+GklO8jBWlsaVV+9oHaPh5NJdd6rAKN4tklGfInX1Q7h0xPgVLP39Jl3eCulPB5qexI71ZFHwbljx4ZXNfouA==} + peerDependencies: + ethers: 6.x + typechain: ^8.3.2 + typescript: '>=4.7.0' + + '@typechain/hardhat@9.1.0': + resolution: {integrity: sha512-mtaUlzLlkqTlfPwB3FORdejqBskSnh+Jl8AIJGjXNAQfRQ4ofHADPl1+oU7Z3pAJzmZbUXII8MhOLQltcHgKnA==} + peerDependencies: + '@typechain/ethers-v6': ^0.5.1 + ethers: ^6.1.0 + hardhat: ^2.9.9 + typechain: ^8.3.2 + + '@types/argparse@1.0.38': + resolution: {integrity: sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==} + + '@types/async-eventemitter@0.2.4': + resolution: {integrity: sha512-2Bq61VD01kgLf1XkK2xPtoBcu7fgn/km5JyEX9v0BlG5VQBzA+BlF9umFk+8gR8S4+eK7MgDY2oyVZCu6ar3Jw==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.6.8': + resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.20.6': + resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==} + + '@types/bn.js@4.11.6': + resolution: {integrity: sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg==} + + '@types/bn.js@5.1.6': + resolution: {integrity: sha512-Xh8vSwUeMKeYYrj3cX4lGQgFSF/N03r+tv4AiLl1SucqV+uTQpxRcnM8AkXKHwYP9ZPXOYXRr2KPXpVlIvqh9w==} + + '@types/cacheable-request@6.0.3': + resolution: {integrity: sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==} + + '@types/chai-as-promised@7.1.8': + resolution: {integrity: sha512-ThlRVIJhr69FLlh6IctTXFkmhtP3NpMZ2QGq69StYLyKZFp/HOp1VdKZj7RvfNWYYcJ1xlbLGLLWj1UvP5u/Gw==} + + '@types/chai@4.3.20': + resolution: {integrity: sha512-/pC9HAB5I/xMlc5FP77qjCnI16ChlJfW0tGa0IUcFn38VJrTV6DeZ60NU5KZBtaOZqjdpwTWohz5HU1RrhiYxQ==} + + '@types/ci-info@2.0.0': + resolution: {integrity: sha512-5R2/MHILQLDCzTuhs1j4Qqq8AaKUf7Ma4KSSkCtc12+fMs47zfa34qhto9goxpyX00tQK1zxB885VCiawZ5Qhg==} + + '@types/concat-stream@1.6.1': + resolution: {integrity: sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==} + + '@types/d3-scale-chromatic@3.1.0': + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} + + '@types/d3-scale@4.0.8': + resolution: {integrity: sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/debug@4.1.12': + resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + + '@types/estree@1.0.7': + resolution: {integrity: sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==} + + '@types/events@3.0.3': + resolution: {integrity: sha512-trOc4AAUThEz9hapPtSd7wf5tiQKvTtu5b371UxXdTuqzIh0ArcRspRP0i0Viu+LXstIQ1z96t1nsPxT9ol01g==} + + '@types/form-data@0.0.33': + resolution: {integrity: sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==} + + '@types/fs-extra@5.1.0': + resolution: {integrity: sha512-AInn5+UBFIK9FK5xc9yP5e3TQSPNNgjHByqYcj9g5elVBnDQcQL7PlO1CIRy2gWlbwK7UPYqi7vRvFA44dCmYQ==} + + '@types/fs-extra@9.0.13': + resolution: {integrity: sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==} + + '@types/glob@7.2.0': + resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + + '@types/hoist-non-react-statics@3.3.6': + resolution: {integrity: sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==} + + '@types/http-cache-semantics@4.0.4': + resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/keccak@3.0.5': + resolution: {integrity: sha512-Mvu4StIJ9KyfPXDVRv3h0fWNBAjHPBQZ8EPcxhqA8FG6pLzxtytVXU5owB6J2/8xZ+ZspWTXJEUjAHt0pk0I1Q==} + + '@types/keyv@3.1.4': + resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==} + + '@types/lodash.clonedeep@4.5.9': + resolution: {integrity: sha512-19429mWC+FyaAhOLzsS8kZUsI+/GmBAQ0HFiCPsKGU+7pBXOQWhyrY6xNNDwUSX8SMZMJvuFVMF9O5dQOlQK9Q==} + + '@types/lodash.isequal@4.5.8': + resolution: {integrity: sha512-uput6pg4E/tj2LGxCZo9+y27JNyB2OZuuI/T5F+ylVDYuqICLG2/ktjxx0v6GvVntAf8TvEzeQLcV0ffRirXuA==} + + '@types/lodash.memoize@4.1.9': + resolution: {integrity: sha512-glY1nQuoqX4Ft8Uk+KfJudOD7DQbbEDF6k9XpGncaohW3RW4eSWBlx6AA0fZCrh40tZcQNH4jS/Oc59J6Eq+aw==} + + '@types/lodash@4.17.12': + resolution: {integrity: sha512-sviUmCE8AYdaF/KIHLDJBQgeYzPBI0vf/17NaYehBJfYD1j6/L95Slh07NlyK2iNyBNaEkb3En2jRt+a8y3xZQ==} + + '@types/lru-cache@5.1.1': + resolution: {integrity: sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw==} + + '@types/mdast@3.0.15': + resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} + + '@types/minimatch@5.1.2': + resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + + '@types/mocha@10.0.9': + resolution: {integrity: sha512-sicdRoWtYevwxjOHNMPTl3vSfJM6oyW8o1wXeI7uww6b6xHg8eBznQDNSGBCDJmsE8UMxP05JgZRtsKbTqt//Q==} + + '@types/mocha@9.1.1': + resolution: {integrity: sha512-Z61JK7DKDtdKTWwLeElSEBcWGRLY8g95ic5FoQqI9CMx0ns/Ghep3B4DfcEimiKMvtamNVULVNKEsiwV3aQmXw==} + + '@types/ms@0.7.34': + resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} + + '@types/ndjson@2.0.1': + resolution: {integrity: sha512-xSRLa/CtPjEo0plSQj+nMKjVBkYh5MeMwOXa1y//jFELdmy9AmVQgWKWQgZ+/XrNlAYxXtmKR8OHaizPgEpUEw==} + + '@types/node@10.17.60': + resolution: {integrity: sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==} + + '@types/node@12.20.55': + resolution: {integrity: sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==} + + '@types/node@18.19.59': + resolution: {integrity: sha512-vizm2EqwV/7Zay+A6J3tGl9Lhr7CjZe2HmWS988sefiEmsyP9CeXEleho6i4hJk/8UtZAo0bWN4QPZZr83RxvQ==} + + '@types/node@22.7.5': + resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} + + '@types/node@8.10.66': + resolution: {integrity: sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==} + + '@types/pbkdf2@3.1.2': + resolution: {integrity: sha512-uRwJqmiXmh9++aSu1VNEn3iIxWOhd8AHXNSdlaLfdAAdSTY9jYVeGWnzejM3dvrkbqE3/hyQkQQ29IFATEGlew==} + + '@types/prettier@2.7.3': + resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} + + '@types/prompts@2.4.9': + resolution: {integrity: sha512-qTxFi6Buiu8+50/+3DGIWLHM6QuWsEKugJnnP6iv2Mc4ncxE4A/OJkjuVOA+5X0X1S/nq5VJRa8Lu+nwcvbrKA==} + + '@types/prop-types@15.7.14': + resolution: {integrity: sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==} + + '@types/qs@6.9.16': + resolution: {integrity: sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==} + + '@types/react-dom@18.3.5': + resolution: {integrity: sha512-P4t6saawp+b/dFrUr2cvkVsfvPguwsxtH6dNIYRllMsefqFzkZk5UIjzyDOv5g1dXIPdG4Sp1yCR4Z6RCUsG/Q==} + peerDependencies: + '@types/react': ^18.0.0 + + '@types/react@18.3.18': + resolution: {integrity: sha512-t4yC+vtgnkYjNSKlFx1jkAhH8LgTo2N/7Qvi83kdEaUtMDiwpbLAktKDaAMlRcJ5eSxZkH74eEGt1ky31d7kfQ==} + + '@types/resolve@1.20.6': + resolution: {integrity: sha512-A4STmOXPhMUtHH+S6ymgE2GiBSMqf4oTvcQZMcHzokuTLVYzXTB8ttjcgxOVaAp2lGwEdzZ0J+cRbbeevQj1UQ==} + + '@types/responselike@1.0.3': + resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==} + + '@types/secp256k1@4.0.6': + resolution: {integrity: sha512-hHxJU6PAEUn0TP4S/ZOzuTUvJWuZ6eIKeNKb5RBpODvSl6hp1Wrw4s7ATY50rklRCScUDpHzVA/DQdSjJ3UoYQ==} + + '@types/semver@6.2.7': + resolution: {integrity: sha512-blctEWbzUFzQx799RZjzzIdBJOXmE37YYEyDtKkx5Dg+V7o/zyyAxLPiI98A2jdTtDgxZleMdfV+7p8WbRJ1OQ==} + + '@types/semver@7.5.8': + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} + + '@types/sinon-chai@3.2.12': + resolution: {integrity: sha512-9y0Gflk3b0+NhQZ/oxGtaAJDvRywCa5sIyaVnounqLvmf93yBF4EgIRspePtkMs3Tr844nCclYMlcCNmLCvjuQ==} + + '@types/sinon@10.0.20': + resolution: {integrity: sha512-2APKKruFNCAZgx3daAyACGzWuJ028VVCUDk6o2rw/Z4PXT0ogwdV4KUegW0MwVs0Zu59auPXbbuBJHF12Sx1Eg==} + + '@types/sinon@9.0.11': + resolution: {integrity: sha512-PwP4UY33SeeVKodNE37ZlOsR9cReypbMJOhZ7BVE0lB+Hix3efCOxiJWiE5Ia+yL9Cn2Ch72EjFTRze8RZsNtg==} + + '@types/sinonjs__fake-timers@8.1.5': + resolution: {integrity: sha512-mQkU2jY8jJEF7YHjHvsQO8+3ughTL1mcnn96igfhONmR+fUPSKIkefQYpSe8bsly2Ep7oQbn/6VG5/9/0qcArQ==} + + '@types/styled-components@5.1.26': + resolution: {integrity: sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw==} + + '@types/through@0.0.33': + resolution: {integrity: sha512-HsJ+z3QuETzP3cswwtzt2vEIiHBk/dCcHGhbmG5X3ecnwFD/lPrMpliGXxSCg03L9AhrdwA4Oz/qfspkDW+xGQ==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/uuid@8.3.4': + resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} + + '@types/w3c-web-usb@1.0.10': + resolution: {integrity: sha512-CHgUI5kTc/QLMP8hODUHhge0D4vx+9UiAwIGiT0sTy/B2XpdX1U5rJt6JSISgr6ikRT7vxV9EVAFeYZqUnl1gQ==} + + '@types/ws@7.4.7': + resolution: {integrity: sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww==} + + '@types/ws@8.5.3': + resolution: {integrity: sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==} + + '@typescript-eslint/eslint-plugin@5.61.0': + resolution: {integrity: sha512-A5l/eUAug103qtkwccSCxn8ZRwT+7RXWkFECdA4Cvl1dOlDUgTpAOfSEElZn2uSUxhdDpnCdetrf0jvU4qrL+g==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/experimental-utils@5.62.0': + resolution: {integrity: sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@typescript-eslint/parser@5.61.0': + resolution: {integrity: sha512-yGr4Sgyh8uO6fSi9hw3jAFXNBHbCtKKFMdX2IkT3ZqpKmtAq3lHS4ixB/COFuAIJpwl9/AqF7j72ZDWYKmIfvg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/scope-manager@5.61.0': + resolution: {integrity: sha512-W8VoMjoSg7f7nqAROEmTt6LoBpn81AegP7uKhhW5KzYlehs8VV0ZW0fIDVbcZRcaP3aPSW+JZFua+ysQN+m/Nw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/scope-manager@5.62.0': + resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/type-utils@5.61.0': + resolution: {integrity: sha512-kk8u//r+oVK2Aj3ph/26XdH0pbAkC2RiSjUYhKD+PExemG4XSjpGFeyZ/QM8lBOa7O8aGOU+/yEbMJgQv/DnCg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/types@5.61.0': + resolution: {integrity: sha512-ldyueo58KjngXpzloHUog/h9REmHl59G1b3a5Sng1GfBo14BkS3ZbMEb3693gnP1k//97lh7bKsp6/V/0v1veQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/types@5.62.0': + resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/typescript-estree@5.61.0': + resolution: {integrity: sha512-Fud90PxONnnLZ36oR5ClJBLTLfU4pIWBmnvGwTbEa2cXIqj70AEDEmOmpkFComjBZ/037ueKrOdHuYmSFVD7Rw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/typescript-estree@5.62.0': + resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/utils@5.61.0': + resolution: {integrity: sha512-mV6O+6VgQmVE6+xzlA91xifndPW9ElFW8vbSF0xCT/czPXVhwDewKila1jOyRwa9AE19zKnrr7Cg5S3pJVrTWQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@typescript-eslint/utils@5.62.0': + resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@typescript-eslint/visitor-keys@5.61.0': + resolution: {integrity: sha512-50XQ5VdbWrX06mQXhy93WywSFZZGsv3EOjq+lqp6WC2t+j3mb6A9xYVdrRxafvK88vg9k9u+CT4l6D8PEatjKg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/visitor-keys@5.62.0': + resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@ungap/promise-all-settled@1.1.2': + resolution: {integrity: sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==} + + '@ungap/structured-clone@1.2.0': + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + + '@vitejs/plugin-react@4.3.4': + resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + vite: ^4.2.0 || ^5.0.0 || ^6.0.0 + + abbrev@1.0.9: + resolution: {integrity: sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q==} + + abitype@0.7.1: + resolution: {integrity: sha512-VBkRHTDZf9Myaek/dO3yMmOzB/y2s3Zo6nVU7yaw1G+TvCHAjwaJzNGN9yo4K5D8bU/VZXKP1EJpRhFr862PlQ==} + peerDependencies: + typescript: '>=4.9.4' + zod: ^3 >=3.19.1 + peerDependenciesMeta: + zod: + optional: true + + abitype@0.9.10: + resolution: {integrity: sha512-FIS7U4n7qwAT58KibwYig5iFG4K61rbhAqaQh/UWj8v1Y8mjX3F8TC9gd8cz9yT1TYel9f8nS5NO5kZp2RW0jQ==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.0.6: + resolution: {integrity: sha512-MMSqYh4+C/aVqI2RQaWqbvI4Kxo5cQV40WQ4QFtDnNzCkqChm8MuENhElmynZlO0qUy/ObkEUaXtKqYnx1Kp3A==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abortcontroller-polyfill@1.7.5: + resolution: {integrity: sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@8.3.4: + resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} + engines: {node: '>=0.4.0'} + + acorn@8.13.0: + resolution: {integrity: sha512-8zSiw54Oxrdym50NlZ9sUusyO1Z1ZchgRLWRaK6c86XJFClyCgFKetdowBg5bKxyp/u+CDBJG4Mpp0m3HLZl9w==} + engines: {node: '>=0.4.0'} + hasBin: true + + address@1.2.2: + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} + + adm-zip@0.4.16: + resolution: {integrity: sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg==} + engines: {node: '>=0.3.0'} + + aes-js@3.0.0: + resolution: {integrity: sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw==} + + aes-js@4.0.0-beta.5: + resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + ajv@5.5.2: + resolution: {integrity: sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw==} + + ajv@6.12.6: + resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + + ajv@8.17.1: + resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} + + amdefine@1.0.1: + resolution: {integrity: sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg==} + engines: {node: '>=0.4.2'} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-colors@4.1.1: + resolution: {integrity: sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==} + engines: {node: '>=6'} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-regex@2.1.1: + resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} + engines: {node: '>=0.10.0'} + + ansi-regex@3.0.1: + resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} + engines: {node: '>=4'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-styles@1.0.0: + resolution: {integrity: sha512-3iF4FIKdxaVYT3JqQuY3Wat/T2t7TRbbQ94Fu50ZUCbLy4TFbTzr90NOHQodQkNqmeEGCw8WbeP78WNi6SKYUA==} + engines: {node: '>=0.8.0'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + antlr4@4.13.2: + resolution: {integrity: sha512-QiVbZhyy4xAZ17UPEuG3YTOt8ZaoeOR1CvEAqrEsDBsOqINslaB147i9xqljZqoyf5S+EUlGStaj+t22LT9MOg==} + engines: {node: '>=16'} + + antlr4@4.8.0: + resolution: {integrity: sha512-en/MxQ4OkPgGJQ3wD/muzj1uDnFSzdFIhc2+c6bHZokWkuBb6RRvFjpWhPxWLbgQvaEzldJZ0GSQpfSAaE3hqg==} + + antlr4ts@0.5.0-alpha.4: + resolution: {integrity: sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ==} + + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + append-transform@2.0.0: + resolution: {integrity: sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==} + engines: {node: '>=8'} + + archy@1.0.0: + resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} + + arg@4.1.3: + resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==} + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + array-back@3.1.0: + resolution: {integrity: sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q==} + engines: {node: '>=6'} + + array-back@4.0.2: + resolution: {integrity: sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg==} + engines: {node: '>=8'} + + array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + array-includes@3.1.8: + resolution: {integrity: sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==} + engines: {node: '>= 0.4'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array-uniq@1.0.3: + resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} + engines: {node: '>=0.10.0'} + + array.prototype.findlastindex@1.2.5: + resolution: {integrity: sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + + asap@2.0.6: + resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} + + asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + + assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + + assertion-error@1.1.0: + resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} + + ast-parents@0.0.1: + resolution: {integrity: sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA==} + + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + + async-limiter@1.0.1: + resolution: {integrity: sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==} + + async@1.5.2: + resolution: {integrity: sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + aws-sign2@0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + + aws4@1.13.2: + resolution: {integrity: sha512-lHe62zvbTB5eEABUVi/AwVh0ZKY9rMMDhmm+eeyuuUQbQ3+J+fONVQOZyj+DdrvD4BY33uYniyRJ4UJIaSKAfw==} + + axios@0.21.4: + resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} + + axios@1.7.7: + resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} + + babel-plugin-styled-components@2.1.4: + resolution: {integrity: sha512-Xgp9g+A/cG47sUyRwwYxGM4bR/jDRg5N6it/8+HxCnbT5XNKSKDT9xm4oag/osgqjC2It/vH0yXsomOG6k558g==} + peerDependencies: + styled-components: '>= 2' + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + base-x@3.0.10: + resolution: {integrity: sha512-7d0s06rR9rYaIWHkpfLIFICM/tkSVdoPC9qYAQRpxn9DdKNWNsKC0uk++akckyLq16Tx2WIinnZ6WRriAt6njQ==} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + + bech32@1.1.4: + resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} + + better-path-resolve@1.0.0: + resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} + engines: {node: '>=4'} + + big-integer@1.6.36: + resolution: {integrity: sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg==} + engines: {node: '>=0.6'} + + big.js@6.2.2: + resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + + bignumber.js@7.2.1: + resolution: {integrity: sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==} + + bignumber.js@9.1.2: + resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + + bignumber.js@9.2.1: + resolution: {integrity: sha512-+NzaKgOUvInq9TIUZ1+DRspzf/HApkCwD4btfuasFTdrfnOxqx853TgDpMolp+uv4RpRp7bPcEU2zKr9+fRmyw==} + + bignumber.js@https://codeload.github.com/frozeman/bignumber.js-nolookahead/tar.gz/57692b3ecfc98bbdd6b3a516cb2353652ea49934: + resolution: {tarball: https://codeload.github.com/frozeman/bignumber.js-nolookahead/tar.gz/57692b3ecfc98bbdd6b3a516cb2353652ea49934} + version: 2.0.7 + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + blakejs@1.2.1: + resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} + + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + bn-str-256@1.9.1: + resolution: {integrity: sha512-u3muv3WO5sYv9nUQsPnDGLg731yNt/MOlKPK5pmBVqClcl7tY97tyfKxw8ed44HVrpi+7dkgJgQpbXP47a3GoQ==} + + bn.js@4.11.6: + resolution: {integrity: sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA==} + + bn.js@4.12.0: + resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} + + bn.js@5.2.1: + resolution: {integrity: sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==} + + body-parser@1.20.3: + resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + boolean@3.2.0: + resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + boxen@5.1.2: + resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} + engines: {node: '>=10'} + + brace-expansion@1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + + brace-expansion@2.0.1: + resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + + browserify-aes@1.2.0: + resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} + + browserslist@4.24.2: + resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + + bs58check@2.1.2: + resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer-to-arraybuffer@0.0.5: + resolution: {integrity: sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ==} + + buffer-xor@1.0.3: + resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + bufferutil@4.0.8: + resolution: {integrity: sha512-4T53u4PdgsXqKaIctwF8ifXlRTTmEPJ8iEPWFdGZvcf7sbwYo6FKFEX9eNNAnzFZ7EzJAQ3CJeOtCRA4rDp7Pw==} + engines: {node: '>=6.14.2'} + + builtin-modules@3.3.0: + resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} + engines: {node: '>=6'} + + builtins@5.1.0: + resolution: {integrity: sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + cacheable-lookup@5.0.4: + resolution: {integrity: sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==} + engines: {node: '>=10.6.0'} + + cacheable-lookup@6.1.0: + resolution: {integrity: sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww==} + engines: {node: '>=10.6.0'} + + cacheable-lookup@7.0.0: + resolution: {integrity: sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==} + engines: {node: '>=14.16'} + + cacheable-request@10.2.14: + resolution: {integrity: sha512-zkDT5WAF4hSSoUgyfg5tFIxz8XQK+25W/TLVojJTMKBaxevLBBtLxgqguAuVQB8PVW79FVjHcU+GJ9tVbDZ9mQ==} + engines: {node: '>=14.16'} + + cacheable-request@7.0.4: + resolution: {integrity: sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==} + engines: {node: '>=8'} + + caching-transform@4.0.0: + resolution: {integrity: sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==} + engines: {node: '>=8'} + + call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camel-case@3.0.0: + resolution: {integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==} + + camelcase@3.0.0: + resolution: {integrity: sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==} + engines: {node: '>=0.10.0'} + + camelcase@4.1.0: + resolution: {integrity: sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==} + engines: {node: '>=4'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + camelize@1.0.1: + resolution: {integrity: sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==} + + caniuse-lite@1.0.30001669: + resolution: {integrity: sha512-DlWzFDJqstqtIVx1zeSpIMLjunf5SmwOw0N2Ck/QSQdS8PLS4+9HrLaYei4w8BIAL7IB/UEDu889d8vhCTPA0w==} + + caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + + cbor@5.2.0: + resolution: {integrity: sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A==} + engines: {node: '>=6.0.0'} + + cbor@8.1.0: + resolution: {integrity: sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==} + engines: {node: '>=12.19'} + + cbor@9.0.2: + resolution: {integrity: sha512-JPypkxsB10s9QOWwa6zwPzqE1Md3vqpPc+cai4sAecuCsRyAtAl/pMyhPlMbT/xtPnm2dznJZYRLui57qiRhaQ==} + engines: {node: '>=16'} + + chai-as-promised@7.1.1: + resolution: {integrity: sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==} + peerDependencies: + chai: '>= 2.1.2 < 5' + + chai-as-promised@7.1.2: + resolution: {integrity: sha512-aBDHZxRzYnUYuIAIPBH2s511DjlKPzXNlXSGFC8CwmroWQLfrW0LtE1nK3MAwwNhJPa9raEjNCmRoFpG0Hurdw==} + peerDependencies: + chai: '>= 2.1.2 < 6' + + chai@4.5.0: + resolution: {integrity: sha512-RITGBfijLkBddZvnn8jdqoTypxvqbOLYQkGGxXzeFjVHvudaPw0HNFD9x928/eUwYWd2dPCugVqspGALTZZQKw==} + engines: {node: '>=4'} + + chalk@0.4.0: + resolution: {integrity: sha512-sQfYDlfv2DGVtjdoQqxS0cEZDroyG8h6TamA6rvxwlrU5BaSLDx9xhatBYl2pxZ7gmpNaPFVwBtdGdu5rQ+tYQ==} + engines: {node: '>=0.8.0'} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + change-case@3.0.2: + resolution: {integrity: sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + + charenc@0.0.2: + resolution: {integrity: sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==} + + check-error@1.0.3: + resolution: {integrity: sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==} + + cheerio-select@2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + + cheerio@1.0.0: + resolution: {integrity: sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==} + engines: {node: '>=18.17'} + + chokidar@3.5.3: + resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} + engines: {node: '>= 8.10.0'} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@4.0.1: + resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} + engines: {node: '>= 14.16.0'} + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + + ci-info@2.0.0: + resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + cids@0.7.5: + resolution: {integrity: sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA==} + engines: {node: '>=4.0.0', npm: '>=3.0.0'} + deprecated: This module has been superseded by the multiformats module + + cipher-base@1.0.4: + resolution: {integrity: sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==} + + class-is@1.1.0: + resolution: {integrity: sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==} + + classnames@2.5.1: + resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + cli-boxes@2.2.1: + resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} + engines: {node: '>=6'} + + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-table3@0.5.1: + resolution: {integrity: sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw==} + engines: {node: '>=6'} + + cliui@3.2.0: + resolution: {integrity: sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==} + + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + clone-response@1.0.3: + resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + code-point-at@1.1.0: + resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} + engines: {node: '>=0.10.0'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + colors@1.2.5: + resolution: {integrity: sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==} + engines: {node: '>=0.1.90'} + + colors@1.4.0: + resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} + engines: {node: '>=0.1.90'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + command-exists@1.2.9: + resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} + + command-line-args@5.2.1: + resolution: {integrity: sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg==} + engines: {node: '>=4.0.0'} + + command-line-usage@6.1.3: + resolution: {integrity: sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw==} + engines: {node: '>=8.0.0'} + + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + + config-chain@1.1.13: + resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} + + constant-case@2.0.0: + resolution: {integrity: sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-hash@2.5.2: + resolution: {integrity: sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw==} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + + cookie@0.4.2: + resolution: {integrity: sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==} + engines: {node: '>= 0.6'} + + cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + engines: {node: '>= 0.6'} + + cookiejar@2.1.4: + resolution: {integrity: sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==} + + core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cors@2.8.5: + resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} + engines: {node: '>= 0.10'} + + cose-base@1.0.3: + resolution: {integrity: sha512-s9whTXInMSgAp/NVXVNuVxVKzGH2qck3aQlVHxDCdAEPgtMKwc4Wq6/QKhgdEdgbLSi9rBTAcPoRa6JpiG4ksg==} + + cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + + create-hash@1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + + create-hmac@1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + + create-require@1.1.1: + resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} + + cross-fetch@3.1.8: + resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} + + cross-fetch@4.0.0: + resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} + + cross-spawn@5.1.0: + resolution: {integrity: sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==} + + cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + + crypt@0.0.2: + resolution: {integrity: sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==} + + crypto-addr-codec@0.1.8: + resolution: {integrity: sha512-GqAK90iLLgP3FvhNmHbpT3wR6dEdaM8hZyZtLX29SPardh3OA13RFLHDR6sntGCgRWOfiHqW6sIyohpNqOtV/g==} + + crypto-js@3.3.0: + resolution: {integrity: sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q==} + + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + + css-color-keywords@1.0.0: + resolution: {integrity: sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==} + engines: {node: '>=4'} + + css-select@5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + + css-to-react-native@3.2.0: + resolution: {integrity: sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==} + + css-what@6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + + csstype@3.1.3: + resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} + + cytoscape-cose-bilkent@4.1.0: + resolution: {integrity: sha512-wgQlVIUJF13Quxiv5e1gstZ08rnZj2XaLHGoFMYXz7SkNfCDOOteKBE6SYRfA9WxxI/iBc3ajfDoc6hb/MRAHQ==} + peerDependencies: + cytoscape: ^3.2.0 + + cytoscape@3.31.0: + resolution: {integrity: sha512-zDGn1K/tfZwEnoGOcHc0H4XazqAAXAuDpcYw9mUnUjATjqljyCNGJv8uEvbvxGaGHaVshxMecyl6oc6uKzRfbw==} + engines: {node: '>=0.10'} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-axis@3.0.0: + resolution: {integrity: sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==} + engines: {node: '>=12'} + + d3-brush@3.0.0: + resolution: {integrity: sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==} + engines: {node: '>=12'} + + d3-chord@3.0.1: + resolution: {integrity: sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-contour@4.0.2: + resolution: {integrity: sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-dispatch@3.0.1: + resolution: {integrity: sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==} + engines: {node: '>=12'} + + d3-drag@3.0.0: + resolution: {integrity: sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==} + engines: {node: '>=12'} + + d3-dsv@3.0.1: + resolution: {integrity: sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==} + engines: {node: '>=12'} + hasBin: true + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-fetch@3.0.1: + resolution: {integrity: sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==} + engines: {node: '>=12'} + + d3-force@3.0.0: + resolution: {integrity: sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==} + engines: {node: '>=12'} + + d3-format@3.1.0: + resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==} + engines: {node: '>=12'} + + d3-geo@3.1.1: + resolution: {integrity: sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==} + engines: {node: '>=12'} + + d3-hierarchy@3.1.2: + resolution: {integrity: sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==} + engines: {node: '>=12'} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@1.0.9: + resolution: {integrity: sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-polygon@3.0.1: + resolution: {integrity: sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==} + engines: {node: '>=12'} + + d3-quadtree@3.0.1: + resolution: {integrity: sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==} + engines: {node: '>=12'} + + d3-random@3.0.1: + resolution: {integrity: sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==} + engines: {node: '>=12'} + + d3-sankey@0.12.3: + resolution: {integrity: sha512-nQhsBRmM19Ax5xEIPLMY9ZmJ/cDvd1BG3UVvt5h3WRxKg5zGRbvnteTyWAbzeSvlh3tW7ZEmq4VwR5mB3tutmQ==} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-selection@3.0.0: + resolution: {integrity: sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==} + engines: {node: '>=12'} + + d3-shape@1.3.7: + resolution: {integrity: sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@4.1.0: + resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==} + engines: {node: '>=12'} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + d3-transition@3.0.1: + resolution: {integrity: sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==} + engines: {node: '>=12'} + peerDependencies: + d3-selection: 2 - 3 + + d3-zoom@3.0.0: + resolution: {integrity: sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==} + engines: {node: '>=12'} + + d3@7.9.0: + resolution: {integrity: sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==} + engines: {node: '>=12'} + + d@1.0.2: + resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} + engines: {node: '>=0.12'} + + dagre-d3-es@7.0.10: + resolution: {integrity: sha512-qTCQmEhcynucuaZgY5/+ti3X/rnszKZhEQH/ZdWdtP1tA/y3VoHJzcVrO9pjjJCNpigfscAtoUB5ONcd2wNn0A==} + + dashdash@1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} + + data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + + date-time@0.1.1: + resolution: {integrity: sha512-p4psdkgdNA6x0600SKbfWiOomNb33ADBMRHf49GMhYVgJsPefZlMSLXXVWWUpbqSxB3DL5/cxKa6a8i3XPK5Xg==} + engines: {node: '>=0.10.0'} + + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + + death@1.1.0: + resolution: {integrity: sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.3: + resolution: {integrity: sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.3.7: + resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + + decimal.js-light@2.5.1: + resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + + decode-named-character-reference@1.0.2: + resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==} + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + decompress-response@3.3.0: + resolution: {integrity: sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==} + engines: {node: '>=4'} + + decompress-response@6.0.0: + resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} + engines: {node: '>=10'} + + deep-eql@4.1.4: + resolution: {integrity: sha512-SUwdGfqdKOwxCPeVYjwSyRpJ7Z+fhpwIAtmCUdZIWZ/YP5R9WAsyuSgpLVDi9bjWoN2LXHNss/dk3urXtdQxGg==} + engines: {node: '>=6'} + + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + default-require-extensions@3.0.1: + resolution: {integrity: sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw==} + engines: {node: '>=8'} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + defer-to-connect@2.0.1: + resolution: {integrity: sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==} + engines: {node: '>=10'} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + delaunator@5.0.1: + resolution: {integrity: sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-indent@5.0.0: + resolution: {integrity: sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==} + engines: {node: '>=4'} + + detect-indent@6.1.0: + resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} + engines: {node: '>=8'} + + detect-libc@2.0.3: + resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==} + engines: {node: '>=8'} + + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + + detect-port@1.6.1: + resolution: {integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==} + engines: {node: '>= 4.0.0'} + hasBin: true + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + diff@4.0.2: + resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} + engines: {node: '>=0.3.1'} + + diff@5.0.0: + resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} + engines: {node: '>=0.3.1'} + + diff@5.2.0: + resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==} + engines: {node: '>=0.3.1'} + + difflib@0.2.4: + resolution: {integrity: sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + dom-walk@0.1.2: + resolution: {integrity: sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + dompurify@3.1.6: + resolution: {integrity: sha512-cTOAhc36AalkjtBpfG6O8JimdTMWNXjiePT2xQH/ppBGi/4uIpmj8eKyIkMJErXWARyINV/sB38yf8JCLF5pbQ==} + + domutils@3.1.0: + resolution: {integrity: sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==} + + dot-case@2.1.1: + resolution: {integrity: sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug==} + + dot-prop@7.2.0: + resolution: {integrity: sha512-Ol/IPXUARn9CSbkrdV4VJo7uCy1I3VuSiWCaFSg+8BdUOzF9n3jefIpcgAydvUZbTdEBZs2vEiTiS9m61ssiDA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + ecc-jsbn@0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + eip55@2.1.1: + resolution: {integrity: sha512-WcagVAmNu2Ww2cDUfzuWVntYwFxbvZ5MvIyLZpMjTTkjD6sCvkGOiS86jTppzu9/gWsc8isLHAeMBWK02OnZmA==} + + electron-to-chromium@1.5.45: + resolution: {integrity: sha512-vOzZS6uZwhhbkZbcRyiy99Wg+pYFV5hk+5YaECvx0+Z31NR3Tt5zS6dze2OepT6PCTzVzT0dIJItti+uAW5zmw==} + + elkjs@0.9.3: + resolution: {integrity: sha512-f/ZeWvW/BCXbhGEf1Ujp29EASo/lk1FDnETgNKwJrsVvGZhUWCZyg3xLJjAsxfOmt8KjswHmI5EwCQcPMpOYhQ==} + + elliptic@6.5.4: + resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} + + elliptic@6.5.7: + resolution: {integrity: sha512-ESVCtTwiA+XhY3wyh24QqRGBoP3rEdDUl3EDUUo9tft074fi19IrdpH7hLCMMP3CIj7jb3W96rn8lt/BqIlt5Q==} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + encodeurl@1.0.2: + resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} + engines: {node: '>= 0.8'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + encoding-sniffer@0.2.0: + resolution: {integrity: sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==} + + end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + + enhanced-resolve@5.18.0: + resolution: {integrity: sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==} + engines: {node: '>=10.13.0'} + + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + error-ex@1.3.2: + resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + + es-abstract@1.23.3: + resolution: {integrity: sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==} + engines: {node: '>= 0.4'} + + es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + + es-to-primitive@1.2.1: + resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} + engines: {node: '>= 0.4'} + + es5-ext@0.10.64: + resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} + engines: {node: '>=0.10'} + + es6-error@4.1.1: + resolution: {integrity: sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==} + + es6-iterator@2.0.3: + resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} + + es6-promise@4.2.8: + resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==} + + es6-symbol@3.1.4: + resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} + engines: {node: '>=0.12'} + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escodegen@1.8.1: + resolution: {integrity: sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A==} + engines: {node: '>=0.12.0'} + hasBin: true + + eslint-compat-utils@0.5.1: + resolution: {integrity: sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q==} + engines: {node: '>=12'} + peerDependencies: + eslint: '>=6.0.0' + + eslint-config-prettier@8.3.0: + resolution: {integrity: sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-doc-generator@1.7.1: + resolution: {integrity: sha512-i1Zjl+Xcy712SZhbceCeMVaIdhbFqY27i8d7f9gyb9P/6AQNnPA0VCWynAFVGYa0hpeR5kwUI09+GBELgC2nnA==} + engines: {node: ^14.18.0 || ^16.0.0 || >=18.0.0} + hasBin: true + peerDependencies: + eslint: '>= 7' + + eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} + + eslint-import-resolver-typescript@3.7.0: + resolution: {integrity: sha512-Vrwyi8HHxY97K5ebydMtffsWAn1SCR9eol49eCd5fJS4O1WV7PaAjbcjmbfJJSMz/t4Mal212Uz/fQZrOB8mow==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.0: + resolution: {integrity: sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-es-x@7.8.0: + resolution: {integrity: sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '>=8' + + eslint-plugin-eslint-plugin@5.5.1: + resolution: {integrity: sha512-9AmfZzcQ7QHwpzfAQpZ7xdtwHYViylmlnruCH0aV64/tuoH3igGXg91vr0e6ShLf/mrAYGqLw5LZ/gOxJeRXnw==} + engines: {node: ^14.17.0 || ^16.0.0 || >= 18.0.0} + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-import@2.27.5: + resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-import@2.29.0: + resolution: {integrity: sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-mocha@10.4.1: + resolution: {integrity: sha512-G85ALUgKaLzuEuHhoW3HVRgPTmia6njQC3qCG6CEvA8/Ja9PDZnRZOuzekMki+HaViEQXINuYsmhp5WR5/4MfA==} + engines: {node: '>=14.0.0'} + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-mocha@9.0.0: + resolution: {integrity: sha512-d7knAcQj1jPCzZf3caeBIn3BnW6ikcvfz0kSqQpwPYcVGLoJV5sz0l0OJB2LR8I7dvTDbqq1oV6ylhSgzA10zg==} + engines: {node: '>=12.0.0'} + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-n@16.6.2: + resolution: {integrity: sha512-6TyDmZ1HXoFQXnhCTUjVFULReoBPOAjpuiKELMkeP40yffI/1ZRO+d9ug/VC6fqISo2WkuIBk3cvuRPALaWlOQ==} + engines: {node: '>=16.0.0'} + peerDependencies: + eslint: '>=7.0.0' + + eslint-plugin-no-only-tests@3.1.0: + resolution: {integrity: sha512-Lf4YW/bL6Un1R6A76pRZyE1dl1vr31G/ev8UzIc/geCgFWyrKil8hVjYqWVKGB/UIGmb6Slzs9T0wNezdSVegw==} + engines: {node: '>=5.0.0'} + + eslint-plugin-prettier@3.4.0: + resolution: {integrity: sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw==} + engines: {node: '>=6.0.0'} + peerDependencies: + eslint: '>=5.0.0' + eslint-config-prettier: '*' + prettier: '>=1.13.0' + peerDependenciesMeta: + eslint-config-prettier: + optional: true + + eslint-plugin-prettier@4.0.0: + resolution: {integrity: sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==} + engines: {node: '>=6.0.0'} + peerDependencies: + eslint: '>=7.28.0' + eslint-config-prettier: '*' + prettier: '>=2.0.0' + peerDependenciesMeta: + eslint-config-prettier: + optional: true + + eslint-plugin-react-hooks@4.6.2: + resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + + eslint-plugin-react-refresh@0.3.5: + resolution: {integrity: sha512-61qNIsc7fo9Pp/mju0J83kzvLm0Bsayu7OQSLEoJxLDCBjIIyb87bkzufoOvdDxLkSlMfkF7UxomC4+eztUBSA==} + peerDependencies: + eslint: '>=7' + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-utils@3.0.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + + eslint-visitor-keys@2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + + esniff@2.0.1: + resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} + engines: {node: '>=0.10'} + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esprima@2.7.3: + resolution: {integrity: sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A==} + engines: {node: '>=0.10.0'} + hasBin: true + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.6.0: + resolution: {integrity: sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@1.9.3: + resolution: {integrity: sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA==} + engines: {node: '>=0.10.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eth-ens-namehash@2.0.8: + resolution: {integrity: sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw==} + + eth-gas-reporter@0.2.27: + resolution: {integrity: sha512-femhvoAM7wL0GcI8ozTdxfuBtBFJ9qsyIAsmKVjlWAHUbdnnXHt+lKzz/kmldM5lA9jLuNHGwuIxorNpLbR1Zw==} + peerDependencies: + '@codechecks/client': ^0.1.0 + peerDependenciesMeta: + '@codechecks/client': + optional: true + + eth-lib@0.1.29: + resolution: {integrity: sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ==} + + eth-lib@0.2.8: + resolution: {integrity: sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw==} + + ethereum-bloom-filters@1.2.0: + resolution: {integrity: sha512-28hyiE7HVsWubqhpVLVmZXFd4ITeHi+BUu05o9isf0GUpMtzBUi+8/gFrGaGYzvGAJQmJ3JKj77Mk9G98T84rA==} + + ethereum-cryptography@0.1.3: + resolution: {integrity: sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ==} + + ethereum-cryptography@1.2.0: + resolution: {integrity: sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw==} + + ethereum-cryptography@2.2.1: + resolution: {integrity: sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==} + + ethereum-ens@0.8.0: + resolution: {integrity: sha512-a8cBTF4AWw1Q1Y37V1LSCS9pRY4Mh3f8vCg5cbXCCEJ3eno1hbI/+Ccv9SZLISYpqQhaglP3Bxb/34lS4Qf7Bg==} + + ethereumjs-util@6.2.1: + resolution: {integrity: sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw==} + + ethereumjs-util@7.1.5: + resolution: {integrity: sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg==} + engines: {node: '>=10.0.0'} + + ethers@4.0.49: + resolution: {integrity: sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg==} + + ethers@5.7.2: + resolution: {integrity: sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg==} + + ethers@6.13.4: + resolution: {integrity: sha512-21YtnZVg4/zKkCQPjrDj38B1r4nQvTZLopUGMLQ1ePU2zV/joCfDC3t3iKQjWRzjjjbzR+mdAIoikeBRNkdllA==} + engines: {node: '>=14.0.0'} + + ethjs-abi@0.1.8: + resolution: {integrity: sha512-3SIJpF+LCVJrNht9OjSJ7+3B9ABZf6dEATMj1PaslL0BW547Cz6/kGyuDvvrcEBlSsbGpCWYrJX5B8OjhcAMFQ==} + engines: {node: '>=6.5.0', npm: '>=3'} + + ethjs-unit@0.1.6: + resolution: {integrity: sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw==} + engines: {node: '>=6.5.0', npm: '>=3'} + + ethjs-util@0.1.6: + resolution: {integrity: sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==} + engines: {node: '>=6.5.0', npm: '>=3'} + + event-emitter@0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + + eventemitter3@4.0.4: + resolution: {integrity: sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==} + + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + evp_bytestokey@1.0.3: + resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + + expand-template@2.0.3: + resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} + engines: {node: '>=6'} + + express@4.21.1: + resolution: {integrity: sha512-YSFlK1Ee0/GC8QaO91tHcDxJiE/X4FbpAyQWkxAvG6AXCuR65YzK8ua6D9hvi/TzUfZMpc+BwuM1IPw8fmQBiQ==} + engines: {node: '>= 0.10.0'} + + ext@1.7.0: + resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + extendable-error@0.1.7: + resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + + extsprintf@1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} + + fast-check@3.1.1: + resolution: {integrity: sha512-3vtXinVyuUKCKFKYcwXhGE6NtGWkqF8Yh3rvMZNzmwz8EPrgoc/v4pDdLHyLnCyCI5MZpZZkDEwFyXyEONOxpA==} + engines: {node: '>=8.0.0'} + + fast-deep-equal@1.1.0: + resolution: {integrity: sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-glob@3.3.2: + resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==} + engines: {node: '>=8.6.0'} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + + fast-uri@3.0.3: + resolution: {integrity: sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==} + + fastq@1.17.1: + resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + + fdir@6.3.0: + resolution: {integrity: sha512-QOnuT+BOtivR77wYvCWHfGt9s4Pz1VIMbD463vegT5MLqNXy8rYFT/lPVEqf/bhYeT6qmqrNHhsX+rWwe3rOCQ==} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@1.3.1: + resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} + engines: {node: '>= 0.8'} + + find-cache-dir@3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + + find-replace@3.0.0: + resolution: {integrity: sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ==} + engines: {node: '>=4.0.0'} + + find-up@1.1.2: + resolution: {integrity: sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==} + engines: {node: '>=0.10.0'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + flatted@3.3.1: + resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + + foreground-child@2.0.0: + resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} + engines: {node: '>=8.0.0'} + + forever-agent@0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + + form-data-encoder@1.7.1: + resolution: {integrity: sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==} + + form-data-encoder@2.1.4: + resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} + engines: {node: '>= 14.17'} + + form-data@2.3.3: + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} + engines: {node: '>= 0.12'} + + form-data@2.5.2: + resolution: {integrity: sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q==} + engines: {node: '>= 0.12'} + + form-data@4.0.1: + resolution: {integrity: sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==} + engines: {node: '>= 6'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fp-ts@1.19.3: + resolution: {integrity: sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg==} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fromentries@1.3.2: + resolution: {integrity: sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@0.30.0: + resolution: {integrity: sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA==} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs-extra@4.0.3: + resolution: {integrity: sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==} + + fs-extra@7.0.1: + resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@8.1.0: + resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} + engines: {node: '>=6 <7 || >=8'} + + fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + + fs-minipass@1.2.7: + resolution: {integrity: sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==} + + fs-readdir-recursive@1.1.0: + resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + ganache-cli@6.12.2: + resolution: {integrity: sha512-bnmwnJDBDsOWBUP8E/BExWf85TsdDEFelQSzihSJm9VChVO1SHp94YXLP5BlA4j/OTxp0wR4R1Tje9OHOuAJVw==} + deprecated: ganache-cli is now ganache; visit https://trfl.io/g7 for details + hasBin: true + bundledDependencies: + - source-map-support + - yargs + - ethereumjs-util + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@1.0.3: + resolution: {integrity: sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + + get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-port@3.2.0: + resolution: {integrity: sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==} + engines: {node: '>=4'} + + get-port@5.1.1: + resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} + engines: {node: '>=8'} + + get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.8.1: + resolution: {integrity: sha512-k9PN+cFBmaLWtVz29SkUoqU5O0slLuHJXt/2P+tMVFT+phsSGXGkp9t3rQIqdz0e+06EHNGs3oM6ZX1s2zHxRg==} + + getpass@0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + + ghost-testrpc@0.0.2: + resolution: {integrity: sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ==} + hasBin: true + + github-from-package@0.0.0: + resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob@5.0.15: + resolution: {integrity: sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@7.1.7: + resolution: {integrity: sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@7.2.0: + resolution: {integrity: sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==} + deprecated: Glob versions prior to v9 are no longer supported + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Glob versions prior to v9 are no longer supported + + global-modules@2.0.0: + resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} + engines: {node: '>=6'} + + global-prefix@3.0.0: + resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} + engines: {node: '>=6'} + + global@4.4.0: + resolution: {integrity: sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==} + + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@10.0.2: + resolution: {integrity: sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==} + engines: {node: '>=8'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + + got@11.8.6: + resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} + engines: {node: '>=10.19.0'} + + got@12.1.0: + resolution: {integrity: sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig==} + engines: {node: '>=14.16'} + + got@12.6.1: + resolution: {integrity: sha512-mThBblvlAF1d4O5oqyvN+ZxLAYwIJK7bpMxgYqPD9okW0C3qm5FFn7k811QrcuEBwaogR3ngOFoCfs6mRv7teQ==} + engines: {node: '>=14.16'} + + graceful-fs@4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + growl@1.10.5: + resolution: {integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==} + engines: {node: '>=4.x'} + + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + har-schema@2.0.0: + resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} + engines: {node: '>=4'} + + har-validator@5.1.5: + resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} + engines: {node: '>=6'} + deprecated: this library is no longer supported + + hardhat-gas-reporter@1.0.10: + resolution: {integrity: sha512-02N4+So/fZrzJ88ci54GqwVA3Zrf0C9duuTyGt0CFRIh/CdNwbnTgkXkRfojOMLBQ+6t+lBIkgbsOtqMvNwikA==} + peerDependencies: + hardhat: ^2.0.2 + + has-bigints@1.0.2: + resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} + + has-color@0.1.7: + resolution: {integrity: sha512-kaNz5OTAYYmt646Hkqw50/qyxP2vFnTVu5AQ1Zmk22Kk5+4Qx6BpO8+u7IKsML5fOsFk0ZT0AcCJNYwcvaLBvw==} + engines: {node: '>=0.10.0'} + + has-flag@1.0.0: + resolution: {integrity: sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA==} + engines: {node: '>=0.10.0'} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + + has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + has@1.0.4: + resolution: {integrity: sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==} + engines: {node: '>= 0.4.0'} + + hash-base@3.1.0: + resolution: {integrity: sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==} + engines: {node: '>=4'} + + hash.js@1.1.3: + resolution: {integrity: sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==} + + hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + + hasha@5.2.2: + resolution: {integrity: sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==} + engines: {node: '>=8'} + + hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + header-case@1.0.1: + resolution: {integrity: sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==} + + heap@0.2.7: + resolution: {integrity: sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg==} + + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + + highlightjs-solidity@2.0.6: + resolution: {integrity: sha512-DySXWfQghjm2l6a/flF+cteroJqD4gI8GSdL4PtvxZSsAHie8m3yVe2JFoRg03ROKT6hp2Lc/BxXkqerNmtQYg==} + + hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + htmlparser2@9.1.0: + resolution: {integrity: sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==} + + http-basic@8.1.3: + resolution: {integrity: sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==} + engines: {node: '>=6.0.0'} + + http-cache-semantics@4.1.1: + resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} + + http-errors@2.0.0: + resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} + engines: {node: '>= 0.8'} + + http-https@1.0.0: + resolution: {integrity: sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg==} + + http-response-object@3.0.2: + resolution: {integrity: sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==} + + http-signature@1.2.0: + resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} + engines: {node: '>=0.8', npm: '>=1.3.7'} + + http2-wrapper@1.0.3: + resolution: {integrity: sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==} + engines: {node: '>=10.19.0'} + + http2-wrapper@2.2.1: + resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} + engines: {node: '>=10.19.0'} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + human-id@1.0.2: + resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + idna-uts46-hx@2.3.1: + resolution: {integrity: sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA==} + engines: {node: '>=4.0.0'} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + immer@10.0.2: + resolution: {integrity: sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==} + + immutable@4.3.7: + resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==} + + import-fresh@3.3.0: + resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} + engines: {node: '>=6'} + + import-lazy@4.0.0: + resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} + engines: {node: '>=8'} + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} + engines: {node: '>= 0.4'} + + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + + interpret@1.4.0: + resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} + engines: {node: '>= 0.10'} + + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + + invert-kv@1.0.0: + resolution: {integrity: sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==} + engines: {node: '>=0.10.0'} + + io-ts@1.10.4: + resolution: {integrity: sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-bigint@1.0.4: + resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.1.2: + resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} + engines: {node: '>= 0.4'} + + is-builtin-module@3.2.1: + resolution: {integrity: sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==} + engines: {node: '>=6'} + + is-bun-module@1.3.0: + resolution: {integrity: sha512-DgXeu5UWI0IsMQundYb5UAOzm6G2eVnarJ0byP6Tm55iZNKceD59LNPA2L4VvsScTtHcw0yEkVwSf7PC+QoLSA==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-core-module@2.15.1: + resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + + is-date-object@1.0.5: + resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} + engines: {node: '>= 0.4'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@1.0.0: + resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@2.0.0: + resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} + engines: {node: '>=4'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-function@1.0.2: + resolution: {integrity: sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==} + + is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hex-prefixed@1.0.0: + resolution: {integrity: sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA==} + engines: {node: '>=6.5.0', npm: '>=3'} + + is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + + is-lower-case@1.1.3: + resolution: {integrity: sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.0.7: + resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} + engines: {node: '>= 0.4'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-regex@1.1.4: + resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-string@1.0.7: + resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} + engines: {node: '>= 0.4'} + + is-subdir@1.2.0: + resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} + engines: {node: '>=4'} + + is-symbol@1.0.4: + resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} + engines: {node: '>= 0.4'} + + is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-upper-case@1.1.2: + resolution: {integrity: sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==} + + is-url@1.2.4: + resolution: {integrity: sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==} + + is-utf8@0.2.1: + resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} + + is-weakref@1.0.2: + resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + isarray@0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isomorphic-fetch@3.0.0: + resolution: {integrity: sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA==} + + isomorphic-ws@5.0.0: + resolution: {integrity: sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==} + peerDependencies: + ws: '*' + + isows@1.0.6: + resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==} + peerDependencies: + ws: '*' + + isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-hook@3.0.0: + resolution: {integrity: sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==} + engines: {node: '>=8'} + + istanbul-lib-instrument@4.0.3: + resolution: {integrity: sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==} + engines: {node: '>=8'} + + istanbul-lib-processinfo@2.0.3: + resolution: {integrity: sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==} + engines: {node: '>=8'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + + istanbul-reports@3.1.7: + resolution: {integrity: sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==} + engines: {node: '>=8'} + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jju@1.4.0: + resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + + js-sha3@0.5.5: + resolution: {integrity: sha512-yLLwn44IVeunwjpDVTDZmQeVbB0h+dZpY2eO68B/Zik8hu6dH+rKeLxwua79GGIvW6xr8NBAcrtiUbYrTjEFTA==} + + js-sha3@0.5.7: + resolution: {integrity: sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g==} + + js-sha3@0.8.0: + resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.1: + resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + jsbn@0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + + jsesc@3.0.2: + resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-schema-traverse@0.3.1: + resolution: {integrity: sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA==} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json-stream-stringify@3.1.6: + resolution: {integrity: sha512-x7fpwxOkbhFCaJDJ8vb1fBY3DdSa4AlITaz+HHILQJzdPMnHEFjxPwVUi1ALIbcIxDE0PNe/0i7frnY8QnBQog==} + engines: {node: '>=7.10.1'} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonfile@2.4.0: + resolution: {integrity: sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==} + + jsonfile@4.0.0: + resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + + jsonfile@6.1.0: + resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} + + jsonschema@1.4.1: + resolution: {integrity: sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ==} + + jsprim@1.4.2: + resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} + engines: {node: '>=0.6.0'} + + just-extend@4.2.1: + resolution: {integrity: sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==} + + just-extend@6.2.0: + resolution: {integrity: sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==} + + katex@0.16.21: + resolution: {integrity: sha512-XvqR7FgOHtWupfMiigNzmh+MgUVmDGU2kXZm899ZkPfcuoPuFxyHmXsgATDpFZDAXCI8tvinaVcDo8PIIJSo4A==} + hasBin: true + + keccak@3.0.4: + resolution: {integrity: sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==} + engines: {node: '>=10.0.0'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + khroma@2.1.0: + resolution: {integrity: sha512-Ls993zuzfayK269Svk9hzpeGUKob/sIgZzyHYdjQoAdQetRKpOLj+k/QQQ/6Qi0Yz65mlROrfd+Ev+1+7dz9Kw==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + klaw@1.3.1: + resolution: {integrity: sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + latest-version@7.0.0: + resolution: {integrity: sha512-KvNT4XqAMzdcL6ka6Tl3i2lYeFDgXNCuIX+xNx6ZMVR1dFq+idXd9FLKNMOIx0t9mJ9/HudyX4oZWXZQ0UJHeg==} + engines: {node: '>=14.16'} + + layout-base@1.0.2: + resolution: {integrity: sha512-8h2oVEZNktL4BH2JCOI90iD1yXwL6iNW7KcCKT2QZgQJR2vbqDsldCTPRU9NifTCqHZci57XvQQ15YTu+sTYPg==} + + lcid@1.0.0: + resolution: {integrity: sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==} + engines: {node: '>=0.10.0'} + + levn@0.3.0: + resolution: {integrity: sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==} + engines: {node: '>= 0.8.0'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + load-json-file@1.1.0: + resolution: {integrity: sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==} + engines: {node: '>=0.10.0'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + lodash-es@4.17.21: + resolution: {integrity: sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==} + + lodash.assign@4.2.0: + resolution: {integrity: sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw==} + + lodash.camelcase@4.3.0: + resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} + + lodash.clonedeep@4.5.0: + resolution: {integrity: sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==} + + lodash.deburr@4.1.0: + resolution: {integrity: sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==} + + lodash.flattendeep@4.4.0: + resolution: {integrity: sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==} + + lodash.get@4.4.2: + resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==} + deprecated: This package is deprecated. Use the optional chaining (?.) operator instead. + + lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + deprecated: This package is deprecated. Use require('node:util').isDeepStrictEqual instead. + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.snakecase@4.1.1: + resolution: {integrity: sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==} + + lodash.startcase@4.4.0: + resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + + lodash.trim@4.5.1: + resolution: {integrity: sha512-nJAlRl/K+eiOehWKDzoBVrSMhK0K3A3YQsUNXHQa5yIrKBAhsZgSu3KoAFoFT+mEgiyBHddZ0pRk1ITpIp90Wg==} + + lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} + + lower-case-first@1.0.2: + resolution: {integrity: sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA==} + + lower-case@1.1.4: + resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==} + + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + + lowercase-keys@2.0.0: + resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} + engines: {node: '>=8'} + + lowercase-keys@3.0.0: + resolution: {integrity: sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lru-cache@4.1.5: + resolution: {integrity: sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lru_map@0.3.3: + resolution: {integrity: sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==} + + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + markdown-table@1.1.3: + resolution: {integrity: sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==} + + markdown-table@3.0.4: + resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + + md5.js@1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + + mdast-util-from-markdown@1.3.1: + resolution: {integrity: sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==} + + mdast-util-to-string@3.2.0: + resolution: {integrity: sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + mermaid@10.9.3: + resolution: {integrity: sha512-V80X1isSEvAewIL3xhmz/rVmc27CVljcsbWxkxlWJWY/1kQa4XOABqpDl2qQLGKzpKm6WbTfUEKImBlUfFYArw==} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micro-eth-signer@0.14.0: + resolution: {integrity: sha512-5PLLzHiVYPWClEvZIXXFu5yutzpadb73rnQCpUqIHu3No3coFuWQNfE5tkBQJ7djuLYl6aRLaS0MgWJYGoqiBw==} + + micro-ftch@0.3.1: + resolution: {integrity: sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==} + + micro-packed@0.7.2: + resolution: {integrity: sha512-HJ/u8+tMzgrJVAl6P/4l8KGjJSA3SCZaRb1m4wpbovNScCSmVOGUYbkkcoPPcknCHWPpRAdjy+yqXqyQWf+k8g==} + + micromark-core-commonmark@1.1.0: + resolution: {integrity: sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==} + + micromark-factory-destination@1.1.0: + resolution: {integrity: sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==} + + micromark-factory-label@1.1.0: + resolution: {integrity: sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==} + + micromark-factory-space@1.1.0: + resolution: {integrity: sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==} + + micromark-factory-title@1.1.0: + resolution: {integrity: sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==} + + micromark-factory-whitespace@1.1.0: + resolution: {integrity: sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==} + + micromark-util-character@1.2.0: + resolution: {integrity: sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==} + + micromark-util-chunked@1.1.0: + resolution: {integrity: sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==} + + micromark-util-classify-character@1.1.0: + resolution: {integrity: sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==} + + micromark-util-combine-extensions@1.1.0: + resolution: {integrity: sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==} + + micromark-util-decode-numeric-character-reference@1.1.0: + resolution: {integrity: sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==} + + micromark-util-decode-string@1.1.0: + resolution: {integrity: sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==} + + micromark-util-encode@1.1.0: + resolution: {integrity: sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==} + + micromark-util-html-tag-name@1.2.0: + resolution: {integrity: sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==} + + micromark-util-normalize-identifier@1.1.0: + resolution: {integrity: sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==} + + micromark-util-resolve-all@1.1.0: + resolution: {integrity: sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==} + + micromark-util-sanitize-uri@1.2.0: + resolution: {integrity: sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==} + + micromark-util-subtokenize@1.1.0: + resolution: {integrity: sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==} + + micromark-util-symbol@1.1.0: + resolution: {integrity: sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==} + + micromark-util-types@1.1.0: + resolution: {integrity: sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==} + + micromark@3.2.0: + resolution: {integrity: sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-response@1.0.1: + resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} + engines: {node: '>=4'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + mimic-response@4.0.0: + resolution: {integrity: sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + min-document@2.19.0: + resolution: {integrity: sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==} + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + + minimatch@3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + + minimatch@4.2.1: + resolution: {integrity: sha512-9Uq1ChtSZO+Mxa/CL1eGizn2vRn3MlLgzhT0Iz8zaY8NdvxvB0d5QdPFmCKf7JKA9Lerx5vRrnwO03jsSfGG9g==} + engines: {node: '>=10'} + + minimatch@5.1.6: + resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==} + engines: {node: '>=10'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass@2.9.0: + resolution: {integrity: sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==} + + minizlib@1.3.3: + resolution: {integrity: sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==} + + mkdirp-classic@0.5.3: + resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + + mkdirp-promise@5.0.1: + resolution: {integrity: sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w==} + engines: {node: '>=4'} + deprecated: This package is broken and no longer maintained. 'mkdirp' itself supports promises now, please switch to that. + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mkdirp@3.0.1: + resolution: {integrity: sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==} + engines: {node: '>=10'} + hasBin: true + + mnemonist@0.38.5: + resolution: {integrity: sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg==} + + mocha@10.7.3: + resolution: {integrity: sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==} + engines: {node: '>= 14.0.0'} + hasBin: true + + mocha@9.2.2: + resolution: {integrity: sha512-L6XC3EdwT6YrIk0yXpavvLkn8h+EU+Y5UcCHKECyMbdUIxyMuZj4bX4U9e1nvnvUUvQVsV2VHQr5zLdcUkhW/g==} + engines: {node: '>= 12.0.0'} + hasBin: true + + mock-fs@4.14.0: + resolution: {integrity: sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw==} + + mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multibase@0.6.1: + resolution: {integrity: sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw==} + deprecated: This module has been superseded by the multiformats module + + multibase@0.7.0: + resolution: {integrity: sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg==} + deprecated: This module has been superseded by the multiformats module + + multicodec@0.5.7: + resolution: {integrity: sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA==} + deprecated: This module has been superseded by the multiformats module + + multicodec@1.0.4: + resolution: {integrity: sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg==} + deprecated: This module has been superseded by the multiformats module + + multihashes@0.4.21: + resolution: {integrity: sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw==} + + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + + nano-base32@1.0.1: + resolution: {integrity: sha512-sxEtoTqAPdjWVGv71Q17koMFGsOMSiHsIFEvzOM7cNp8BXB4AnEwmDabm5dorusJf/v1z7QxaZYxUorU9RKaAw==} + + nano-json-stream-parser@0.1.2: + resolution: {integrity: sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew==} + + nanoid@3.3.1: + resolution: {integrity: sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanoid@3.3.11: + resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + napi-build-utils@2.0.0: + resolution: {integrity: sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==} + + natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + ndjson@2.0.0: + resolution: {integrity: sha512-nGl7LRGrzugTtaFcJMhLbpzJM6XdivmbkdlaGcrk/LXg2KL/YBC6z1g70xh0/al+oFuVFP8N8kiWRucmeEH/qQ==} + engines: {node: '>=10'} + hasBin: true + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + next-tick@1.1.0: + resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} + + nise@4.1.0: + resolution: {integrity: sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==} + + nise@5.1.9: + resolution: {integrity: sha512-qOnoujW4SV6e40dYxJOb3uvuoPHtmLzIk4TFo+j0jPJoC+5Z9xja5qH5JZobEPsa8+YYphMrOSwnrshEhG2qww==} + + no-case@2.3.2: + resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==} + + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + + node-abi@3.71.0: + resolution: {integrity: sha512-SZ40vRiy/+wRTf21hxkkEjPJZpARzUMVcJoQse2EF8qkUWbbO2z7vd5oA/H6bVH6SZQ5STGcu0KRDS7biNRfxw==} + engines: {node: '>=10'} + + node-addon-api@2.0.2: + resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} + + node-addon-api@3.2.1: + resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} + + node-addon-api@5.1.0: + resolution: {integrity: sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==} + + node-addon-api@6.1.0: + resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} + + node-emoji@1.11.0: + resolution: {integrity: sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A==} + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-gyp-build@4.8.2: + resolution: {integrity: sha512-IRUxE4BVsHWXkV/SFOut4qTlagw2aM8T5/vnTsmrHJvVoKueJHRc/JaFND7QDDc61kLYUJ6qlZM3sqTSyx2dTw==} + hasBin: true + + node-hid@2.1.2: + resolution: {integrity: sha512-qhCyQqrPpP93F/6Wc/xUR7L8mAJW0Z6R7HMQV8jCHHksAxNDe/4z4Un/H9CpLOT+5K39OPyt9tIQlavxWES3lg==} + engines: {node: '>=10'} + hasBin: true + + node-preload@0.2.1: + resolution: {integrity: sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==} + engines: {node: '>=8'} + + node-releases@2.0.18: + resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + + nofilter@1.0.4: + resolution: {integrity: sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA==} + engines: {node: '>=8'} + + nofilter@3.1.0: + resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} + engines: {node: '>=12.19'} + + non-layered-tidy-tree-layout@2.0.2: + resolution: {integrity: sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==} + + nopt@3.0.6: + resolution: {integrity: sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg==} + hasBin: true + + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + + normalize-url@8.0.1: + resolution: {integrity: sha512-IO9QvjUMWxPQQhs60oOu10CRkWCiZzSUkzbXGGV9pviYl1fXYcvkzQ5jV9z8Y6un8ARoVRl4EtC6v6jNqbaJ/w==} + engines: {node: '>=14.16'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + number-is-nan@1.0.1: + resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==} + engines: {node: '>=0.10.0'} + + number-to-bn@1.7.0: + resolution: {integrity: sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig==} + engines: {node: '>=6.5.0', npm: '>=3'} + + nyc@15.1.0: + resolution: {integrity: sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==} + engines: {node: '>=8.9'} + hasBin: true + + oauth-sign@0.9.0: + resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.2: + resolution: {integrity: sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.values@1.2.0: + resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} + engines: {node: '>= 0.4'} + + obliterator@2.0.4: + resolution: {integrity: sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ==} + + oboe@2.1.5: + resolution: {integrity: sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA==} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + optionator@0.8.3: + resolution: {integrity: sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==} + engines: {node: '>= 0.8.0'} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + + ordinal@1.0.3: + resolution: {integrity: sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ==} + + os-locale@1.4.0: + resolution: {integrity: sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==} + engines: {node: '>=0.10.0'} + + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + outdent@0.5.0: + resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} + + p-cancelable@2.1.1: + resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} + engines: {node: '>=8'} + + p-cancelable@3.0.0: + resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} + engines: {node: '>=12.20'} + + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-map@3.0.0: + resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==} + engines: {node: '>=8'} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + package-hash@4.0.0: + resolution: {integrity: sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==} + engines: {node: '>=8'} + + package-json@8.1.1: + resolution: {integrity: sha512-cbH9IAIJHNj9uXi196JVsRlt7cHKak6u/e6AkL/bkRelZ7rlL3X1YKxsZwa36xipOEKAsdtmaG6aAJoM1fx2zA==} + engines: {node: '>=14.16'} + + package-manager-detector@0.2.2: + resolution: {integrity: sha512-VgXbyrSNsml4eHWIvxxG/nTL4wgybMTXCV2Un/+yEc3aDKKU6nQBZjbeP3Pl3qm9Qg92X/1ng4ffvCeD/zwHgg==} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + param-case@2.1.1: + resolution: {integrity: sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-cache-control@1.0.1: + resolution: {integrity: sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==} + + parse-headers@2.0.5: + resolution: {integrity: sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==} + + parse-json@2.2.0: + resolution: {integrity: sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==} + engines: {node: '>=0.10.0'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-ms@0.1.2: + resolution: {integrity: sha512-VwMglE9412ifMHcRFEVJePEpreQh90wjIiOdP0UQQGKV4l+QprdKI+p5noXTkmGjznBMb40s+VymcclATAVvYA==} + engines: {node: '>=0.10.0'} + + parse5-htmlparser2-tree-adapter@7.1.0: + resolution: {integrity: sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==} + + parse5-parser-stream@7.1.2: + resolution: {integrity: sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==} + + parse5@7.2.0: + resolution: {integrity: sha512-ZkDsAOcxsUMZ4Lz5fVciOehNcJ+Gb8gTzcA4yl3wnc273BAybYWrQ+Ks/OjCjSEpjvQkDSeZbybK9qj2VHHdGA==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + pascal-case@2.0.1: + resolution: {integrity: sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==} + + path-case@2.1.1: + resolution: {integrity: sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==} + + path-exists@2.1.0: + resolution: {integrity: sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==} + engines: {node: '>=0.10.0'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-to-regexp@0.1.10: + resolution: {integrity: sha512-7lf7qcQidTku0Gu3YDPc8DJ1q7OOucfa/BSsIwjuh56VU7katFvuM8hULfkwB3Fns/rsVF7PwPKVw1sl5KQS9w==} + + path-to-regexp@1.9.0: + resolution: {integrity: sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g==} + + path-to-regexp@6.3.0: + resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + + path-type@1.1.0: + resolution: {integrity: sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==} + engines: {node: '>=0.10.0'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pathval@1.1.1: + resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} + + pbkdf2@3.1.2: + resolution: {integrity: sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==} + engines: {node: '>=0.12'} + + performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + + picocolors@1.1.0: + resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + picomatch@4.0.2: + resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==} + engines: {node: '>=12'} + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pinkie-promise@2.0.1: + resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} + engines: {node: '>=0.10.0'} + + pinkie@2.0.4: + resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} + engines: {node: '>=0.10.0'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + + possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@8.5.3: + resolution: {integrity: sha512-dle9A3yYxlBSrt8Fu+IpjGT8SY8hN0mlaA6GY8t0P5PjIOZemULz/E2Bnm/2dcUOena75OTNkHI76uZBNUUq3A==} + engines: {node: ^10 || ^12 || >=14} + + prebuild-install@7.1.3: + resolution: {integrity: sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==} + engines: {node: '>=10'} + hasBin: true + + prelude-ls@1.1.2: + resolution: {integrity: sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==} + engines: {node: '>= 0.8.0'} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.0: + resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} + engines: {node: '>=6.0.0'} + + prettier@2.4.1: + resolution: {integrity: sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA==} + engines: {node: '>=10.13.0'} + hasBin: true + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + pretty-ms@0.2.2: + resolution: {integrity: sha512-ah/vWDJAT0arxQwVcSGp6etaLTZr4IsrXTy/khfjimzdYgSxYWzTMByrtpJUWinAnVY8szDg+qQhsE5MUMz3lQ==} + engines: {node: '>=0.10.0'} + hasBin: true + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process-on-spawn@1.0.0: + resolution: {integrity: sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==} + engines: {node: '>=8'} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + promise@8.3.0: + resolution: {integrity: sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + proto-list@1.2.4: + resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + + pseudomap@1.0.2: + resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} + + psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + + pump@3.0.2: + resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==} + + punycode@2.1.0: + resolution: {integrity: sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA==} + engines: {node: '>=6'} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pure-rand@5.0.5: + resolution: {integrity: sha512-BwQpbqxSCBJVpamI6ydzcKqyFmnd5msMWUGvzXLm1aXvusbbgkbOto/EUPM00hjveJEaJtdbhUjKSzWRhQVkaw==} + + qs@6.13.0: + resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} + engines: {node: '>=0.6'} + + qs@6.5.3: + resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} + engines: {node: '>=0.6'} + + query-string@5.1.1: + resolution: {integrity: sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==} + engines: {node: '>=0.10.0'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-lru@5.1.1: + resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} + engines: {node: '>=10'} + + rambda@7.5.0: + resolution: {integrity: sha512-y/M9weqWAH4iopRd7EHDEQQvpFPHj1AA3oHozE9tfITHUtTR7Z9PSlIRRG2l1GuW7sefC1cXFfIcF+cgnShdBA==} + + ramda@0.27.2: + resolution: {integrity: sha512-SbiLPU40JuJniHexQSAgad32hfwd+DRUdwF2PlVuI5RZD0/vahUco7R8vD86J/tcEKKF9vZrUVwgtmGCqlCKyA==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} + engines: {node: '>= 0.8'} + + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + + react-dom@18.3.1: + resolution: {integrity: sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==} + peerDependencies: + react: ^18.3.1 + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + react-refresh@0.14.2: + resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} + engines: {node: '>=0.10.0'} + + react-router-dom@6.11.0: + resolution: {integrity: sha512-Q3mK1c/CYoF++J6ZINz7EZzwlgSOZK/kc7lxIA7PhtWhKju4KfF1WHqlx0kVCIFJAWztuYVpXZeljEbds8z4Og==} + engines: {node: '>=14'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + + react-router@6.11.0: + resolution: {integrity: sha512-hTm6KKNpj9SDG4syIWRjCU219O0RZY8RUPobCFt9p+PlF7nnkRgMoh2DieTKvw3F3Mw6zg565HGnSv8BuoY5oQ==} + engines: {node: '>=14'} + peerDependencies: + react: '>=16.8' + + react-tooltip@5.28.0: + resolution: {integrity: sha512-R5cO3JPPXk6FRbBHMO0rI9nkUG/JKfalBSQfZedZYzmqaZQgq7GLzF8vcCWx6IhUCKg0yPqJhXIzmIO5ff15xg==} + peerDependencies: + react: '>=16.14.0' + react-dom: '>=16.14.0' + + react@18.3.1: + resolution: {integrity: sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==} + engines: {node: '>=0.10.0'} + + read-pkg-up@1.0.1: + resolution: {integrity: sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==} + engines: {node: '>=0.10.0'} + + read-pkg@1.1.0: + resolution: {integrity: sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==} + engines: {node: '>=0.10.0'} + + read-yaml-file@1.1.0: + resolution: {integrity: sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA==} + engines: {node: '>=6'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@4.0.2: + resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==} + engines: {node: '>= 14.16.0'} + + rechoir@0.6.2: + resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} + engines: {node: '>= 0.10'} + + recursive-readdir@2.2.3: + resolution: {integrity: sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA==} + engines: {node: '>=6.0.0'} + + reduce-flatten@2.0.0: + resolution: {integrity: sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==} + engines: {node: '>=6'} + + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + + regexp.prototype.flags@1.5.3: + resolution: {integrity: sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ==} + engines: {node: '>= 0.4'} + + registry-auth-token@5.0.2: + resolution: {integrity: sha512-o/3ikDxtXaA59BmZuZrJZDJv8NMDGSj+6j6XaeBmHw8eY1i1qd9+6H+LjVvQXx3HN6aRCGa1cUdJ9RaJZUugnQ==} + engines: {node: '>=14'} + + registry-url@6.0.1: + resolution: {integrity: sha512-+crtS5QjFRqFCoQmvGduwYWEBng99ZvmFvF+cUJkGYF1L1BfU8C6Zp9T7f5vPAwyLkUExpvK+ANVZmGU49qi4Q==} + engines: {node: '>=12'} + + release-zalgo@1.0.0: + resolution: {integrity: sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==} + engines: {node: '>=4'} + + req-cwd@2.0.0: + resolution: {integrity: sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ==} + engines: {node: '>=4'} + + req-from@2.0.0: + resolution: {integrity: sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA==} + engines: {node: '>=4'} + + request@2.88.2: + resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} + engines: {node: '>= 6'} + deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@1.2.1: + resolution: {integrity: sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + require-main-filename@1.0.1: + resolution: {integrity: sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==} + + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + + requireindex@1.2.0: + resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} + engines: {node: '>=0.10.5'} + + resolve-alpn@1.2.1: + resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} + + resolve-from@3.0.0: + resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==} + engines: {node: '>=4'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.1.7: + resolution: {integrity: sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg==} + + resolve@1.17.0: + resolution: {integrity: sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==} + + resolve@1.19.0: + resolution: {integrity: sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==} + + resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} + hasBin: true + + responselike@2.0.1: + resolution: {integrity: sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==} + + responselike@3.0.0: + resolution: {integrity: sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==} + engines: {node: '>=14.16'} + + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + + reusify@1.0.4: + resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + ripemd160-min@0.0.6: + resolution: {integrity: sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A==} + engines: {node: '>=8'} + + ripemd160@2.0.2: + resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} + + rlp@2.2.7: + resolution: {integrity: sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ==} + hasBin: true + + robust-predicates@3.0.2: + resolution: {integrity: sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==} + + rollup@4.39.0: + resolution: {integrity: sha512-thI8kNc02yNvnmJp8dr3fNWJ9tCONDhp6TV35X6HkKGGs9E6q7YWCHbe5vKiTa7TAiNcFEmXKj3X/pG2b3ci0g==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + rw@1.3.3: + resolution: {integrity: sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==} + + rxjs@7.8.1: + resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==} + + sade@1.8.1: + resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==} + engines: {node: '>=6'} + + safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sc-istanbul@0.4.6: + resolution: {integrity: sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g==} + hasBin: true + + scheduler@0.23.2: + resolution: {integrity: sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==} + + scrypt-js@2.0.4: + resolution: {integrity: sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw==} + + scrypt-js@3.0.1: + resolution: {integrity: sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA==} + + secp256k1@4.0.4: + resolution: {integrity: sha512-6JfvwvjUOn8F/jUoBY2Q1v5WY5XS+rj8qSe0v8Y4ezH4InLgTEeOOPQsRll9OV429Pvo6BCHGavIyJfr3TAhsw==} + engines: {node: '>=18.0.0'} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.5.4: + resolution: {integrity: sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==} + engines: {node: '>=10'} + hasBin: true + + semver@7.6.3: + resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} + engines: {node: '>=10'} + hasBin: true + + send@0.19.0: + resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} + engines: {node: '>= 0.8.0'} + + sentence-case@2.1.1: + resolution: {integrity: sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==} + + serialize-javascript@6.0.0: + resolution: {integrity: sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + serve-static@1.16.2: + resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} + engines: {node: '>= 0.8.0'} + + servify@0.1.12: + resolution: {integrity: sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw==} + engines: {node: '>=6'} + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + setimmediate@1.0.4: + resolution: {integrity: sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog==} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.11: + resolution: {integrity: sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==} + hasBin: true + + sha1@1.1.1: + resolution: {integrity: sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA==} + + sha3@2.1.4: + resolution: {integrity: sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg==} + + shallowequal@1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shelljs@0.8.5: + resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} + engines: {node: '>=4'} + hasBin: true + + side-channel@1.0.6: + resolution: {integrity: sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + simple-concat@1.0.1: + resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} + + simple-get@2.8.2: + resolution: {integrity: sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw==} + + simple-get@4.0.1: + resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} + + sinon-chai@3.7.0: + resolution: {integrity: sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==} + peerDependencies: + chai: ^4.0.0 + sinon: '>=4.0.0' + + sinon@14.0.2: + resolution: {integrity: sha512-PDpV0ZI3ZCS3pEqx0vpNp6kzPhHrLx72wA0G+ZLaaJjLIYeE0n8INlgaohKuGy7hP0as5tbUd23QWu5U233t+w==} + deprecated: 16.1.1 + + sinon@9.2.4: + resolution: {integrity: sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==} + deprecated: 16.1.1 + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + + snake-case@2.1.0: + resolution: {integrity: sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==} + + solc@0.4.26: + resolution: {integrity: sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA==} + hasBin: true + + solc@0.8.26: + resolution: {integrity: sha512-yiPQNVf5rBFHwN6SIf3TUUvVAFKcQqmSUFeq+fb6pNRCo0ZCgpYOZDi3BVoezCPIAcKrVYd/qXlBLUP9wVrZ9g==} + engines: {node: '>=10.0.0'} + hasBin: true + + solhint@5.0.3: + resolution: {integrity: sha512-OLCH6qm/mZTCpplTXzXTJGId1zrtNuDYP5c2e6snIv/hdRVxPfBBz/bAlL91bY/Accavkayp2Zp2BaDSrLVXTQ==} + hasBin: true + + solidity-coverage@0.8.13: + resolution: {integrity: sha512-RiBoI+kF94V3Rv0+iwOj3HQVSqNzA9qm/qDP1ZDXK5IX0Cvho1qiz8hAXTsAo6KOIUeP73jfscq0KlLqVxzGWA==} + hasBin: true + peerDependencies: + hardhat: ^2.11.0 + + solpp@0.11.5: + resolution: {integrity: sha512-LjzCGMrTDXtera2C4mbQGZSpBznP+o3/82L2CneAAMNbm+t4xPsvfrgJkIaY+IZ5YLrB8IXn7cYthwHMKvAWnQ==} + engines: {node: '>=8.15.1'} + hasBin: true + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.2.0: + resolution: {integrity: sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA==} + engines: {node: '>=0.8.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + spawn-wrap@2.0.0: + resolution: {integrity: sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==} + engines: {node: '>=8'} + + spawndamnit@2.0.0: + resolution: {integrity: sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA==} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.20: + resolution: {integrity: sha512-jg25NiDV/1fLtSgEgyvVyDunvaNHbuwF9lfNV17gSmPFAlYzdfNBlLtLzXTevwkPj7DhGbmN9VnmJIgLnhvaBw==} + + split2@3.2.2: + resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + sshpk@1.18.0: + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} + engines: {node: '>=0.10.0'} + hasBin: true + + stable-hash@0.0.4: + resolution: {integrity: sha512-LjdcbuBeLcdETCrPn9i8AYAZ1eCtu4ECAWtP7UleOiZ9LzVxRzzUZEoZ8zB24nhkQnDWyET0I+3sWokSDS3E7g==} + + stacktrace-parser@0.1.10: + resolution: {integrity: sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg==} + engines: {node: '>=6'} + + statuses@2.0.1: + resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} + engines: {node: '>= 0.8'} + + strict-uri-encode@1.1.0: + resolution: {integrity: sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ==} + engines: {node: '>=0.10.0'} + + string-argv@0.3.2: + resolution: {integrity: sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==} + engines: {node: '>=0.6.19'} + + string-format@2.0.0: + resolution: {integrity: sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA==} + + string-width@1.0.2: + resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} + engines: {node: '>=0.10.0'} + + string-width@2.1.1: + resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} + engines: {node: '>=4'} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-ansi@0.1.1: + resolution: {integrity: sha512-behete+3uqxecWlDAm5lmskaSaISA+ThQ4oNNBDTBJt0x2ppR6IPqfZNuj6BLaLJ/Sji4TPZlcRyOis8wXQTLg==} + engines: {node: '>=0.8.0'} + hasBin: true + + strip-ansi@3.0.1: + resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} + engines: {node: '>=0.10.0'} + + strip-ansi@4.0.0: + resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} + engines: {node: '>=4'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-bom@2.0.0: + resolution: {integrity: sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==} + engines: {node: '>=0.10.0'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-hex-prefix@1.0.0: + resolution: {integrity: sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A==} + engines: {node: '>=6.5.0', npm: '>=3'} + + strip-indent@2.0.0: + resolution: {integrity: sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA==} + engines: {node: '>=4'} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + styled-components@5.3.10: + resolution: {integrity: sha512-3kSzSBN0TiCnGJM04UwO1HklIQQSXW7rCARUk+VyMR7clz8XVlA3jijtf5ypqoDIdNMKx3la4VvaPFR855SFcg==} + engines: {node: '>=10'} + peerDependencies: + react: '>= 16.8.0' + react-dom: '>= 16.8.0' + react-is: '>= 16.8.0' + + stylis@4.3.5: + resolution: {integrity: sha512-K7npNOKGRYuhAFFzkzMGfxFDpN6gDwf8hcMiE+uveTVbBgm93HrNP3ZDUpKqzZ4pG7TP6fmb+EMAQPjq9FqqvA==} + + supports-color@3.2.3: + resolution: {integrity: sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A==} + engines: {node: '>=0.8.0'} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svg-pan-zoom@3.6.2: + resolution: {integrity: sha512-JwnvRWfVKw/Xzfe6jriFyfey/lWJLq4bUh2jwoR5ChWQuQoOH8FEh1l/bEp46iHHKHEJWIyFJETbazraxNWECg==} + + swap-case@1.1.2: + resolution: {integrity: sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==} + + swarm-js@0.1.42: + resolution: {integrity: sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ==} + + sync-request@6.1.0: + resolution: {integrity: sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==} + engines: {node: '>=8.0.0'} + + sync-rpc@1.3.6: + resolution: {integrity: sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==} + + table-layout@1.0.2: + resolution: {integrity: sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A==} + engines: {node: '>=8.0.0'} + + table@6.8.2: + resolution: {integrity: sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==} + engines: {node: '>=10.0.0'} + + tapable@2.2.1: + resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} + engines: {node: '>=6'} + + tar-fs@2.1.1: + resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar@4.4.19: + resolution: {integrity: sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==} + engines: {node: '>=4.5'} + + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + testrpc@0.0.1: + resolution: {integrity: sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA==} + deprecated: testrpc has been renamed to ganache-cli, please use this package from now on. + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + then-request@6.0.2: + resolution: {integrity: sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==} + engines: {node: '>=6.0.0'} + + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + + through2@4.0.2: + resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} + + time-require@0.1.2: + resolution: {integrity: sha512-IqcSpa1sVNleRbC9eHnN7p7vwEHNmsjsXUDqjlnvo4+2VLJ7/gIY2XACTBuRhMB4weYbDYKsR3av2ySykRhDIA==} + engines: {node: '>= 0.10.0'} + + timed-out@4.0.1: + resolution: {integrity: sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA==} + engines: {node: '>=0.10.0'} + + tinyglobby@0.2.6: + resolution: {integrity: sha512-NbBoFBpqfcgd1tCiO8Lkfdk+xrA7mlLR9zgvZcZWQQwU63XAfUePyd6wZBaU93Hqw347lHnwFzttAkemHzzz4g==} + engines: {node: '>=12.0.0'} + + title-case@2.1.1: + resolution: {integrity: sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==} + + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tough-cookie@2.5.0: + resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} + engines: {node: '>=0.8'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + truffle-blockchain-utils@0.0.5: + resolution: {integrity: sha512-eCCV8FbYOuKagRY5NiqJCZrrh9GjWX2573ahqZPvUrzxYGIvCpSsHpGCub2e00YefpMfBqwscbsDTK7WNVfwoA==} + deprecated: 'WARNING: This package has been renamed to @truffle/blockchain-utils.' + + truffle-contract-schema@2.0.3: + resolution: {integrity: sha512-eI5cFifbB3zpcO4RsXSnjN9JMSlJ4M50GQPdrfbrIXRTXHsyQ433SkgFjIATUwfq++TXWkCRfKMjN8eA7YQ3+Q==} + deprecated: 'WARNING: This package has been renamed to @truffle/contract-schema.' + + truffle-contract@3.0.8: + resolution: {integrity: sha512-uhXb/G4dORU4RjFlwZZbFT0n5BS8akify+MaRsnWWs4SA/bo6x4/bQs1xtdO3b5Cl9nXiOX88wdQzRj3xtPVUg==} + deprecated: 'WARNING: This package has been renamed to @truffle/contract.' + + truffle-error@0.0.3: + resolution: {integrity: sha512-9gxs1z6BUn7MqrE4NPm/jcYe8rLok3Z57aweGIh1+CoRJSttzYqwcXCqaPRSNrTFnsTeZMBukkYr/PUcADoihw==} + deprecated: 'WARNING: This package has been renamed to @truffle/error.' + + ts-command-line-args@2.5.1: + resolution: {integrity: sha512-H69ZwTw3rFHb5WYpQya40YAX2/w7Ut75uUECbgBIsLmM+BNuYnxsltfyyLMxy6sEeKxgijLTnQtLd0nKd6+IYw==} + hasBin: true + + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + + ts-essentials@7.0.3: + resolution: {integrity: sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ==} + peerDependencies: + typescript: '>=3.7.0' + + ts-node@10.9.1: + resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + ts-node@10.9.2: + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} + hasBin: true + peerDependencies: + '@swc/core': '>=1.2.50' + '@swc/wasm': '>=1.2.50' + '@types/node': '*' + typescript: '>=2.7' + peerDependenciesMeta: + '@swc/core': + optional: true + '@swc/wasm': + optional: true + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.7.0: + resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + + tslib@2.8.0: + resolution: {integrity: sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==} + + tsort@0.0.1: + resolution: {integrity: sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw==} + + tsutils@3.21.0: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + + tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + + tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + + type-check@0.3.2: + resolution: {integrity: sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==} + engines: {node: '>= 0.8.0'} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-detect@4.1.0: + resolution: {integrity: sha512-Acylog8/luQ8L7il+geoSxhEkazvkslg7PSNKOX59mbB9cOveP5aq9h74Y7YU8yDpJwetzQQrfIwtf4Wp4LKcw==} + engines: {node: '>=4'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@0.7.1: + resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} + engines: {node: '>=8'} + + type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + + type-fest@2.19.0: + resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} + engines: {node: '>=12.20'} + + type-fest@3.13.1: + resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} + engines: {node: '>=14.16'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + type@2.7.3: + resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==} + + typechain@8.3.2: + resolution: {integrity: sha512-x/sQYr5w9K7yv3es7jo4KTX05CLxOf7TRWwoHlrjRh8H82G64g+k7VuWPJlgMo6qrjfCulOdfBjiaDtmhFYD/Q==} + hasBin: true + peerDependencies: + typescript: '>=4.3.0' + + typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.6: + resolution: {integrity: sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==} + engines: {node: '>= 0.4'} + + typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + typescript@5.0.4: + resolution: {integrity: sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==} + engines: {node: '>=12.20'} + hasBin: true + + typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + engines: {node: '>=14.17'} + hasBin: true + + typical@4.0.0: + resolution: {integrity: sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw==} + engines: {node: '>=8'} + + typical@5.2.0: + resolution: {integrity: sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==} + engines: {node: '>=8'} + + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + + ultron@1.1.1: + resolution: {integrity: sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==} + + unbox-primitive@1.0.2: + resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} + + underscore@1.13.7: + resolution: {integrity: sha512-GMXzWtsc57XAtguZgaQViUOzs0KTkk8ojr3/xAxXLITqf/3EMwxC0inyETfDFjH/Krbhuep0HNbbjI9i/q3F3g==} + + undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + + undici-types@6.19.8: + resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} + + undici@5.28.4: + resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} + engines: {node: '>=14.0'} + + undici@6.20.1: + resolution: {integrity: sha512-AjQF1QsmqfJys+LXfGTNum+qw4S88CojRInG/6t31W/1fk6G59s92bnAvGz5Cmur+kQv2SURXEvvudLmbrE8QA==} + engines: {node: '>=18.17'} + + unist-util-stringify-position@3.0.3: + resolution: {integrity: sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==} + + universalify@0.1.2: + resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + untildify@4.0.0: + resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} + engines: {node: '>=8'} + + update-browserslist-db@1.1.1: + resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + upper-case-first@1.1.2: + resolution: {integrity: sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==} + + upper-case@1.1.3: + resolution: {integrity: sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==} + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + url-set-query@1.0.0: + resolution: {integrity: sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg==} + + usb@2.9.0: + resolution: {integrity: sha512-G0I/fPgfHUzWH8xo2KkDxTTFruUWfppgSFJ+bQxz/kVY2x15EQ/XDB7dqD1G432G4gBG4jYQuF3U7j/orSs5nw==} + engines: {node: '>=10.20.0 <11.x || >=12.17.0 <13.0 || >=14.0.0'} + + utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + + utf8@2.1.2: + resolution: {integrity: sha512-QXo+O/QkLP/x1nyi54uQiG0XrODxdysuQvE5dtVqv7F5K2Qb6FsN+qbr6KhF5wQ20tfcV3VQp0/2x1e1MRSPWg==} + + utf8@3.0.0: + resolution: {integrity: sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@2.0.1: + resolution: {integrity: sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + + uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. + hasBin: true + + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + + uvu@0.5.6: + resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} + engines: {node: '>=8'} + hasBin: true + + v8-compile-cache-lib@3.0.1: + resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + validator@13.12.0: + resolution: {integrity: sha512-c1Q0mCiPlgdTVVVIJIrBuxNicYE+t/7oKeI9MWLj3fh/uq2Pxh/3eeWbVZ4OcGW1TUf53At0njHw5SMdA3tmMg==} + engines: {node: '>= 0.10'} + + varint@5.0.2: + resolution: {integrity: sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow==} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + verror@1.10.0: + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} + engines: {'0': node >=0.6.0} + + viem@2.21.34: + resolution: {integrity: sha512-IR8ucya4dkVJv1jzv/qBz1TxYbSoXZuJPuqQk1/AybU9VuGdMUayittYwr0Navs97XFNml6UWGVya07apoaBmQ==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + vite-plugin-singlefile@2.1.0: + resolution: {integrity: sha512-7tJo+UgZABlKpY/nubth/wxJ4+pUGREPnEwNOknxwl2MM0zTvF14KTU4Ln1lc140gjLLV5mjDrvuoquU7OZqCg==} + engines: {node: '>18.0.0'} + peerDependencies: + rollup: ^4.28.1 + vite: ^5.4.11 || ^6.0.0 + + vite@5.4.17: + resolution: {integrity: sha512-5+VqZryDj4wgCs55o9Lp+p8GE78TLVg0lasCH5xFZ4jacZjtqZa6JUw9/p0WeAojaOfncSM6v77InkFPGnvPvg==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + web-worker@1.3.0: + resolution: {integrity: sha512-BSR9wyRsy/KOValMgd5kMyr3JzpdeoR9KVId8u5GVlTTAtNChlsE4yTxeY7zMdNSyOmoKBv8NH2qeRY9Tg+IaA==} + + web3-bzz@1.10.0: + resolution: {integrity: sha512-o9IR59io3pDUsXTsps5pO5hW1D5zBmg46iNc2t4j2DkaYHNdDLwk2IP9ukoM2wg47QILfPEJYzhTfkS/CcX0KA==} + engines: {node: '>=8.0.0'} + + web3-bzz@1.10.4: + resolution: {integrity: sha512-ZZ/X4sJ0Uh2teU9lAGNS8EjveEppoHNQiKlOXAjedsrdWuaMErBPdLQjXfcrYvN6WM6Su9PMsAxf3FXXZ+HwQw==} + engines: {node: '>=8.0.0'} + + web3-core-helpers@1.10.0: + resolution: {integrity: sha512-pIxAzFDS5vnbXvfvLSpaA1tfRykAe9adw43YCKsEYQwH0gCLL0kMLkaCX3q+Q8EVmAh+e1jWL/nl9U0de1+++g==} + engines: {node: '>=8.0.0'} + + web3-core-helpers@1.10.4: + resolution: {integrity: sha512-r+L5ylA17JlD1vwS8rjhWr0qg7zVoVMDvWhajWA5r5+USdh91jRUYosp19Kd1m2vE034v7Dfqe1xYRoH2zvG0g==} + engines: {node: '>=8.0.0'} + + web3-core-method@1.10.0: + resolution: {integrity: sha512-4R700jTLAMKDMhQ+nsVfIXvH6IGJlJzGisIfMKWAIswH31h5AZz7uDUW2YctI+HrYd+5uOAlS4OJeeT9bIpvkA==} + engines: {node: '>=8.0.0'} + + web3-core-method@1.10.4: + resolution: {integrity: sha512-uZTb7flr+Xl6LaDsyTeE2L1TylokCJwTDrIVfIfnrGmnwLc6bmTWCCrm71sSrQ0hqs6vp/MKbQYIYqUN0J8WyA==} + engines: {node: '>=8.0.0'} + + web3-core-promievent@1.10.0: + resolution: {integrity: sha512-68N7k5LWL5R38xRaKFrTFT2pm2jBNFaM4GioS00YjAKXRQ3KjmhijOMG3TICz6Aa5+6GDWYelDNx21YAeZ4YTg==} + engines: {node: '>=8.0.0'} + + web3-core-promievent@1.10.4: + resolution: {integrity: sha512-2de5WnJQ72YcIhYwV/jHLc4/cWJnznuoGTJGD29ncFQHAfwW/MItHFSVKPPA5v8AhJe+r6y4Y12EKvZKjQVBvQ==} + engines: {node: '>=8.0.0'} + + web3-core-requestmanager@1.10.0: + resolution: {integrity: sha512-3z/JKE++Os62APml4dvBM+GAuId4h3L9ckUrj7ebEtS2AR0ixyQPbrBodgL91Sv7j7cQ3Y+hllaluqjguxvSaQ==} + engines: {node: '>=8.0.0'} + + web3-core-requestmanager@1.10.4: + resolution: {integrity: sha512-vqP6pKH8RrhT/2MoaU+DY/OsYK9h7HmEBNCdoMj+4ZwujQtw/Mq2JifjwsJ7gits7Q+HWJwx8q6WmQoVZAWugg==} + engines: {node: '>=8.0.0'} + + web3-core-subscriptions@1.10.0: + resolution: {integrity: sha512-HGm1PbDqsxejI075gxBc5OSkwymilRWZufIy9zEpnWKNmfbuv5FfHgW1/chtJP6aP3Uq2vHkvTDl3smQBb8l+g==} + engines: {node: '>=8.0.0'} + + web3-core-subscriptions@1.10.4: + resolution: {integrity: sha512-o0lSQo/N/f7/L76C0HV63+S54loXiE9fUPfHFcTtpJRQNDBVsSDdWRdePbWwR206XlsBqD5VHApck1//jEafTw==} + engines: {node: '>=8.0.0'} + + web3-core@1.10.0: + resolution: {integrity: sha512-fWySwqy2hn3TL89w5TM8wXF1Z2Q6frQTKHWmP0ppRQorEK8NcHJRfeMiv/mQlSKoTS1F6n/nv2uyZsixFycjYQ==} + engines: {node: '>=8.0.0'} + + web3-core@1.10.4: + resolution: {integrity: sha512-B6elffYm81MYZDTrat7aEhnhdtVE3lDBUZft16Z8awYMZYJDbnykEbJVS+l3mnA7AQTnSDr/1MjWofGDLBJPww==} + engines: {node: '>=8.0.0'} + + web3-core@4.7.0: + resolution: {integrity: sha512-skP4P56fhlrE+rIuS4WY9fTdja1DPml2xrrDmv+vQhPtmSFBs7CqesycIRLQh4dK1D4de/a23tkX6DLYdUt3nA==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-errors@1.3.0: + resolution: {integrity: sha512-j5JkAKCtuVMbY3F5PYXBqg1vWrtF4jcyyMY1rlw8a4PV67AkqlepjGgpzWJZd56Mt+TvHy6DA1F/3Id8LatDSQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-abi@1.10.0: + resolution: {integrity: sha512-cwS+qRBWpJ43aI9L3JS88QYPfFcSJJ3XapxOQ4j40v6mk7ATpA8CVK1vGTzpihNlOfMVRBkR95oAj7oL6aiDOg==} + engines: {node: '>=8.0.0'} + + web3-eth-abi@1.10.4: + resolution: {integrity: sha512-cZ0q65eJIkd/jyOlQPDjr8X4fU6CRL1eWgdLwbWEpo++MPU/2P4PFk5ZLAdye9T5Sdp+MomePPJ/gHjLMj2VfQ==} + engines: {node: '>=8.0.0'} + + web3-eth-abi@4.3.0: + resolution: {integrity: sha512-OqZPGGxHmfKJt33BfpclEMmWvnnLJ/B+jVTnVagd2OIU1kIv09xf/E60ei0eGeG612uFy/pPq31u4RidF/gf6g==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-accounts@1.10.0: + resolution: {integrity: sha512-wiq39Uc3mOI8rw24wE2n15hboLE0E9BsQLdlmsL4Zua9diDS6B5abXG0XhFcoNsXIGMWXVZz4TOq3u4EdpXF/Q==} + engines: {node: '>=8.0.0'} + + web3-eth-accounts@1.10.4: + resolution: {integrity: sha512-ysy5sVTg9snYS7tJjxVoQAH6DTOTkRGR8emEVCWNGLGiB9txj+qDvSeT0izjurS/g7D5xlMAgrEHLK1Vi6I3yg==} + engines: {node: '>=8.0.0'} + + web3-eth-accounts@4.2.1: + resolution: {integrity: sha512-aOlEZFzqAgKprKs7+DGArU4r9b+ILBjThpeq42aY7LAQcP+mSpsWcQgbIRK3r/n3OwTYZ3aLPk0Ih70O/LwnYA==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-contract@1.10.0: + resolution: {integrity: sha512-MIC5FOzP/+2evDksQQ/dpcXhSqa/2hFNytdl/x61IeWxhh6vlFeSjq0YVTAyIzdjwnL7nEmZpjfI6y6/Ufhy7w==} + engines: {node: '>=8.0.0'} + + web3-eth-contract@1.10.4: + resolution: {integrity: sha512-Q8PfolOJ4eV9TvnTj1TGdZ4RarpSLmHnUnzVxZ/6/NiTfe4maJz99R0ISgwZkntLhLRtw0C7LRJuklzGYCNN3A==} + engines: {node: '>=8.0.0'} + + web3-eth-contract@4.7.0: + resolution: {integrity: sha512-fdStoBOjFyMHwlyJmSUt/BTDL1ATwKGmG3zDXQ/zTKlkkW/F/074ut0Vry4GuwSBg9acMHc0ycOiZx9ZKjNHsw==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-ens@1.10.0: + resolution: {integrity: sha512-3hpGgzX3qjgxNAmqdrC2YUQMTfnZbs4GeLEmy8aCWziVwogbuqQZ+Gzdfrym45eOZodk+lmXyLuAdqkNlvkc1g==} + engines: {node: '>=8.0.0'} + + web3-eth-ens@1.10.4: + resolution: {integrity: sha512-LLrvxuFeVooRVZ9e5T6OWKVflHPFgrVjJ/jtisRWcmI7KN/b64+D/wJzXqgmp6CNsMQcE7rpmf4CQmJCrTdsgg==} + engines: {node: '>=8.0.0'} + + web3-eth-ens@4.4.0: + resolution: {integrity: sha512-DeyVIS060hNV9g8dnTx92syqvgbvPricE3MerCxe/DquNZT3tD8aVgFfq65GATtpCgDDJffO2bVeHp3XBemnSQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-iban@1.10.0: + resolution: {integrity: sha512-0l+SP3IGhInw7Q20LY3IVafYEuufo4Dn75jAHT7c2aDJsIolvf2Lc6ugHkBajlwUneGfbRQs/ccYPQ9JeMUbrg==} + engines: {node: '>=8.0.0'} + + web3-eth-iban@1.10.4: + resolution: {integrity: sha512-0gE5iNmOkmtBmbKH2aTodeompnNE8jEyvwFJ6s/AF6jkw9ky9Op9cqfzS56AYAbrqEFuClsqB/AoRves7LDELw==} + engines: {node: '>=8.0.0'} + + web3-eth-iban@4.0.7: + resolution: {integrity: sha512-8weKLa9KuKRzibC87vNLdkinpUE30gn0IGY027F8doeJdcPUfsa4IlBgNC4k4HLBembBB2CTU0Kr/HAOqMeYVQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth-personal@1.10.0: + resolution: {integrity: sha512-anseKn98w/d703eWq52uNuZi7GhQeVjTC5/svrBWEKob0WZ5kPdo+EZoFN0sp5a5ubbrk/E0xSl1/M5yORMtpg==} + engines: {node: '>=8.0.0'} + + web3-eth-personal@1.10.4: + resolution: {integrity: sha512-BRa/hs6jU1hKHz+AC/YkM71RP3f0Yci1dPk4paOic53R4ZZG4MgwKRkJhgt3/GPuPliwS46f/i5A7fEGBT4F9w==} + engines: {node: '>=8.0.0'} + + web3-eth-personal@4.1.0: + resolution: {integrity: sha512-RFN83uMuvA5cu1zIwwJh9A/bAj0OBxmGN3tgx19OD/9ygeUZbifOL06jgFzN0t+1ekHqm3DXYQM8UfHpXi7yDQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-eth@1.10.0: + resolution: {integrity: sha512-Z5vT6slNMLPKuwRyKGbqeGYC87OAy8bOblaqRTgg94CXcn/mmqU7iPIlG4506YdcdK3x6cfEDG7B6w+jRxypKA==} + engines: {node: '>=8.0.0'} + + web3-eth@1.10.4: + resolution: {integrity: sha512-Sql2kYKmgt+T/cgvg7b9ce24uLS7xbFrxE4kuuor1zSCGrjhTJ5rRNG8gTJUkAJGKJc7KgnWmgW+cOfMBPUDSA==} + engines: {node: '>=8.0.0'} + + web3-eth@4.10.0: + resolution: {integrity: sha512-8d7epCOm1hv/xGnOW8pWNkO5Ze9b+LKl81Pa1VUdRi2xZKtBaQsk+4qg6EnqeDF6SPpL502wNmX6TAB69vGBWw==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-net@1.10.0: + resolution: {integrity: sha512-NLH/N3IshYWASpxk4/18Ge6n60GEvWBVeM8inx2dmZJVmRI6SJIlUxbL8jySgiTn3MMZlhbdvrGo8fpUW7a1GA==} + engines: {node: '>=8.0.0'} + + web3-net@1.10.4: + resolution: {integrity: sha512-mKINnhOOnZ4koA+yV2OT5s5ztVjIx7IY9a03w6s+yao/BUn+Luuty0/keNemZxTr1E8Ehvtn28vbOtW7Ids+Ow==} + engines: {node: '>=8.0.0'} + + web3-net@4.1.0: + resolution: {integrity: sha512-WWmfvHVIXWEoBDWdgKNYKN8rAy6SgluZ0abyRyXOL3ESr7ym7pKWbfP4fjApIHlYTh8tNqkrdPfM4Dyi6CA0SA==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-providers-http@1.10.0: + resolution: {integrity: sha512-eNr965YB8a9mLiNrkjAWNAPXgmQWfpBfkkn7tpEFlghfww0u3I0tktMZiaToJVcL2+Xq+81cxbkpeWJ5XQDwOA==} + engines: {node: '>=8.0.0'} + + web3-providers-http@1.10.4: + resolution: {integrity: sha512-m2P5Idc8hdiO0l60O6DSCPw0kw64Zgi0pMjbEFRmxKIck2Py57RQMu4bxvkxJwkF06SlGaEQF8rFZBmuX7aagQ==} + engines: {node: '>=8.0.0'} + + web3-providers-http@4.2.0: + resolution: {integrity: sha512-IPMnDtHB7dVwaB7/mMxAZzyq7d5ezfO1+Vw0bNfAeIi7gaDlJiggp85SdyAfOgov8AMUA/dyiY72kQ0KmjXKvQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-providers-ipc@1.10.0: + resolution: {integrity: sha512-OfXG1aWN8L1OUqppshzq8YISkWrYHaATW9H8eh0p89TlWMc1KZOL9vttBuaBEi96D/n0eYDn2trzt22bqHWfXA==} + engines: {node: '>=8.0.0'} + + web3-providers-ipc@1.10.4: + resolution: {integrity: sha512-YRF/bpQk9z3WwjT+A6FI/GmWRCASgd+gC0si7f9zbBWLXjwzYAKG73bQBaFRAHex1hl4CVcM5WUMaQXf3Opeuw==} + engines: {node: '>=8.0.0'} + + web3-providers-ipc@4.0.7: + resolution: {integrity: sha512-YbNqY4zUvIaK2MHr1lQFE53/8t/ejHtJchrWn9zVbFMGXlTsOAbNoIoZWROrg1v+hCBvT2c9z8xt7e/+uz5p1g==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-providers-ws@1.10.0: + resolution: {integrity: sha512-sK0fNcglW36yD5xjnjtSGBnEtf59cbw4vZzJ+CmOWIKGIR96mP5l684g0WD0Eo+f4NQc2anWWXG74lRc9OVMCQ==} + engines: {node: '>=8.0.0'} + + web3-providers-ws@1.10.4: + resolution: {integrity: sha512-j3FBMifyuFFmUIPVQR4pj+t5ILhAexAui0opgcpu9R5LxQrLRUZxHSnU+YO25UycSOa/NAX8A+qkqZNpcFAlxA==} + engines: {node: '>=8.0.0'} + + web3-providers-ws@4.0.8: + resolution: {integrity: sha512-goJdgata7v4pyzHRsg9fSegUG4gVnHZSHODhNnn6J93ykHkBI1nz4fjlGpcQLUMi4jAMz6SHl9Ibzs2jj9xqPw==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-rpc-methods@1.3.0: + resolution: {integrity: sha512-/CHmzGN+IYgdBOme7PdqzF+FNeMleefzqs0LVOduncSaqsppeOEoskLXb2anSpzmQAP3xZJPaTrkQPWSJMORig==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-rpc-providers@1.0.0-rc.2: + resolution: {integrity: sha512-ocFIEXcBx/DYQ90HhVepTBUVnL9pGsZw8wyPb1ZINSenwYus9SvcFkjU1Hfvd/fXjuhAv2bUVch9vxvMx1mXAQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-shh@1.10.0: + resolution: {integrity: sha512-uNUUuNsO2AjX41GJARV9zJibs11eq6HtOe6Wr0FtRUcj8SN6nHeYIzwstAvJ4fXA53gRqFMTxdntHEt9aXVjpg==} + engines: {node: '>=8.0.0'} + + web3-shh@1.10.4: + resolution: {integrity: sha512-cOH6iFFM71lCNwSQrC3niqDXagMqrdfFW85hC9PFUrAr3PUrIem8TNstTc3xna2bwZeWG6OBy99xSIhBvyIACw==} + engines: {node: '>=8.0.0'} + + web3-types@1.8.1: + resolution: {integrity: sha512-isspsvQbBJFUkJYz2Badb7dz/BrLLLpOop/WmnL5InyYMr7kYYc8038NYO7Vkp1M7Bupa/wg+yALvBm7EGbyoQ==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-utils@1.10.0: + resolution: {integrity: sha512-kSaCM0uMcZTNUSmn5vMEhlo02RObGNRRCkdX0V9UTAU0+lrvn0HSaudyCo6CQzuXUsnuY2ERJGCGPfeWmv19Rg==} + engines: {node: '>=8.0.0'} + + web3-utils@1.10.4: + resolution: {integrity: sha512-tsu8FiKJLk2PzhDl9fXbGUWTkkVXYhtTA+SmEFkKft+9BgwLxfCRpU96sWv7ICC8zixBNd3JURVoiR3dUXgP8A==} + engines: {node: '>=8.0.0'} + + web3-utils@4.3.2: + resolution: {integrity: sha512-bEFpYEBMf6ER78Uvj2mdsCbaLGLK9kABOsa3TtXOEEhuaMy/RK0KlRkKoZ2vmf/p3hB8e1q5erknZ6Hy7AVp7A==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3-validator@2.0.6: + resolution: {integrity: sha512-qn9id0/l1bWmvH4XfnG/JtGKKwut2Vokl6YXP5Kfg424npysmtRLe9DgiNBM9Op7QL/aSiaA0TVXibuIuWcizg==} + engines: {node: '>=14', npm: '>=6.12.0'} + + web3@0.20.6: + resolution: {integrity: sha512-diON1+Y8sPQ33htuTMZfyo+qlsmCBSYwi+MVTRneS8anqZUaTrGaBkTpPkPUvfX1X+NK+Y2spLaaei3HfXeSuw==} + + web3@0.20.7: + resolution: {integrity: sha512-VU6/DSUX93d1fCzBz7WP/SGCQizO1rKZi4Px9j/3yRyfssHyFcZamMw2/sj4E8TlfMXONvZLoforR8B4bRoyTQ==} + + web3@1.10.0: + resolution: {integrity: sha512-YfKY9wSkGcM8seO+daR89oVTcbu18NsVfvOngzqMYGUU0pPSQmE57qQDvQzUeoIOHAnXEBNzrhjQJmm8ER0rng==} + engines: {node: '>=8.0.0'} + + web3@1.10.4: + resolution: {integrity: sha512-kgJvQZjkmjOEKimx/tJQsqWfRDPTTcBfYPa9XletxuHLpHcXdx67w8EFn5AW3eVxCutE9dTVHgGa9VYe8vgsEA==} + engines: {node: '>=8.0.0'} + + web3@4.14.0: + resolution: {integrity: sha512-LohqxtSXXl4uA3abPK0bB91dziA5GygOLtO83p8bQzY+CYxp1fgGfiD8ahDRcu+WBttUhRFZmCsOhmrmP7HtTA==} + engines: {node: '>=14.0.0', npm: '>=6.12.0'} + + webauthn-p256@0.0.10: + resolution: {integrity: sha512-EeYD+gmIT80YkSIDb2iWq0lq2zbHo1CxHlQTeJ+KkCILWpVy3zASH3ByD4bopzfk0uCwXxLqKGLqp2W4O28VFA==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + websocket@1.0.35: + resolution: {integrity: sha512-/REy6amwPZl44DDzvRCkaI1q1bIiQB0mEFQLUrhz3z2EK91cp3n72rAjUlrTP0zV22HJIUOVHQGPxhFRjxjt+Q==} + engines: {node: '>=4.0.0'} + + whatwg-encoding@3.1.1: + resolution: {integrity: sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==} + engines: {node: '>=18'} + + whatwg-fetch@3.6.20: + resolution: {integrity: sha512-EqhiFU6daOA8kpjOWTL0olhVOF3i7OrFzSYiGsEMB8GcXS+RrzauAERX65xMeNWVqxA6HXH2m69Z9LaKKdisfg==} + + whatwg-mimetype@4.0.0: + resolution: {integrity: sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==} + engines: {node: '>=18'} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + which-boxed-primitive@1.0.2: + resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} + + which-module@1.0.0: + resolution: {integrity: sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==} + + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + + which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + widest-line@3.1.0: + resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} + engines: {node: '>=8'} + + window-size@0.2.0: + resolution: {integrity: sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw==} + engines: {node: '>= 0.10.0'} + hasBin: true + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + wordwrapjs@4.0.1: + resolution: {integrity: sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA==} + engines: {node: '>=8.0.0'} + + workerpool@6.2.0: + resolution: {integrity: sha512-Rsk5qQHJ9eowMH28Jwhe8HEbmdYDX4lwoMWshiCXugjtHqMD9ZbiqSDLxcsfdqsETPzVUtX5s1Z5kStiIM6l4A==} + + workerpool@6.5.1: + resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} + + wrap-ansi@2.1.0: + resolution: {integrity: sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==} + engines: {node: '>=0.10.0'} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + + ws@3.3.3: + resolution: {integrity: sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@7.4.6: + resolution: {integrity: sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + xhr-request-promise@0.1.3: + resolution: {integrity: sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg==} + + xhr-request@1.1.0: + resolution: {integrity: sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==} + + xhr2-cookies@1.1.0: + resolution: {integrity: sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g==} + + xhr2@0.2.1: + resolution: {integrity: sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw==} + engines: {node: '>= 6'} + + xhr@2.6.0: + resolution: {integrity: sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA==} + + xmlhttprequest@1.8.0: + resolution: {integrity: sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA==} + engines: {node: '>=0.4.0'} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@3.2.2: + resolution: {integrity: sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yaeti@0.0.6: + resolution: {integrity: sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug==} + engines: {node: '>=0.10.32'} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + + yallist@2.1.2: + resolution: {integrity: sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + + yargs-parser@2.4.1: + resolution: {integrity: sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA==} + + yargs-parser@20.2.4: + resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} + engines: {node: '>=10'} + + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yargs@4.8.1: + resolution: {integrity: sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA==} + + yn@3.1.1: + resolution: {integrity: sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==} + engines: {node: '>=6'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + z-schema@5.0.5: + resolution: {integrity: sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==} + engines: {node: '>=8.0.0'} + hasBin: true + + zod@3.23.8: + resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + +snapshots: + + '@adraffy/ens-normalize@1.10.1': {} + + '@adraffy/ens-normalize@1.11.0': {} + + '@ampproject/remapping@2.3.0': + dependencies: + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + + '@babel/code-frame@7.25.9': + dependencies: + '@babel/highlight': 7.25.9 + picocolors: 1.1.1 + + '@babel/code-frame@7.26.2': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.25.9': {} + + '@babel/core@7.25.9': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.25.9 + '@babel/generator': 7.25.9 + '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-module-transforms': 7.25.9(@babel/core@7.25.9) + '@babel/helpers': 7.25.9 + '@babel/parser': 7.25.9 + '@babel/template': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) + '@babel/types': 7.25.9 + convert-source-map: 2.0.0 + debug: 4.3.7(supports-color@5.5.0) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/core@7.26.0': + dependencies: + '@ampproject/remapping': 2.3.0 + '@babel/code-frame': 7.26.2 + '@babel/generator': 7.26.5 + '@babel/helper-compilation-targets': 7.25.9 + '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0) + '@babel/helpers': 7.26.0 + '@babel/parser': 7.26.5 + '@babel/template': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) + '@babel/types': 7.26.5 + convert-source-map: 2.0.0 + debug: 4.3.7(supports-color@5.5.0) + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.25.9': + dependencies: + '@babel/types': 7.25.9 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.0.2 + + '@babel/generator@7.26.5': + dependencies: + '@babel/parser': 7.26.5 + '@babel/types': 7.26.5 + '@jridgewell/gen-mapping': 0.3.5 + '@jridgewell/trace-mapping': 0.3.25 + jsesc: 3.0.2 + + '@babel/helper-annotate-as-pure@7.25.9': + dependencies: + '@babel/types': 7.25.9 + + '@babel/helper-compilation-targets@7.25.9': + dependencies: + '@babel/compat-data': 7.25.9 + '@babel/helper-validator-option': 7.25.9 + browserslist: 4.24.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-module-imports@7.25.9(supports-color@5.5.0)': + dependencies: + '@babel/traverse': 7.25.9(supports-color@5.5.0) + '@babel/types': 7.25.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.25.9(@babel/core@7.25.9)': + dependencies: + '@babel/core': 7.25.9 + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/helper-simple-access': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/helper-validator-identifier': 7.25.9 + '@babel/traverse': 7.25.9(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + + '@babel/helper-plugin-utils@7.26.5': {} + + '@babel/helper-simple-access@7.25.9': + dependencies: + '@babel/traverse': 7.25.9(supports-color@5.5.0) + '@babel/types': 7.25.9 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.25.9': {} + + '@babel/helper-validator-identifier@7.25.9': {} + + '@babel/helper-validator-option@7.25.9': {} + + '@babel/helpers@7.25.9': + dependencies: + '@babel/template': 7.25.9 + '@babel/types': 7.25.9 + + '@babel/helpers@7.26.0': + dependencies: + '@babel/template': 7.25.9 + '@babel/types': 7.26.5 + + '@babel/highlight@7.25.9': + dependencies: + '@babel/helper-validator-identifier': 7.25.9 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/parser@7.25.9': + dependencies: + '@babel/types': 7.25.9 + + '@babel/parser@7.26.5': + dependencies: + '@babel/types': 7.26.5 + + '@babel/plugin-syntax-jsx@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-transform-react-jsx-self@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/plugin-transform-react-jsx-source@7.25.9(@babel/core@7.26.0)': + dependencies: + '@babel/core': 7.26.0 + '@babel/helper-plugin-utils': 7.26.5 + + '@babel/runtime@7.25.9': + dependencies: + regenerator-runtime: 0.14.1 + + '@babel/template@7.25.9': + dependencies: + '@babel/code-frame': 7.26.2 + '@babel/parser': 7.26.5 + '@babel/types': 7.26.5 + + '@babel/traverse@7.25.9(supports-color@5.5.0)': + dependencies: + '@babel/code-frame': 7.25.9 + '@babel/generator': 7.25.9 + '@babel/parser': 7.25.9 + '@babel/template': 7.25.9 + '@babel/types': 7.25.9 + debug: 4.3.7(supports-color@5.5.0) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.25.9': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@babel/types@7.26.5': + dependencies: + '@babel/helper-string-parser': 7.25.9 + '@babel/helper-validator-identifier': 7.25.9 + + '@braintree/sanitize-url@6.0.4': {} + + '@changesets/apply-release-plan@7.0.5': + dependencies: + '@changesets/config': 3.0.3 + '@changesets/get-version-range-type': 0.4.0 + '@changesets/git': 3.0.1 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + detect-indent: 6.1.0 + fs-extra: 7.0.1 + lodash.startcase: 4.4.0 + outdent: 0.5.0 + prettier: 2.8.8 + resolve-from: 5.0.0 + semver: 7.6.3 + + '@changesets/assemble-release-plan@6.0.4': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + semver: 7.6.3 + + '@changesets/changelog-git@0.2.0': + dependencies: + '@changesets/types': 6.0.0 + + '@changesets/cli@2.27.9': + dependencies: + '@changesets/apply-release-plan': 7.0.5 + '@changesets/assemble-release-plan': 6.0.4 + '@changesets/changelog-git': 0.2.0 + '@changesets/config': 3.0.3 + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/get-release-plan': 4.0.4 + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 + '@changesets/should-skip-package': 0.1.1 + '@changesets/types': 6.0.0 + '@changesets/write': 0.3.2 + '@manypkg/get-packages': 1.1.3 + ansi-colors: 4.1.3 + ci-info: 3.9.0 + enquirer: 2.4.1 + external-editor: 3.1.0 + fs-extra: 7.0.1 + mri: 1.2.0 + p-limit: 2.3.0 + package-manager-detector: 0.2.2 + picocolors: 1.1.1 + resolve-from: 5.0.0 + semver: 7.6.3 + spawndamnit: 2.0.0 + term-size: 2.2.1 + + '@changesets/config@3.0.3': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/get-dependents-graph': 2.1.2 + '@changesets/logger': 0.1.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + micromatch: 4.0.8 + + '@changesets/errors@0.2.0': + dependencies: + extendable-error: 0.1.7 + + '@changesets/get-dependents-graph@2.1.2': + dependencies: + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + picocolors: 1.1.1 + semver: 7.6.3 + + '@changesets/get-release-plan@4.0.4': + dependencies: + '@changesets/assemble-release-plan': 6.0.4 + '@changesets/config': 3.0.3 + '@changesets/pre': 2.0.1 + '@changesets/read': 0.6.1 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/get-version-range-type@0.4.0': {} + + '@changesets/git@3.0.1': + dependencies: + '@changesets/errors': 0.2.0 + '@manypkg/get-packages': 1.1.3 + is-subdir: 1.2.0 + micromatch: 4.0.8 + spawndamnit: 2.0.0 + + '@changesets/logger@0.1.1': + dependencies: + picocolors: 1.1.1 + + '@changesets/parse@0.4.0': + dependencies: + '@changesets/types': 6.0.0 + js-yaml: 3.14.1 + + '@changesets/pre@2.0.1': + dependencies: + '@changesets/errors': 0.2.0 + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + fs-extra: 7.0.1 + + '@changesets/read@0.6.1': + dependencies: + '@changesets/git': 3.0.1 + '@changesets/logger': 0.1.1 + '@changesets/parse': 0.4.0 + '@changesets/types': 6.0.0 + fs-extra: 7.0.1 + p-filter: 2.1.0 + picocolors: 1.1.1 + + '@changesets/should-skip-package@0.1.1': + dependencies: + '@changesets/types': 6.0.0 + '@manypkg/get-packages': 1.1.3 + + '@changesets/types@4.1.0': {} + + '@changesets/types@6.0.0': {} + + '@changesets/write@0.3.2': + dependencies: + '@changesets/types': 6.0.0 + fs-extra: 7.0.1 + human-id: 1.0.2 + prettier: 2.8.8 + + '@cspotcode/source-map-support@0.8.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.9 + + '@emotion/is-prop-valid@1.3.1': + dependencies: + '@emotion/memoize': 0.9.0 + + '@emotion/memoize@0.9.0': {} + + '@emotion/stylis@0.8.5': {} + + '@emotion/unitless@0.7.5': {} + + '@ensdomains/address-encoder@0.1.9': + dependencies: + bech32: 1.1.4 + blakejs: 1.2.1 + bn.js: 4.12.0 + bs58: 4.0.1 + crypto-addr-codec: 0.1.8 + nano-base32: 1.0.1 + ripemd160: 2.0.2 + + '@ensdomains/ens@0.4.5': + dependencies: + bluebird: 3.7.2 + eth-ens-namehash: 2.0.8 + solc: 0.4.26 + testrpc: 0.0.1 + web3-utils: 1.10.4 + + '@ensdomains/ensjs@2.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@babel/runtime': 7.25.9 + '@ensdomains/address-encoder': 0.1.9 + '@ensdomains/ens': 0.4.5 + '@ensdomains/resolver': 0.2.4 + content-hash: 2.5.2 + eth-ens-namehash: 2.0.8 + ethers: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + js-sha3: 0.8.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@ensdomains/resolver@0.2.4': {} + + '@esbuild/aix-ppc64@0.21.5': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/win32-arm64@0.21.5': + optional: true + + '@esbuild/win32-ia32@0.21.5': + optional: true + + '@esbuild/win32-x64@0.21.5': + optional: true + + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.1)': + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.11.1': {} + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.12.6 + debug: 4.3.7(supports-color@5.5.0) + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.0 + js-yaml: 4.1.0 + minimatch: 3.1.2 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.1': {} + + '@ethereumjs/common@2.5.0': + dependencies: + crc-32: 1.2.2 + ethereumjs-util: 7.1.5 + + '@ethereumjs/common@2.6.5': + dependencies: + crc-32: 1.2.2 + ethereumjs-util: 7.1.5 + + '@ethereumjs/rlp@4.0.1': {} + + '@ethereumjs/rlp@5.0.2': {} + + '@ethereumjs/tx@3.3.2': + dependencies: + '@ethereumjs/common': 2.6.5 + ethereumjs-util: 7.1.5 + + '@ethereumjs/tx@3.5.2': + dependencies: + '@ethereumjs/common': 2.6.5 + ethereumjs-util: 7.1.5 + + '@ethereumjs/util@8.1.0': + dependencies: + '@ethereumjs/rlp': 4.0.1 + ethereum-cryptography: 2.2.1 + micro-ftch: 0.3.1 + + '@ethereumjs/util@9.1.0': + dependencies: + '@ethereumjs/rlp': 5.0.2 + ethereum-cryptography: 2.2.1 + + '@ethersproject/abi@5.7.0': + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/abstract-provider@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/properties': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/web': 5.7.1 + + '@ethersproject/abstract-signer@5.7.0': + dependencies: + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + + '@ethersproject/address@5.6.1': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/rlp': 5.7.0 + + '@ethersproject/address@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/rlp': 5.7.0 + + '@ethersproject/base64@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + + '@ethersproject/basex@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/properties': 5.7.0 + + '@ethersproject/bignumber@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + bn.js: 5.2.1 + + '@ethersproject/bytes@5.7.0': + dependencies: + '@ethersproject/logger': 5.7.0 + + '@ethersproject/constants@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + + '@ethersproject/contracts@5.7.0': + dependencies: + '@ethersproject/abi': 5.7.0 + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/transactions': 5.7.0 + + '@ethersproject/hash@5.7.0': + dependencies: + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/hdnode@5.7.0': + dependencies: + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/basex': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/pbkdf2': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/wordlists': 5.7.0 + + '@ethersproject/json-wallets@5.7.0': + dependencies: + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/hdnode': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/pbkdf2': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/random': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + aes-js: 3.0.0 + scrypt-js: 3.0.1 + + '@ethersproject/keccak256@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + js-sha3: 0.8.0 + + '@ethersproject/logger@5.7.0': {} + + '@ethersproject/networks@5.7.1': + dependencies: + '@ethersproject/logger': 5.7.0 + + '@ethersproject/pbkdf2@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/sha2': 5.7.0 + + '@ethersproject/properties@5.7.0': + dependencies: + '@ethersproject/logger': 5.7.0 + + '@ethersproject/providers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/basex': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/properties': 5.7.0 + '@ethersproject/random': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/web': 5.7.1 + bech32: 1.1.4 + ws: 7.4.6(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@ethersproject/random@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/rlp@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/sha2@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + hash.js: 1.1.7 + + '@ethersproject/signing-key@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + bn.js: 5.2.1 + elliptic: 6.5.4 + hash.js: 1.1.7 + + '@ethersproject/solidity@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/strings@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/transactions@5.7.0': + dependencies: + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + + '@ethersproject/units@5.7.0': + dependencies: + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/logger': 5.7.0 + + '@ethersproject/wallet@5.7.0': + dependencies: + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/hdnode': 5.7.0 + '@ethersproject/json-wallets': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/random': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/wordlists': 5.7.0 + + '@ethersproject/web@5.7.1': + dependencies: + '@ethersproject/base64': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@ethersproject/wordlists@5.7.0': + dependencies: + '@ethersproject/bytes': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/strings': 5.7.0 + + '@fastify/busboy@2.1.1': {} + + '@floating-ui/core@1.6.9': + dependencies: + '@floating-ui/utils': 0.2.9 + + '@floating-ui/dom@1.6.13': + dependencies: + '@floating-ui/core': 1.6.9 + '@floating-ui/utils': 0.2.9 + + '@floating-ui/utils@0.2.9': {} + + '@fontsource/roboto@5.1.1': {} + + '@fvictorio/tabtab@0.0.3': + dependencies: + debug: 4.3.7(supports-color@5.5.0) + enquirer: 2.4.1 + minimist: 1.2.8 + mkdirp: 1.0.4 + untildify: 4.0.0 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/config-array@0.13.0': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.3.7(supports-color@5.5.0) + minimatch: 3.1.2 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.1 + resolve-from: 5.0.0 + + '@istanbuljs/nyc-config-typescript@1.0.2(nyc@15.1.0)': + dependencies: + '@istanbuljs/schema': 0.1.3 + nyc: 15.1.0 + + '@istanbuljs/schema@0.1.3': {} + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.8 + + '@jridgewell/gen-mapping@0.3.5': + dependencies: + '@jridgewell/set-array': 1.2.1 + '@jridgewell/sourcemap-codec': 1.5.0 + '@jridgewell/trace-mapping': 0.3.25 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/set-array@1.2.1': {} + + '@jridgewell/sourcemap-codec@1.5.0': {} + + '@jridgewell/trace-mapping@0.3.25': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@jridgewell/trace-mapping@0.3.9': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.0 + + '@json-schema-spec/json-pointer@0.1.2': {} + + '@json-schema-tools/dereferencer@1.6.3': + dependencies: + '@json-schema-tools/reference-resolver': 1.2.6 + '@json-schema-tools/traverse': 1.10.4 + fast-safe-stringify: 2.1.1 + transitivePeerDependencies: + - encoding + + '@json-schema-tools/meta-schema@1.7.5': {} + + '@json-schema-tools/reference-resolver@1.2.6': + dependencies: + '@json-schema-spec/json-pointer': 0.1.2 + isomorphic-fetch: 3.0.0 + transitivePeerDependencies: + - encoding + + '@json-schema-tools/referencer@1.1.3': + dependencies: + '@json-schema-tools/traverse': 1.10.4 + + '@json-schema-tools/titleizer@1.0.9': + dependencies: + '@json-schema-tools/traverse': 1.10.4 + + '@json-schema-tools/transpiler@1.10.5': + dependencies: + '@json-schema-tools/referencer': 1.1.3 + '@json-schema-tools/titleizer': 1.0.9 + '@json-schema-tools/traverse': 1.10.4 + lodash.camelcase: 4.3.0 + lodash.deburr: 4.1.0 + lodash.snakecase: 4.1.1 + lodash.trim: 4.5.1 + + '@json-schema-tools/traverse@1.10.4': {} + + '@ledgerhq/cryptoassets@9.13.0': + dependencies: + invariant: 2.2.4 + + '@ledgerhq/devices@8.4.4': + dependencies: + '@ledgerhq/errors': 6.19.1 + '@ledgerhq/logs': 6.12.0 + rxjs: 7.8.1 + semver: 7.6.3 + + '@ledgerhq/domain-service@1.2.9(debug@4.3.7)': + dependencies: + '@ledgerhq/errors': 6.19.1 + '@ledgerhq/logs': 6.12.0 + '@ledgerhq/types-live': 6.52.3 + axios: 1.7.7(debug@4.3.7) + eip55: 2.1.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + transitivePeerDependencies: + - debug + + '@ledgerhq/errors@6.19.1': {} + + '@ledgerhq/hw-app-eth@6.33.6(debug@4.3.7)': + dependencies: + '@ethersproject/abi': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ledgerhq/cryptoassets': 9.13.0 + '@ledgerhq/domain-service': 1.2.9(debug@4.3.7) + '@ledgerhq/errors': 6.19.1 + '@ledgerhq/hw-transport': 6.31.4 + '@ledgerhq/hw-transport-mocker': 6.29.4 + '@ledgerhq/logs': 6.12.0 + axios: 1.7.7(debug@4.3.7) + bignumber.js: 9.1.2 + crypto-js: 4.2.0 + transitivePeerDependencies: + - debug + + '@ledgerhq/hw-transport-mocker@6.29.4': + dependencies: + '@ledgerhq/hw-transport': 6.31.4 + '@ledgerhq/logs': 6.12.0 + rxjs: 7.8.1 + + '@ledgerhq/hw-transport-node-hid-noevents@6.30.5': + dependencies: + '@ledgerhq/devices': 8.4.4 + '@ledgerhq/errors': 6.19.1 + '@ledgerhq/hw-transport': 6.31.4 + '@ledgerhq/logs': 6.12.0 + node-hid: 2.1.2 + + '@ledgerhq/hw-transport-node-hid@6.29.5': + dependencies: + '@ledgerhq/devices': 8.4.4 + '@ledgerhq/errors': 6.19.1 + '@ledgerhq/hw-transport': 6.31.4 + '@ledgerhq/hw-transport-node-hid-noevents': 6.30.5 + '@ledgerhq/logs': 6.12.0 + lodash: 4.17.21 + node-hid: 2.1.2 + usb: 2.9.0 + + '@ledgerhq/hw-transport@6.31.4': + dependencies: + '@ledgerhq/devices': 8.4.4 + '@ledgerhq/errors': 6.19.1 + '@ledgerhq/logs': 6.12.0 + events: 3.3.0 + + '@ledgerhq/logs@6.12.0': {} + + '@ledgerhq/types-live@6.52.3': + dependencies: + bignumber.js: 9.2.1 + rxjs: 7.8.1 + + '@manypkg/find-root@1.1.0': + dependencies: + '@babel/runtime': 7.25.9 + '@types/node': 12.20.55 + find-up: 4.1.0 + fs-extra: 8.1.0 + + '@manypkg/get-packages@1.1.3': + dependencies: + '@babel/runtime': 7.25.9 + '@changesets/types': 4.1.0 + '@manypkg/find-root': 1.1.0 + fs-extra: 8.1.0 + globby: 11.1.0 + read-yaml-file: 1.1.0 + + '@microsoft/api-extractor-model@7.28.9(@types/node@18.19.59)': + dependencies: + '@microsoft/tsdoc': 0.14.2 + '@microsoft/tsdoc-config': 0.16.2 + '@rushstack/node-core-library': 3.66.0(@types/node@18.19.59) + transitivePeerDependencies: + - '@types/node' + + '@microsoft/api-extractor@7.40.1(@types/node@18.19.59)': + dependencies: + '@microsoft/api-extractor-model': 7.28.9(@types/node@18.19.59) + '@microsoft/tsdoc': 0.14.2 + '@microsoft/tsdoc-config': 0.16.2 + '@rushstack/node-core-library': 3.66.0(@types/node@18.19.59) + '@rushstack/rig-package': 0.5.1 + '@rushstack/ts-command-line': 4.17.1 + colors: 1.2.5 + lodash: 4.17.21 + resolve: 1.22.8 + semver: 7.5.4 + source-map: 0.6.1 + typescript: 5.3.3 + transitivePeerDependencies: + - '@types/node' + + '@microsoft/tsdoc-config@0.16.2': + dependencies: + '@microsoft/tsdoc': 0.14.2 + ajv: 6.12.6 + jju: 1.4.0 + resolve: 1.19.0 + + '@microsoft/tsdoc@0.14.2': {} + + '@noble/curves@1.2.0': + dependencies: + '@noble/hashes': 1.3.2 + + '@noble/curves@1.4.2': + dependencies: + '@noble/hashes': 1.4.0 + + '@noble/curves@1.6.0': + dependencies: + '@noble/hashes': 1.5.0 + + '@noble/curves@1.8.1': + dependencies: + '@noble/hashes': 1.7.1 + + '@noble/hashes@1.2.0': {} + + '@noble/hashes@1.3.2': {} + + '@noble/hashes@1.4.0': {} + + '@noble/hashes@1.5.0': {} + + '@noble/hashes@1.7.1': {} + + '@noble/secp256k1@1.7.1': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.17.1 + + '@nolyfill/is-core-module@1.0.39': {} + + '@nomicfoundation/edr-darwin-arm64@0.11.0': {} + + '@nomicfoundation/edr-darwin-x64@0.11.0': {} + + '@nomicfoundation/edr-linux-arm64-gnu@0.11.0': {} + + '@nomicfoundation/edr-linux-arm64-musl@0.11.0': {} + + '@nomicfoundation/edr-linux-x64-gnu@0.11.0': {} + + '@nomicfoundation/edr-linux-x64-musl@0.11.0': {} + + '@nomicfoundation/edr-win32-x64-msvc@0.11.0': {} + + '@nomicfoundation/edr@0.11.0': + dependencies: + '@nomicfoundation/edr-darwin-arm64': 0.11.0 + '@nomicfoundation/edr-darwin-x64': 0.11.0 + '@nomicfoundation/edr-linux-arm64-gnu': 0.11.0 + '@nomicfoundation/edr-linux-arm64-musl': 0.11.0 + '@nomicfoundation/edr-linux-x64-gnu': 0.11.0 + '@nomicfoundation/edr-linux-x64-musl': 0.11.0 + '@nomicfoundation/edr-win32-x64-msvc': 0.11.0 + + '@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-darwin-x64@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.2': + optional: true + + '@nomicfoundation/solidity-analyzer@0.1.2': + optionalDependencies: + '@nomicfoundation/solidity-analyzer-darwin-arm64': 0.1.2 + '@nomicfoundation/solidity-analyzer-darwin-x64': 0.1.2 + '@nomicfoundation/solidity-analyzer-linux-arm64-gnu': 0.1.2 + '@nomicfoundation/solidity-analyzer-linux-arm64-musl': 0.1.2 + '@nomicfoundation/solidity-analyzer-linux-x64-gnu': 0.1.2 + '@nomicfoundation/solidity-analyzer-linux-x64-musl': 0.1.2 + '@nomicfoundation/solidity-analyzer-win32-x64-msvc': 0.1.2 + + '@nomiclabs/truffle-contract@4.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10)(web3-core-helpers@1.10.4)(web3-core-promievent@1.10.4)(web3-eth-abi@1.10.4)(web3-utils@1.10.4)(web3@1.10.4(bufferutil@4.0.8)(utf-8-validate@5.0.10))': + dependencies: + '@ensdomains/ensjs': 2.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@truffle/blockchain-utils': 0.1.9 + '@truffle/contract-schema': 3.4.16 + '@truffle/debug-utils': 6.0.57 + '@truffle/error': 0.1.1 + '@truffle/interface-adapter': 0.5.37(bufferutil@4.0.8)(utf-8-validate@5.0.10) + bignumber.js: 7.2.1 + ethereum-ens: 0.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + ethers: 4.0.49 + source-map-support: 0.5.21 + web3: 1.10.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-core-helpers: 1.10.4 + web3-core-promievent: 1.10.4 + web3-eth-abi: 1.10.4 + web3-utils: 1.10.4 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@open-rpc/meta-schema@1.14.9': {} + + '@open-rpc/schema-utils-js@2.0.2': + dependencies: + '@json-schema-tools/dereferencer': 1.6.3 + '@json-schema-tools/meta-schema': 1.7.5 + '@json-schema-tools/reference-resolver': 1.2.6 + '@open-rpc/meta-schema': 1.14.9 + ajv: 6.12.6 + detect-node: 2.1.0 + fast-safe-stringify: 2.1.1 + fs-extra: 10.1.0 + is-url: 1.2.4 + isomorphic-fetch: 3.0.0 + transitivePeerDependencies: + - encoding + + '@open-rpc/typings@1.12.4': + dependencies: + '@json-schema-tools/titleizer': 1.0.9 + '@json-schema-tools/transpiler': 1.10.5 + '@open-rpc/schema-utils-js': 2.0.2 + commander: 6.2.1 + fs-extra: 10.1.0 + transitivePeerDependencies: + - encoding + + '@pnpm/config.env-replace@1.1.0': {} + + '@pnpm/network.ca-file@1.0.2': + dependencies: + graceful-fs: 4.2.10 + + '@pnpm/npm-conf@2.3.1': + dependencies: + '@pnpm/config.env-replace': 1.1.0 + '@pnpm/network.ca-file': 1.0.2 + config-chain: 1.1.13 + + '@remix-run/router@1.6.0': {} + + '@rollup/rollup-android-arm-eabi@4.39.0': + optional: true + + '@rollup/rollup-android-arm64@4.39.0': + optional: true + + '@rollup/rollup-darwin-arm64@4.39.0': + optional: true + + '@rollup/rollup-darwin-x64@4.39.0': + optional: true + + '@rollup/rollup-freebsd-arm64@4.39.0': + optional: true + + '@rollup/rollup-freebsd-x64@4.39.0': + optional: true + + '@rollup/rollup-linux-arm-gnueabihf@4.39.0': + optional: true + + '@rollup/rollup-linux-arm-musleabihf@4.39.0': + optional: true + + '@rollup/rollup-linux-arm64-gnu@4.39.0': + optional: true + + '@rollup/rollup-linux-arm64-musl@4.39.0': + optional: true + + '@rollup/rollup-linux-loongarch64-gnu@4.39.0': + optional: true + + '@rollup/rollup-linux-powerpc64le-gnu@4.39.0': + optional: true + + '@rollup/rollup-linux-riscv64-gnu@4.39.0': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.39.0': + optional: true + + '@rollup/rollup-linux-s390x-gnu@4.39.0': + optional: true + + '@rollup/rollup-linux-x64-gnu@4.39.0': + optional: true + + '@rollup/rollup-linux-x64-musl@4.39.0': + optional: true + + '@rollup/rollup-win32-arm64-msvc@4.39.0': + optional: true + + '@rollup/rollup-win32-ia32-msvc@4.39.0': + optional: true + + '@rollup/rollup-win32-x64-msvc@4.39.0': + optional: true + + '@rushstack/node-core-library@3.66.0(@types/node@18.19.59)': + dependencies: + colors: 1.2.5 + fs-extra: 7.0.1 + import-lazy: 4.0.0 + jju: 1.4.0 + resolve: 1.22.8 + semver: 7.5.4 + z-schema: 5.0.5 + optionalDependencies: + '@types/node': 18.19.59 + + '@rushstack/rig-package@0.5.1': + dependencies: + resolve: 1.22.8 + strip-json-comments: 3.1.1 + + '@rushstack/ts-command-line@4.17.1': + dependencies: + '@types/argparse': 1.0.38 + argparse: 1.0.10 + colors: 1.2.5 + string-argv: 0.3.2 + + '@scure/base@1.1.9': {} + + '@scure/base@1.2.4': {} + + '@scure/bip32@1.1.5': + dependencies: + '@noble/hashes': 1.2.0 + '@noble/secp256k1': 1.7.1 + '@scure/base': 1.1.9 + + '@scure/bip32@1.4.0': + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.9 + + '@scure/bip32@1.5.0': + dependencies: + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@scure/base': 1.1.9 + + '@scure/bip39@1.1.1': + dependencies: + '@noble/hashes': 1.2.0 + '@scure/base': 1.1.9 + + '@scure/bip39@1.3.0': + dependencies: + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.9 + + '@scure/bip39@1.4.0': + dependencies: + '@noble/hashes': 1.5.0 + '@scure/base': 1.1.9 + + '@sentry/core@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/minimal': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/hub@5.30.0': + dependencies: + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/minimal@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/types': 5.30.0 + tslib: 1.14.1 + + '@sentry/node@5.30.0': + dependencies: + '@sentry/core': 5.30.0 + '@sentry/hub': 5.30.0 + '@sentry/tracing': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + cookie: 0.4.2 + https-proxy-agent: 5.0.1 + lru_map: 0.3.3 + tslib: 1.14.1 + transitivePeerDependencies: + - supports-color + + '@sentry/tracing@5.30.0': + dependencies: + '@sentry/hub': 5.30.0 + '@sentry/minimal': 5.30.0 + '@sentry/types': 5.30.0 + '@sentry/utils': 5.30.0 + tslib: 1.14.1 + + '@sentry/types@5.30.0': {} + + '@sentry/utils@5.30.0': + dependencies: + '@sentry/types': 5.30.0 + tslib: 1.14.1 + + '@sinclair/typebox@0.27.8': {} + + '@sindresorhus/is@4.6.0': {} + + '@sindresorhus/is@5.6.0': {} + + '@sinonjs/commons@1.8.6': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/commons@2.0.0': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/commons@3.0.1': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/fake-timers@11.3.1': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@sinonjs/fake-timers@6.0.1': + dependencies: + '@sinonjs/commons': 1.8.6 + + '@sinonjs/fake-timers@9.1.2': + dependencies: + '@sinonjs/commons': 1.8.6 + + '@sinonjs/samsam@5.3.1': + dependencies: + '@sinonjs/commons': 1.8.6 + lodash.get: 4.4.2 + type-detect: 4.1.0 + + '@sinonjs/samsam@7.0.1': + dependencies: + '@sinonjs/commons': 2.0.0 + lodash.get: 4.4.2 + type-detect: 4.1.0 + + '@sinonjs/text-encoding@0.7.3': {} + + '@solidity-parser/parser@0.14.5': + dependencies: + antlr4ts: 0.5.0-alpha.4 + + '@solidity-parser/parser@0.18.0': {} + + '@szmarczak/http-timer@4.0.6': + dependencies: + defer-to-connect: 2.0.1 + + '@szmarczak/http-timer@5.0.1': + dependencies: + defer-to-connect: 2.0.1 + + '@truffle/abi-utils@1.0.3': + dependencies: + change-case: 3.0.2 + fast-check: 3.1.1 + web3-utils: 1.10.0 + + '@truffle/blockchain-utils@0.1.9': {} + + '@truffle/codec@0.17.3': + dependencies: + '@truffle/abi-utils': 1.0.3 + '@truffle/compile-common': 0.9.8 + big.js: 6.2.2 + bn.js: 5.2.1 + cbor: 5.2.0 + debug: 4.3.7(supports-color@5.5.0) + lodash: 4.17.21 + semver: 7.6.3 + utf8: 3.0.0 + web3-utils: 1.10.0 + transitivePeerDependencies: + - supports-color + + '@truffle/compile-common@0.9.8': + dependencies: + '@truffle/error': 0.2.2 + colors: 1.4.0 + + '@truffle/contract-schema@3.4.16': + dependencies: + ajv: 6.12.6 + debug: 4.3.7(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + + '@truffle/debug-utils@6.0.57': + dependencies: + '@truffle/codec': 0.17.3 + '@trufflesuite/chromafi': 3.0.0 + bn.js: 5.2.1 + chalk: 2.4.2 + debug: 4.3.7(supports-color@5.5.0) + highlightjs-solidity: 2.0.6 + transitivePeerDependencies: + - supports-color + + '@truffle/error@0.1.1': {} + + '@truffle/error@0.2.2': {} + + '@truffle/interface-adapter@0.5.37(bufferutil@4.0.8)(utf-8-validate@5.0.10)': + dependencies: + bn.js: 5.2.1 + ethers: 4.0.49 + web3: 1.10.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@trufflesuite/chromafi@3.0.0': + dependencies: + camelcase: 4.1.0 + chalk: 2.4.2 + cheerio: 1.0.0 + detect-indent: 5.0.0 + highlight.js: 10.7.3 + lodash.merge: 4.6.2 + strip-ansi: 4.0.0 + strip-indent: 2.0.0 + + '@tsconfig/node10@1.0.11': {} + + '@tsconfig/node12@1.0.11': {} + + '@tsconfig/node14@1.0.3': {} + + '@tsconfig/node16@1.0.4': {} + + '@typechain/ethers-v6@0.5.1(ethers@6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.0.4))(typescript@5.0.4)': + dependencies: + ethers: 6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + lodash: 4.17.21 + ts-essentials: 7.0.3(typescript@5.0.4) + typechain: 8.3.2(typescript@5.0.4) + typescript: 5.0.4 + + '@typechain/hardhat@9.1.0(@typechain/ethers-v6@0.5.1(ethers@6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.0.4))(typescript@5.0.4))(ethers@6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10))(hardhat@packages+hardhat-core)(typechain@8.3.2(typescript@5.0.4))': + dependencies: + '@typechain/ethers-v6': 0.5.1(ethers@6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10))(typechain@8.3.2(typescript@5.0.4))(typescript@5.0.4) + ethers: 6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + fs-extra: 9.1.0 + hardhat: link:packages/hardhat-core + typechain: 8.3.2(typescript@5.0.4) + + '@types/argparse@1.0.38': {} + + '@types/async-eventemitter@0.2.4': + dependencies: + '@types/events': 3.0.3 + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.25.9 + '@babel/types': 7.25.9 + '@types/babel__generator': 7.6.8 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.20.6 + + '@types/babel__generator@7.6.8': + dependencies: + '@babel/types': 7.25.9 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.25.9 + '@babel/types': 7.25.9 + + '@types/babel__traverse@7.20.6': + dependencies: + '@babel/types': 7.25.9 + + '@types/bn.js@4.11.6': + dependencies: + '@types/node': 18.19.59 + + '@types/bn.js@5.1.6': + dependencies: + '@types/node': 18.19.59 + + '@types/cacheable-request@6.0.3': + dependencies: + '@types/http-cache-semantics': 4.0.4 + '@types/keyv': 3.1.4 + '@types/node': 18.19.59 + '@types/responselike': 1.0.3 + + '@types/chai-as-promised@7.1.8': + dependencies: + '@types/chai': 4.3.20 + + '@types/chai@4.3.20': {} + + '@types/ci-info@2.0.0': {} + + '@types/concat-stream@1.6.1': + dependencies: + '@types/node': 18.19.59 + + '@types/d3-scale-chromatic@3.1.0': {} + + '@types/d3-scale@4.0.8': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-time@3.0.4': {} + + '@types/debug@4.1.12': + dependencies: + '@types/ms': 0.7.34 + + '@types/estree@1.0.7': {} + + '@types/events@3.0.3': {} + + '@types/form-data@0.0.33': + dependencies: + '@types/node': 18.19.59 + + '@types/fs-extra@5.1.0': + dependencies: + '@types/node': 18.19.59 + + '@types/fs-extra@9.0.13': + dependencies: + '@types/node': 18.19.59 + + '@types/glob@7.2.0': + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 18.19.59 + + '@types/hoist-non-react-statics@3.3.6': + dependencies: + '@types/react': 18.3.18 + hoist-non-react-statics: 3.3.2 + + '@types/http-cache-semantics@4.0.4': {} + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/keccak@3.0.5': + dependencies: + '@types/node': 18.19.59 + + '@types/keyv@3.1.4': + dependencies: + '@types/node': 18.19.59 + + '@types/lodash.clonedeep@4.5.9': + dependencies: + '@types/lodash': 4.17.12 + + '@types/lodash.isequal@4.5.8': + dependencies: + '@types/lodash': 4.17.12 + + '@types/lodash.memoize@4.1.9': + dependencies: + '@types/lodash': 4.17.12 + + '@types/lodash@4.17.12': {} + + '@types/lru-cache@5.1.1': {} + + '@types/mdast@3.0.15': + dependencies: + '@types/unist': 2.0.11 + + '@types/minimatch@5.1.2': {} + + '@types/mocha@10.0.9': {} + + '@types/mocha@9.1.1': {} + + '@types/ms@0.7.34': {} + + '@types/ndjson@2.0.1': + dependencies: + '@types/node': 18.19.59 + '@types/through': 0.0.33 + + '@types/node@10.17.60': {} + + '@types/node@12.20.55': {} + + '@types/node@18.19.59': + dependencies: + undici-types: 5.26.5 + + '@types/node@22.7.5': + dependencies: + undici-types: 6.19.8 + + '@types/node@8.10.66': {} + + '@types/pbkdf2@3.1.2': + dependencies: + '@types/node': 18.19.59 + + '@types/prettier@2.7.3': {} + + '@types/prompts@2.4.9': + dependencies: + '@types/node': 18.19.59 + kleur: 3.0.3 + + '@types/prop-types@15.7.14': {} + + '@types/qs@6.9.16': {} + + '@types/react-dom@18.3.5(@types/react@18.3.18)': + dependencies: + '@types/react': 18.3.18 + + '@types/react@18.3.18': + dependencies: + '@types/prop-types': 15.7.14 + csstype: 3.1.3 + + '@types/resolve@1.20.6': {} + + '@types/responselike@1.0.3': + dependencies: + '@types/node': 18.19.59 + + '@types/secp256k1@4.0.6': + dependencies: + '@types/node': 18.19.59 + + '@types/semver@6.2.7': {} + + '@types/semver@7.5.8': {} + + '@types/sinon-chai@3.2.12': + dependencies: + '@types/chai': 4.3.20 + '@types/sinon': 9.0.11 + + '@types/sinon@10.0.20': + dependencies: + '@types/sinonjs__fake-timers': 8.1.5 + + '@types/sinon@9.0.11': + dependencies: + '@types/sinonjs__fake-timers': 8.1.5 + + '@types/sinonjs__fake-timers@8.1.5': {} + + '@types/styled-components@5.1.26': + dependencies: + '@types/hoist-non-react-statics': 3.3.6 + '@types/react': 18.3.18 + csstype: 3.1.3 + + '@types/through@0.0.33': + dependencies: + '@types/node': 18.19.59 + + '@types/unist@2.0.11': {} + + '@types/uuid@8.3.4': {} + + '@types/w3c-web-usb@1.0.10': {} + + '@types/ws@7.4.7': + dependencies: + '@types/node': 18.19.59 + + '@types/ws@8.5.3': + dependencies: + '@types/node': 18.19.59 + + '@typescript-eslint/eslint-plugin@5.61.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1)(typescript@5.0.4)': + dependencies: + '@eslint-community/regexpp': 4.11.1 + '@typescript-eslint/parser': 5.61.0(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/scope-manager': 5.61.0 + '@typescript-eslint/type-utils': 5.61.0(eslint@8.57.1)(typescript@5.0.4) + '@typescript-eslint/utils': 5.61.0(eslint@8.57.1)(typescript@5.0.4) + debug: 4.3.7(supports-color@5.5.0) + eslint: 8.57.1 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare-lite: 1.4.0 + semver: 7.6.3 + tsutils: 3.21.0(typescript@5.0.4) + optionalDependencies: + typescript: 5.0.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/experimental-utils@5.62.0(eslint@8.57.1)(typescript@5.0.4)': + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.0.4) + eslint: 8.57.1 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4)': + dependencies: + '@typescript-eslint/scope-manager': 5.61.0 + '@typescript-eslint/types': 5.61.0 + '@typescript-eslint/typescript-estree': 5.61.0(typescript@5.0.4) + debug: 4.3.7(supports-color@5.5.0) + eslint: 8.57.1 + optionalDependencies: + typescript: 5.0.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@5.61.0': + dependencies: + '@typescript-eslint/types': 5.61.0 + '@typescript-eslint/visitor-keys': 5.61.0 + + '@typescript-eslint/scope-manager@5.62.0': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + + '@typescript-eslint/type-utils@5.61.0(eslint@8.57.1)(typescript@5.0.4)': + dependencies: + '@typescript-eslint/typescript-estree': 5.61.0(typescript@5.0.4) + '@typescript-eslint/utils': 5.61.0(eslint@8.57.1)(typescript@5.0.4) + debug: 4.3.7(supports-color@5.5.0) + eslint: 8.57.1 + tsutils: 3.21.0(typescript@5.0.4) + optionalDependencies: + typescript: 5.0.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@5.61.0': {} + + '@typescript-eslint/types@5.62.0': {} + + '@typescript-eslint/typescript-estree@5.61.0(typescript@5.0.4)': + dependencies: + '@typescript-eslint/types': 5.61.0 + '@typescript-eslint/visitor-keys': 5.61.0 + debug: 4.3.7(supports-color@5.5.0) + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.6.3 + tsutils: 3.21.0(typescript@5.0.4) + optionalDependencies: + typescript: 5.0.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/typescript-estree@5.62.0(typescript@5.0.4)': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + debug: 4.3.7(supports-color@5.5.0) + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.6.3 + tsutils: 3.21.0(typescript@5.0.4) + optionalDependencies: + typescript: 5.0.4 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/typescript-estree@5.62.0(typescript@5.3.3)': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + debug: 4.3.7(supports-color@5.5.0) + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.6.3 + tsutils: 3.21.0(typescript@5.3.3) + optionalDependencies: + typescript: 5.3.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@5.61.0(eslint@8.57.1)(typescript@5.0.4)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 5.61.0 + '@typescript-eslint/types': 5.61.0 + '@typescript-eslint/typescript-estree': 5.61.0(typescript@5.0.4) + eslint: 8.57.1 + eslint-scope: 5.1.1 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@5.0.4)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.0.4) + eslint: 8.57.1 + eslint-scope: 5.1.1 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@5.3.3)': + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.3.3) + eslint: 8.57.1 + eslint-scope: 5.1.1 + semver: 7.6.3 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/visitor-keys@5.61.0': + dependencies: + '@typescript-eslint/types': 5.61.0 + eslint-visitor-keys: 3.4.3 + + '@typescript-eslint/visitor-keys@5.62.0': + dependencies: + '@typescript-eslint/types': 5.62.0 + eslint-visitor-keys: 3.4.3 + + '@ungap/promise-all-settled@1.1.2': {} + + '@ungap/structured-clone@1.2.0': {} + + '@vitejs/plugin-react@4.3.4(vite@5.4.17(@types/node@22.7.5))': + dependencies: + '@babel/core': 7.26.0 + '@babel/plugin-transform-react-jsx-self': 7.25.9(@babel/core@7.26.0) + '@babel/plugin-transform-react-jsx-source': 7.25.9(@babel/core@7.26.0) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.2 + vite: 5.4.17(@types/node@22.7.5) + transitivePeerDependencies: + - supports-color + + abbrev@1.0.9: {} + + abitype@0.7.1(typescript@5.0.4)(zod@3.23.8): + dependencies: + typescript: 5.0.4 + optionalDependencies: + zod: 3.23.8 + + abitype@0.9.10(typescript@5.0.4)(zod@3.23.8): + optionalDependencies: + typescript: 5.0.4 + zod: 3.23.8 + + abitype@1.0.6(typescript@5.0.4)(zod@3.23.8): + optionalDependencies: + typescript: 5.0.4 + zod: 3.23.8 + + abortcontroller-polyfill@1.7.5: {} + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-jsx@5.3.2(acorn@8.13.0): + dependencies: + acorn: 8.13.0 + + acorn-walk@8.3.4: + dependencies: + acorn: 8.13.0 + + acorn@8.13.0: {} + + address@1.2.2: {} + + adm-zip@0.4.16: {} + + aes-js@3.0.0: {} + + aes-js@4.0.0-beta.5: {} + + agent-base@6.0.2: + dependencies: + debug: 4.3.7(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + ajv@5.5.2: + dependencies: + co: 4.6.0 + fast-deep-equal: 1.1.0 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.3.1 + + ajv@6.12.6: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.17.1: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.0.3 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + amdefine@1.0.1: + optional: true + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-colors@4.1.1: {} + + ansi-colors@4.1.3: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-regex@2.1.1: {} + + ansi-regex@3.0.1: {} + + ansi-regex@5.0.1: {} + + ansi-styles@1.0.0: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + antlr4@4.13.2: {} + + antlr4@4.8.0: {} + + antlr4ts@0.5.0-alpha.4: {} + + any-promise@1.3.0: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + append-transform@2.0.0: + dependencies: + default-require-extensions: 3.0.1 + + archy@1.0.0: {} + + arg@4.1.3: {} + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + array-back@3.1.0: {} + + array-back@4.0.2: {} + + array-buffer-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + is-array-buffer: 3.0.4 + + array-flatten@1.1.1: {} + + array-includes@3.1.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + get-intrinsic: 1.2.4 + is-string: 1.0.7 + + array-union@2.1.0: {} + + array-uniq@1.0.3: {} + + array.prototype.findlastindex@1.2.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-shim-unscopables: 1.0.2 + + array.prototype.flat@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + array.prototype.flatmap@1.3.2: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-shim-unscopables: 1.0.2 + + arraybuffer.prototype.slice@1.0.3: + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + + asap@2.0.6: {} + + asn1@0.2.6: + dependencies: + safer-buffer: 2.1.2 + + assert-plus@1.0.0: {} + + assertion-error@1.1.0: {} + + ast-parents@0.0.1: {} + + astral-regex@2.0.0: {} + + async-limiter@1.0.1: {} + + async@1.5.2: {} + + asynckit@0.4.0: {} + + at-least-node@1.0.0: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.0.0 + + aws-sign2@0.7.0: {} + + aws4@1.13.2: {} + + axios@0.21.4: + dependencies: + follow-redirects: 1.15.9(debug@4.3.7) + transitivePeerDependencies: + - debug + + axios@1.7.7(debug@4.3.7): + dependencies: + follow-redirects: 1.15.9(debug@4.3.7) + form-data: 4.0.1 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + + babel-plugin-styled-components@2.1.4(@babel/core@7.26.0)(styled-components@5.3.10(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1))(supports-color@5.5.0): + dependencies: + '@babel/helper-annotate-as-pure': 7.25.9 + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.0) + lodash: 4.17.21 + picomatch: 2.3.1 + styled-components: 5.3.10(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1) + transitivePeerDependencies: + - '@babel/core' + - supports-color + + balanced-match@1.0.2: {} + + base-x@3.0.10: + dependencies: + safe-buffer: 5.2.1 + + base64-js@1.5.1: {} + + bcrypt-pbkdf@1.0.2: + dependencies: + tweetnacl: 0.14.5 + + bech32@1.1.4: {} + + better-path-resolve@1.0.0: + dependencies: + is-windows: 1.0.2 + + big-integer@1.6.36: {} + + big.js@6.2.2: {} + + bignumber.js@7.2.1: {} + + bignumber.js@9.1.2: {} + + bignumber.js@9.2.1: {} + + bignumber.js@https://codeload.github.com/frozeman/bignumber.js-nolookahead/tar.gz/57692b3ecfc98bbdd6b3a516cb2353652ea49934: {} + + binary-extensions@2.3.0: {} + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + blakejs@1.2.1: {} + + bluebird@3.7.2: {} + + bn-str-256@1.9.1: + dependencies: + decimal.js-light: 2.5.1 + lodash: 4.17.21 + + bn.js@4.11.6: {} + + bn.js@4.12.0: {} + + bn.js@5.2.1: {} + + body-parser@1.20.3: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + on-finished: 2.4.1 + qs: 6.13.0 + raw-body: 2.5.2 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + boolbase@1.0.0: {} + + boolean@3.2.0: {} + + boxen@5.1.2: + dependencies: + ansi-align: 3.0.1 + camelcase: 6.3.0 + chalk: 4.1.2 + cli-boxes: 2.2.1 + string-width: 4.2.3 + type-fest: 0.20.2 + widest-line: 3.1.0 + wrap-ansi: 7.0.0 + + brace-expansion@1.1.11: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.0.1: + dependencies: + balanced-match: 1.0.2 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + brorand@1.1.0: {} + + browser-stdout@1.3.1: {} + + browserify-aes@1.2.0: + dependencies: + buffer-xor: 1.0.3 + cipher-base: 1.0.4 + create-hash: 1.2.0 + evp_bytestokey: 1.0.3 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + browserslist@4.24.2: + dependencies: + caniuse-lite: 1.0.30001669 + electron-to-chromium: 1.5.45 + node-releases: 2.0.18 + update-browserslist-db: 1.1.1(browserslist@4.24.2) + + bs58@4.0.1: + dependencies: + base-x: 3.0.10 + + bs58check@2.1.2: + dependencies: + bs58: 4.0.1 + create-hash: 1.2.0 + safe-buffer: 5.2.1 + + buffer-from@1.1.2: {} + + buffer-to-arraybuffer@0.0.5: {} + + buffer-xor@1.0.3: {} + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + bufferutil@4.0.8: + dependencies: + node-gyp-build: 4.8.2 + + builtin-modules@3.3.0: {} + + builtins@5.1.0: + dependencies: + semver: 7.6.3 + + bytes@3.1.2: {} + + cacheable-lookup@5.0.4: {} + + cacheable-lookup@6.1.0: {} + + cacheable-lookup@7.0.0: {} + + cacheable-request@10.2.14: + dependencies: + '@types/http-cache-semantics': 4.0.4 + get-stream: 6.0.1 + http-cache-semantics: 4.1.1 + keyv: 4.5.4 + mimic-response: 4.0.0 + normalize-url: 8.0.1 + responselike: 3.0.0 + + cacheable-request@7.0.4: + dependencies: + clone-response: 1.0.3 + get-stream: 5.2.0 + http-cache-semantics: 4.1.1 + keyv: 4.5.4 + lowercase-keys: 2.0.0 + normalize-url: 6.1.0 + responselike: 2.0.1 + + caching-transform@4.0.0: + dependencies: + hasha: 5.2.2 + make-dir: 3.1.0 + package-hash: 4.0.0 + write-file-atomic: 3.0.3 + + call-bind@1.0.7: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 + + callsites@3.1.0: {} + + camel-case@3.0.0: + dependencies: + no-case: 2.3.2 + upper-case: 1.1.3 + + camelcase@3.0.0: {} + + camelcase@4.1.0: {} + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + camelize@1.0.1: {} + + caniuse-lite@1.0.30001669: {} + + caseless@0.12.0: {} + + cbor@5.2.0: + dependencies: + bignumber.js: 9.2.1 + nofilter: 1.0.4 + + cbor@8.1.0: + dependencies: + nofilter: 3.1.0 + + cbor@9.0.2: + dependencies: + nofilter: 3.1.0 + + chai-as-promised@7.1.1(chai@4.5.0): + dependencies: + chai: 4.5.0 + check-error: 1.0.3 + + chai-as-promised@7.1.2(chai@4.5.0): + dependencies: + chai: 4.5.0 + check-error: 1.0.3 + + chai@4.5.0: + dependencies: + assertion-error: 1.1.0 + check-error: 1.0.3 + deep-eql: 4.1.4 + get-func-name: 2.0.2 + loupe: 2.3.7 + pathval: 1.1.1 + type-detect: 4.1.0 + + chalk@0.4.0: + dependencies: + ansi-styles: 1.0.0 + has-color: 0.1.7 + strip-ansi: 0.1.1 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + change-case@3.0.2: + dependencies: + camel-case: 3.0.0 + constant-case: 2.0.0 + dot-case: 2.1.1 + header-case: 1.0.1 + is-lower-case: 1.1.3 + is-upper-case: 1.1.2 + lower-case: 1.1.4 + lower-case-first: 1.0.2 + no-case: 2.3.2 + param-case: 2.1.1 + pascal-case: 2.0.1 + path-case: 2.1.1 + sentence-case: 2.1.1 + snake-case: 2.1.0 + swap-case: 1.1.2 + title-case: 2.1.1 + upper-case: 1.1.3 + upper-case-first: 1.1.2 + + character-entities@2.0.2: {} + + chardet@0.7.0: {} + + charenc@0.0.2: {} + + check-error@1.0.3: + dependencies: + get-func-name: 2.0.2 + + cheerio-select@2.1.0: + dependencies: + boolbase: 1.0.0 + css-select: 5.1.0 + css-what: 6.1.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + + cheerio@1.0.0: + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.1.0 + encoding-sniffer: 0.2.0 + htmlparser2: 9.1.0 + parse5: 7.2.0 + parse5-htmlparser2-tree-adapter: 7.1.0 + parse5-parser-stream: 7.1.2 + undici: 6.20.1 + whatwg-mimetype: 4.0.0 + + chokidar@3.5.3: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@4.0.1: + dependencies: + readdirp: 4.0.2 + + chownr@1.1.4: {} + + ci-info@2.0.0: {} + + ci-info@3.9.0: {} + + cids@0.7.5: + dependencies: + buffer: 5.7.1 + class-is: 1.1.0 + multibase: 0.6.1 + multicodec: 1.0.4 + multihashes: 0.4.21 + + cipher-base@1.0.4: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + class-is@1.1.0: {} + + classnames@2.5.1: {} + + clean-stack@2.2.0: {} + + cli-boxes@2.2.1: {} + + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + + cli-spinners@2.9.2: {} + + cli-table3@0.5.1: + dependencies: + object-assign: 4.1.1 + string-width: 2.1.1 + optionalDependencies: + colors: 1.4.0 + + cliui@3.2.0: + dependencies: + string-width: 1.0.2 + strip-ansi: 3.0.1 + wrap-ansi: 2.1.0 + + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone-response@1.0.3: + dependencies: + mimic-response: 1.0.1 + + clone@1.0.4: {} + + co@4.6.0: {} + + code-point-at@1.1.0: {} + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + colors@1.2.5: {} + + colors@1.4.0: {} + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + command-exists@1.2.9: {} + + command-line-args@5.2.1: + dependencies: + array-back: 3.1.0 + find-replace: 3.0.0 + lodash.camelcase: 4.3.0 + typical: 4.0.0 + + command-line-usage@6.1.3: + dependencies: + array-back: 4.0.2 + chalk: 2.4.2 + table-layout: 1.0.2 + typical: 5.2.0 + + commander@10.0.1: {} + + commander@2.20.3: {} + + commander@6.2.1: {} + + commander@7.2.0: {} + + commander@8.3.0: {} + + commander@9.5.0: + optional: true + + commondir@1.0.1: {} + + concat-map@0.0.1: {} + + concat-stream@1.6.2: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + + config-chain@1.1.13: + dependencies: + ini: 1.3.8 + proto-list: 1.2.4 + + constant-case@2.0.0: + dependencies: + snake-case: 2.1.0 + upper-case: 1.1.3 + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-hash@2.5.2: + dependencies: + cids: 0.7.5 + multicodec: 0.5.7 + multihashes: 0.4.21 + + content-type@1.0.5: {} + + convert-source-map@1.9.0: {} + + convert-source-map@2.0.0: {} + + cookie-signature@1.0.6: {} + + cookie@0.4.2: {} + + cookie@0.7.1: {} + + cookiejar@2.1.4: {} + + core-util-is@1.0.2: {} + + core-util-is@1.0.3: {} + + cors@2.8.5: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + cose-base@1.0.3: + dependencies: + layout-base: 1.0.2 + + cosmiconfig@8.3.6(typescript@5.0.4): + dependencies: + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 5.0.4 + + cosmiconfig@8.3.6(typescript@5.3.3): + dependencies: + import-fresh: 3.3.0 + js-yaml: 4.1.0 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 5.3.3 + + crc-32@1.2.2: {} + + create-hash@1.2.0: + dependencies: + cipher-base: 1.0.4 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.2 + sha.js: 2.4.11 + + create-hmac@1.1.7: + dependencies: + cipher-base: 1.0.4 + create-hash: 1.2.0 + inherits: 2.0.4 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + + create-require@1.1.1: {} + + cross-fetch@3.1.8: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + cross-fetch@4.0.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + + cross-spawn@5.1.0: + dependencies: + lru-cache: 4.1.5 + shebang-command: 1.2.0 + which: 1.3.1 + + cross-spawn@7.0.3: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crypt@0.0.2: {} + + crypto-addr-codec@0.1.8: + dependencies: + base-x: 3.0.10 + big-integer: 1.6.36 + blakejs: 1.2.1 + bs58: 4.0.1 + ripemd160-min: 0.0.6 + safe-buffer: 5.2.1 + sha3: 2.1.4 + + crypto-js@3.3.0: {} + + crypto-js@4.2.0: {} + + css-color-keywords@1.0.0: {} + + css-select@5.1.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.1.0 + nth-check: 2.1.1 + + css-to-react-native@3.2.0: + dependencies: + camelize: 1.0.1 + css-color-keywords: 1.0.0 + postcss-value-parser: 4.2.0 + + css-what@6.1.0: {} + + csstype@3.1.3: {} + + cytoscape-cose-bilkent@4.1.0(cytoscape@3.31.0): + dependencies: + cose-base: 1.0.3 + cytoscape: 3.31.0 + + cytoscape@3.31.0: {} + + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-axis@3.0.0: {} + + d3-brush@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3-chord@3.0.1: + dependencies: + d3-path: 3.1.0 + + d3-color@3.1.0: {} + + d3-contour@4.0.2: + dependencies: + d3-array: 3.2.4 + + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.0.1 + + d3-dispatch@3.0.1: {} + + d3-drag@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-selection: 3.0.0 + + d3-dsv@3.0.1: + dependencies: + commander: 7.2.0 + iconv-lite: 0.6.3 + rw: 1.3.3 + + d3-ease@3.0.1: {} + + d3-fetch@3.0.1: + dependencies: + d3-dsv: 3.0.1 + + d3-force@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-quadtree: 3.0.1 + d3-timer: 3.0.1 + + d3-format@3.1.0: {} + + d3-geo@3.1.1: + dependencies: + d3-array: 3.2.4 + + d3-hierarchy@3.1.2: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@1.0.9: {} + + d3-path@3.1.0: {} + + d3-polygon@3.0.1: {} + + d3-quadtree@3.0.1: {} + + d3-random@3.0.1: {} + + d3-sankey@0.12.3: + dependencies: + d3-array: 2.12.1 + d3-shape: 1.3.7 + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 3.1.0 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + + d3-selection@3.0.0: {} + + d3-shape@1.3.7: + dependencies: + d3-path: 1.0.9 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@4.1.0: + dependencies: + d3-time: 3.1.0 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + d3-transition@3.0.1(d3-selection@3.0.0): + dependencies: + d3-color: 3.1.0 + d3-dispatch: 3.0.1 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-timer: 3.0.1 + + d3-zoom@3.0.0: + dependencies: + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-interpolate: 3.0.1 + d3-selection: 3.0.0 + d3-transition: 3.0.1(d3-selection@3.0.0) + + d3@7.9.0: + dependencies: + d3-array: 3.2.4 + d3-axis: 3.0.0 + d3-brush: 3.0.0 + d3-chord: 3.0.1 + d3-color: 3.1.0 + d3-contour: 4.0.2 + d3-delaunay: 6.0.4 + d3-dispatch: 3.0.1 + d3-drag: 3.0.0 + d3-dsv: 3.0.1 + d3-ease: 3.0.1 + d3-fetch: 3.0.1 + d3-force: 3.0.0 + d3-format: 3.1.0 + d3-geo: 3.1.1 + d3-hierarchy: 3.1.2 + d3-interpolate: 3.0.1 + d3-path: 3.1.0 + d3-polygon: 3.0.1 + d3-quadtree: 3.0.1 + d3-random: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-selection: 3.0.0 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-time-format: 4.1.0 + d3-timer: 3.0.1 + d3-transition: 3.0.1(d3-selection@3.0.0) + d3-zoom: 3.0.0 + + d@1.0.2: + dependencies: + es5-ext: 0.10.64 + type: 2.7.3 + + dagre-d3-es@7.0.10: + dependencies: + d3: 7.9.0 + lodash-es: 4.17.21 + + dashdash@1.14.1: + dependencies: + assert-plus: 1.0.0 + + data-view-buffer@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + data-view-byte-offset@1.0.0: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + date-time@0.1.1: {} + + dayjs@1.11.13: {} + + death@1.1.0: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.3.3(supports-color@8.1.1): + dependencies: + ms: 2.1.2 + optionalDependencies: + supports-color: 8.1.1 + + debug@4.3.7(supports-color@5.5.0): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 5.5.0 + + debug@4.3.7(supports-color@8.1.1): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 8.1.1 + + decamelize@1.2.0: {} + + decamelize@4.0.0: {} + + decimal.js-light@2.5.1: {} + + decode-named-character-reference@1.0.2: + dependencies: + character-entities: 2.0.2 + + decode-uri-component@0.2.2: {} + + decompress-response@3.3.0: + dependencies: + mimic-response: 1.0.1 + + decompress-response@6.0.0: + dependencies: + mimic-response: 3.1.0 + + deep-eql@4.1.4: + dependencies: + type-detect: 4.1.0 + + deep-extend@0.6.0: {} + + deep-is@0.1.4: {} + + deepmerge@4.3.1: {} + + default-require-extensions@3.0.1: + dependencies: + strip-bom: 4.0.0 + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + defer-to-connect@2.0.1: {} + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + delaunator@5.0.1: + dependencies: + robust-predicates: 3.0.2 + + delayed-stream@1.0.0: {} + + depd@2.0.0: {} + + dequal@2.0.3: {} + + destroy@1.2.0: {} + + detect-indent@5.0.0: {} + + detect-indent@6.1.0: {} + + detect-libc@2.0.3: {} + + detect-node@2.1.0: {} + + detect-port@1.6.1: + dependencies: + address: 1.2.2 + debug: 4.3.7(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + + diff-sequences@29.6.3: {} + + diff@4.0.2: {} + + diff@5.0.0: {} + + diff@5.2.0: {} + + difflib@0.2.4: + dependencies: + heap: 0.2.7 + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + dom-walk@0.1.2: {} + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + dompurify@3.1.6: {} + + domutils@3.1.0: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-case@2.1.1: + dependencies: + no-case: 2.3.2 + + dot-prop@7.2.0: + dependencies: + type-fest: 2.19.0 + + ecc-jsbn@0.1.2: + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + + ee-first@1.1.1: {} + + eip55@2.1.1: + dependencies: + keccak: 3.0.4 + + electron-to-chromium@1.5.45: {} + + elkjs@0.9.3: {} + + elliptic@6.5.4: + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + elliptic@6.5.7: + dependencies: + bn.js: 4.12.0 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + emoji-regex@8.0.0: {} + + encodeurl@1.0.2: {} + + encodeurl@2.0.0: {} + + encoding-sniffer@0.2.0: + dependencies: + iconv-lite: 0.6.3 + whatwg-encoding: 3.1.1 + + end-of-stream@1.4.4: + dependencies: + once: 1.4.0 + + enhanced-resolve@5.18.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.2.1 + + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + + entities@4.5.0: {} + + env-paths@2.2.1: {} + + error-ex@1.3.2: + dependencies: + is-arrayish: 0.2.1 + + es-abstract@1.23.3: + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.2 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.3 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.6 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + + es-define-property@1.0.0: + dependencies: + get-intrinsic: 1.2.4 + + es-errors@1.3.0: {} + + es-object-atoms@1.0.0: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.0.3: + dependencies: + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + es-shim-unscopables@1.0.2: + dependencies: + hasown: 2.0.2 + + es-to-primitive@1.2.1: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.0.5 + is-symbol: 1.0.4 + + es5-ext@0.10.64: + dependencies: + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + esniff: 2.0.1 + next-tick: 1.1.0 + + es6-error@4.1.1: {} + + es6-iterator@2.0.3: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-symbol: 3.1.4 + + es6-promise@4.2.8: {} + + es6-symbol@3.1.4: + dependencies: + d: 1.0.2 + ext: 1.7.0 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@4.0.0: {} + + escodegen@1.8.1: + dependencies: + esprima: 2.7.3 + estraverse: 1.9.3 + esutils: 2.0.3 + optionator: 0.8.3 + optionalDependencies: + source-map: 0.2.0 + + eslint-compat-utils@0.5.1(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + semver: 7.6.3 + + eslint-config-prettier@8.3.0(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + + eslint-doc-generator@1.7.1(eslint@8.57.1)(typescript@5.3.3): + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.3.3) + ajv: 8.17.1 + boolean: 3.2.0 + commander: 10.0.1 + cosmiconfig: 8.3.6(typescript@5.3.3) + deepmerge: 4.3.1 + dot-prop: 7.2.0 + eslint: 8.57.1 + jest-diff: 29.7.0 + json-schema-traverse: 1.0.0 + markdown-table: 3.0.4 + no-case: 3.0.4 + type-fest: 3.13.1 + transitivePeerDependencies: + - supports-color + - typescript + + eslint-import-resolver-node@0.3.9: + dependencies: + debug: 3.2.7 + is-core-module: 2.15.1 + resolve: 1.22.8 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.29.0)(eslint@8.57.1): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.3.7(supports-color@5.5.0) + enhanced-resolve: 5.18.0 + eslint: 8.57.1 + fast-glob: 3.3.2 + get-tsconfig: 4.8.1 + is-bun-module: 1.3.0 + is-glob: 4.0.3 + stable-hash: 0.0.4 + optionalDependencies: + eslint-plugin-import: 2.29.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 5.61.0(eslint@8.57.1)(typescript@5.0.4) + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.29.0)(eslint@8.57.1) + transitivePeerDependencies: + - supports-color + + eslint-plugin-es-x@7.8.0(eslint@8.57.1): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@eslint-community/regexpp': 4.11.1 + eslint: 8.57.1 + eslint-compat-utils: 0.5.1(eslint@8.57.1) + + eslint-plugin-eslint-plugin@5.5.1(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-utils: 3.0.0(eslint@8.57.1) + estraverse: 5.3.0 + + eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint@8.57.1): + dependencies: + array-includes: 3.1.8 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) + has: 1.0.4 + is-core-module: 2.15.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.values: 1.2.0 + resolve: 1.22.8 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 5.61.0(eslint@8.57.1)(typescript@5.0.4) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-import@2.29.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1): + dependencies: + array-includes: 3.1.8 + array.prototype.findlastindex: 1.2.5 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.12.0(@typescript-eslint/parser@5.61.0(eslint@8.57.1)(typescript@5.0.4))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@8.57.1) + hasown: 2.0.2 + is-core-module: 2.15.1 + is-glob: 4.0.3 + minimatch: 3.1.2 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.0 + semver: 6.3.1 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 5.61.0(eslint@8.57.1)(typescript@5.0.4) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-mocha@10.4.1(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-utils: 3.0.0(eslint@8.57.1) + globals: 13.24.0 + rambda: 7.5.0 + + eslint-plugin-mocha@9.0.0(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-utils: 3.0.0(eslint@8.57.1) + ramda: 0.27.2 + + eslint-plugin-n@16.6.2(eslint@8.57.1): + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + builtins: 5.1.0 + eslint: 8.57.1 + eslint-plugin-es-x: 7.8.0(eslint@8.57.1) + get-tsconfig: 4.8.1 + globals: 13.24.0 + ignore: 5.3.2 + is-builtin-module: 3.2.1 + is-core-module: 2.15.1 + minimatch: 3.1.2 + resolve: 1.22.8 + semver: 7.6.3 + + eslint-plugin-no-only-tests@3.1.0: {} + + eslint-plugin-prettier@3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.4.1): + dependencies: + eslint: 8.57.1 + prettier: 2.4.1 + prettier-linter-helpers: 1.0.0 + optionalDependencies: + eslint-config-prettier: 8.3.0(eslint@8.57.1) + + eslint-plugin-prettier@3.4.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8): + dependencies: + eslint: 8.57.1 + prettier: 2.8.8 + prettier-linter-helpers: 1.0.0 + optionalDependencies: + eslint-config-prettier: 8.3.0(eslint@8.57.1) + + eslint-plugin-prettier@4.0.0(eslint-config-prettier@8.3.0(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8): + dependencies: + eslint: 8.57.1 + prettier: 2.8.8 + prettier-linter-helpers: 1.0.0 + optionalDependencies: + eslint-config-prettier: 8.3.0(eslint@8.57.1) + + eslint-plugin-react-hooks@4.6.2(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + + eslint-plugin-react-refresh@0.3.5(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-utils@3.0.0(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 2.1.0 + + eslint-visitor-keys@2.1.0: {} + + eslint-visitor-keys@3.4.3: {} + + eslint@8.57.1: + dependencies: + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.1) + '@eslint-community/regexpp': 4.11.1 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 + ajv: 6.12.6 + chalk: 4.1.2 + cross-spawn: 7.0.3 + debug: 4.3.7(supports-color@5.5.0) + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.6.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.0 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.2 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + esniff@2.0.1: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + event-emitter: 0.3.5 + type: 2.7.3 + + espree@9.6.1: + dependencies: + acorn: 8.13.0 + acorn-jsx: 5.3.2(acorn@8.13.0) + eslint-visitor-keys: 3.4.3 + + esprima@2.7.3: {} + + esprima@4.0.1: {} + + esquery@1.6.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@1.9.3: {} + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + esutils@2.0.3: {} + + etag@1.8.1: {} + + eth-ens-namehash@2.0.8: + dependencies: + idna-uts46-hx: 2.3.1 + js-sha3: 0.5.7 + + eth-gas-reporter@0.2.27(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@solidity-parser/parser': 0.14.5 + axios: 1.7.7(debug@4.3.7) + cli-table3: 0.5.1 + colors: 1.4.0 + ethereum-cryptography: 1.2.0 + ethers: 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + fs-readdir-recursive: 1.1.0 + lodash: 4.17.21 + markdown-table: 1.1.3 + mocha: 10.7.3 + req-cwd: 2.0.0 + sha1: 1.1.1 + sync-request: 6.1.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + eth-lib@0.1.29(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + bn.js: 4.12.0 + elliptic: 6.5.7 + nano-json-stream-parser: 0.1.2 + servify: 0.1.12 + ws: 3.3.3(bufferutil@4.0.8)(utf-8-validate@5.0.10) + xhr-request-promise: 0.1.3 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + eth-lib@0.2.8: + dependencies: + bn.js: 4.12.0 + elliptic: 6.5.7 + xhr-request-promise: 0.1.3 + + ethereum-bloom-filters@1.2.0: + dependencies: + '@noble/hashes': 1.5.0 + + ethereum-cryptography@0.1.3: + dependencies: + '@types/pbkdf2': 3.1.2 + '@types/secp256k1': 4.0.6 + blakejs: 1.2.1 + browserify-aes: 1.2.0 + bs58check: 2.1.2 + create-hash: 1.2.0 + create-hmac: 1.1.7 + hash.js: 1.1.7 + keccak: 3.0.4 + pbkdf2: 3.1.2 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + scrypt-js: 3.0.1 + secp256k1: 4.0.4 + setimmediate: 1.0.5 + + ethereum-cryptography@1.2.0: + dependencies: + '@noble/hashes': 1.2.0 + '@noble/secp256k1': 1.7.1 + '@scure/bip32': 1.1.5 + '@scure/bip39': 1.1.1 + + ethereum-cryptography@2.2.1: + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/bip32': 1.4.0 + '@scure/bip39': 1.3.0 + + ethereum-ens@0.8.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + bluebird: 3.7.2 + eth-ens-namehash: 2.0.8 + js-sha3: 0.5.7 + pako: 1.0.11 + underscore: 1.13.7 + web3: 1.10.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + ethereumjs-util@6.2.1: + dependencies: + '@types/bn.js': 4.11.6 + bn.js: 4.12.0 + create-hash: 1.2.0 + elliptic: 6.5.7 + ethereum-cryptography: 0.1.3 + ethjs-util: 0.1.6 + rlp: 2.2.7 + + ethereumjs-util@7.1.5: + dependencies: + '@types/bn.js': 5.1.6 + bn.js: 5.2.1 + create-hash: 1.2.0 + ethereum-cryptography: 0.1.3 + rlp: 2.2.7 + + ethers@4.0.49: + dependencies: + aes-js: 3.0.0 + bn.js: 4.12.0 + elliptic: 6.5.4 + hash.js: 1.1.3 + js-sha3: 0.5.7 + scrypt-js: 2.0.4 + setimmediate: 1.0.4 + uuid: 2.0.1 + xmlhttprequest: 1.8.0 + + ethers@5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@ethersproject/abi': 5.7.0 + '@ethersproject/abstract-provider': 5.7.0 + '@ethersproject/abstract-signer': 5.7.0 + '@ethersproject/address': 5.7.0 + '@ethersproject/base64': 5.7.0 + '@ethersproject/basex': 5.7.0 + '@ethersproject/bignumber': 5.7.0 + '@ethersproject/bytes': 5.7.0 + '@ethersproject/constants': 5.7.0 + '@ethersproject/contracts': 5.7.0 + '@ethersproject/hash': 5.7.0 + '@ethersproject/hdnode': 5.7.0 + '@ethersproject/json-wallets': 5.7.0 + '@ethersproject/keccak256': 5.7.0 + '@ethersproject/logger': 5.7.0 + '@ethersproject/networks': 5.7.1 + '@ethersproject/pbkdf2': 5.7.0 + '@ethersproject/properties': 5.7.0 + '@ethersproject/providers': 5.7.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + '@ethersproject/random': 5.7.0 + '@ethersproject/rlp': 5.7.0 + '@ethersproject/sha2': 5.7.0 + '@ethersproject/signing-key': 5.7.0 + '@ethersproject/solidity': 5.7.0 + '@ethersproject/strings': 5.7.0 + '@ethersproject/transactions': 5.7.0 + '@ethersproject/units': 5.7.0 + '@ethersproject/wallet': 5.7.0 + '@ethersproject/web': 5.7.1 + '@ethersproject/wordlists': 5.7.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + ethers@6.13.4(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@types/node': 22.7.5 + aes-js: 4.0.0-beta.5 + tslib: 2.7.0 + ws: 8.17.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + ethjs-abi@0.1.8: + dependencies: + bn.js: 4.11.6 + js-sha3: 0.5.5 + number-to-bn: 1.7.0 + + ethjs-unit@0.1.6: + dependencies: + bn.js: 4.11.6 + number-to-bn: 1.7.0 + + ethjs-util@0.1.6: + dependencies: + is-hex-prefixed: 1.0.0 + strip-hex-prefix: 1.0.0 + + event-emitter@0.3.5: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + + eventemitter3@4.0.4: {} + + eventemitter3@5.0.1: {} + + events@3.3.0: {} + + evp_bytestokey@1.0.3: + dependencies: + md5.js: 1.3.5 + safe-buffer: 5.2.1 + + expand-template@2.0.3: {} + + express@4.21.1: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.3 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.1 + cookie-signature: 1.0.6 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.1 + fresh: 0.5.2 + http-errors: 2.0.0 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.10 + proxy-addr: 2.0.7 + qs: 6.13.0 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.0 + serve-static: 1.16.2 + setprototypeof: 1.2.0 + statuses: 2.0.1 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + ext@1.7.0: + dependencies: + type: 2.7.3 + + extend@3.0.2: {} + + extendable-error@0.1.7: {} + + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + extsprintf@1.3.0: {} + + fast-check@3.1.1: + dependencies: + pure-rand: 5.0.5 + + fast-deep-equal@1.1.0: {} + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-glob@3.3.2: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-safe-stringify@2.1.1: {} + + fast-uri@3.0.3: {} + + fastq@1.17.1: + dependencies: + reusify: 1.0.4 + + fdir@6.3.0(picomatch@4.0.2): + optionalDependencies: + picomatch: 4.0.2 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + file-uri-to-path@1.0.0: {} + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.3.1: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-cache-dir@3.3.2: + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + + find-replace@3.0.0: + dependencies: + array-back: 3.1.0 + + find-up@1.1.2: + dependencies: + path-exists: 2.1.0 + pinkie-promise: 2.0.1 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + flat-cache@3.2.0: + dependencies: + flatted: 3.3.1 + keyv: 4.5.4 + rimraf: 3.0.2 + + flat@5.0.2: {} + + flatted@3.3.1: {} + + follow-redirects@1.15.9(debug@4.3.7): + optionalDependencies: + debug: 4.3.7(supports-color@5.5.0) + + for-each@0.3.3: + dependencies: + is-callable: 1.2.7 + + foreground-child@2.0.0: + dependencies: + cross-spawn: 7.0.3 + signal-exit: 3.0.7 + + forever-agent@0.6.1: {} + + form-data-encoder@1.7.1: {} + + form-data-encoder@2.1.4: {} + + form-data@2.3.3: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + form-data@2.5.2: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + safe-buffer: 5.2.1 + + form-data@4.0.1: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + + forwarded@0.2.0: {} + + fp-ts@1.19.3: {} + + fresh@0.5.2: {} + + fromentries@1.3.2: {} + + fs-constants@1.0.0: {} + + fs-extra@0.30.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 2.4.0 + klaw: 1.3.1 + path-is-absolute: 1.0.1 + rimraf: 2.7.1 + + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-extra@4.0.3: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@7.0.1: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@8.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 4.0.0 + universalify: 0.1.2 + + fs-extra@9.1.0: + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + + fs-minipass@1.2.7: + dependencies: + minipass: 2.9.0 + + fs-readdir-recursive@1.1.0: {} + + fs.realpath@1.0.0: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.6: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + functions-have-names: 1.2.3 + + functions-have-names@1.2.3: {} + + ganache-cli@6.12.2: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@1.0.3: {} + + get-caller-file@2.0.5: {} + + get-func-name@2.0.2: {} + + get-intrinsic@1.2.4: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + + get-package-type@0.1.0: {} + + get-port@3.2.0: {} + + get-port@5.1.1: {} + + get-stream@5.2.0: + dependencies: + pump: 3.0.2 + + get-stream@6.0.1: {} + + get-symbol-description@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + + get-tsconfig@4.8.1: + dependencies: + resolve-pkg-maps: 1.0.0 + + getpass@0.1.7: + dependencies: + assert-plus: 1.0.0 + + ghost-testrpc@0.0.2: + dependencies: + chalk: 2.4.2 + node-emoji: 1.11.0 + + github-from-package@0.0.0: {} + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob@5.0.15: + dependencies: + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@7.1.7: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@7.2.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.6 + once: 1.4.0 + + global-modules@2.0.0: + dependencies: + global-prefix: 3.0.0 + + global-prefix@3.0.0: + dependencies: + ini: 1.3.8 + kind-of: 6.0.3 + which: 1.3.1 + + global@4.4.0: + dependencies: + min-document: 2.19.0 + process: 0.11.10 + + globals@11.12.0: {} + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.0.1 + + globby@10.0.2: + dependencies: + '@types/glob': 7.2.0 + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + glob: 7.2.0 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.2 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + gopd@1.0.1: + dependencies: + get-intrinsic: 1.2.4 + + got@11.8.6: + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.3 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.1 + + got@12.1.0: + dependencies: + '@sindresorhus/is': 4.6.0 + '@szmarczak/http-timer': 5.0.1 + '@types/cacheable-request': 6.0.3 + '@types/responselike': 1.0.3 + cacheable-lookup: 6.1.0 + cacheable-request: 7.0.4 + decompress-response: 6.0.0 + form-data-encoder: 1.7.1 + get-stream: 6.0.1 + http2-wrapper: 2.2.1 + lowercase-keys: 3.0.0 + p-cancelable: 3.0.0 + responselike: 2.0.1 + + got@12.6.1: + dependencies: + '@sindresorhus/is': 5.6.0 + '@szmarczak/http-timer': 5.0.1 + cacheable-lookup: 7.0.0 + cacheable-request: 10.2.14 + decompress-response: 6.0.0 + form-data-encoder: 2.1.4 + get-stream: 6.0.1 + http2-wrapper: 2.2.1 + lowercase-keys: 3.0.0 + p-cancelable: 3.0.0 + responselike: 3.0.0 + + graceful-fs@4.2.10: {} + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + growl@1.10.5: {} + + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + + har-schema@2.0.0: {} + + har-validator@5.1.5: + dependencies: + ajv: 6.12.6 + har-schema: 2.0.0 + + hardhat-gas-reporter@1.0.10(bufferutil@4.0.8)(hardhat@packages+hardhat-core)(utf-8-validate@5.0.10): + dependencies: + array-uniq: 1.0.3 + eth-gas-reporter: 0.2.27(bufferutil@4.0.8)(utf-8-validate@5.0.10) + hardhat: link:packages/hardhat-core + sha1: 1.1.1 + transitivePeerDependencies: + - '@codechecks/client' + - bufferutil + - debug + - utf-8-validate + + has-bigints@1.0.2: {} + + has-color@0.1.7: {} + + has-flag@1.0.0: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.0 + + has-proto@1.0.3: {} + + has-symbols@1.0.3: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.0.3 + + has@1.0.4: {} + + hash-base@3.1.0: + dependencies: + inherits: 2.0.4 + readable-stream: 3.6.2 + safe-buffer: 5.2.1 + + hash.js@1.1.3: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + hash.js@1.1.7: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + hasha@5.2.2: + dependencies: + is-stream: 2.0.1 + type-fest: 0.8.1 + + hasown@2.0.2: + dependencies: + function-bind: 1.1.2 + + he@1.2.0: {} + + header-case@1.0.1: + dependencies: + no-case: 2.3.2 + upper-case: 1.1.3 + + heap@0.2.7: {} + + highlight.js@10.7.3: {} + + highlightjs-solidity@2.0.6: {} + + hmac-drbg@1.0.1: + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + hosted-git-info@2.8.9: {} + + html-escaper@2.0.2: {} + + htmlparser2@9.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.1.0 + entities: 4.5.0 + + http-basic@8.1.3: + dependencies: + caseless: 0.12.0 + concat-stream: 1.6.2 + http-response-object: 3.0.2 + parse-cache-control: 1.0.1 + + http-cache-semantics@4.1.1: {} + + http-errors@2.0.0: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.1 + toidentifier: 1.0.1 + + http-https@1.0.0: {} + + http-response-object@3.0.2: + dependencies: + '@types/node': 10.17.60 + + http-signature@1.2.0: + dependencies: + assert-plus: 1.0.0 + jsprim: 1.4.2 + sshpk: 1.18.0 + + http2-wrapper@1.0.3: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + + http2-wrapper@2.2.1: + dependencies: + quick-lru: 5.1.1 + resolve-alpn: 1.2.1 + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.3.7(supports-color@5.5.0) + transitivePeerDependencies: + - supports-color + + human-id@1.0.2: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + + idna-uts46-hx@2.3.1: + dependencies: + punycode: 2.1.0 + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + immer@10.0.2: {} + + immutable@4.3.7: {} + + import-fresh@3.3.0: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-lazy@4.0.0: {} + + imurmurhash@0.1.4: {} + + indent-string@4.0.0: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.4: {} + + ini@1.3.8: {} + + internal-slot@1.0.7: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.2 + side-channel: 1.0.6 + + internmap@1.0.1: {} + + internmap@2.0.3: {} + + interpret@1.4.0: {} + + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + + invert-kv@1.0.0: {} + + io-ts@1.10.4: + dependencies: + fp-ts: 1.19.3 + + ipaddr.js@1.9.1: {} + + is-arguments@1.1.1: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-array-buffer@3.0.4: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + + is-arrayish@0.2.1: {} + + is-bigint@1.0.4: + dependencies: + has-bigints: 1.0.2 + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-boolean-object@1.1.2: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-builtin-module@3.2.1: + dependencies: + builtin-modules: 3.3.0 + + is-bun-module@1.3.0: + dependencies: + semver: 7.6.3 + + is-callable@1.2.7: {} + + is-core-module@2.15.1: + dependencies: + hasown: 2.0.2 + + is-data-view@1.0.1: + dependencies: + is-typed-array: 1.1.13 + + is-date-object@1.0.5: + dependencies: + has-tostringtag: 1.0.2 + + is-extglob@2.1.1: {} + + is-fullwidth-code-point@1.0.0: + dependencies: + number-is-nan: 1.0.1 + + is-fullwidth-code-point@2.0.0: {} + + is-fullwidth-code-point@3.0.0: {} + + is-function@1.0.2: {} + + is-generator-function@1.0.10: + dependencies: + has-tostringtag: 1.0.2 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hex-prefixed@1.0.0: {} + + is-interactive@1.0.0: {} + + is-lower-case@1.1.3: + dependencies: + lower-case: 1.1.4 + + is-negative-zero@2.0.3: {} + + is-number-object@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-number@7.0.0: {} + + is-path-inside@3.0.3: {} + + is-plain-obj@2.1.0: {} + + is-regex@1.1.4: + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + + is-shared-array-buffer@1.0.3: + dependencies: + call-bind: 1.0.7 + + is-stream@2.0.1: {} + + is-string@1.0.7: + dependencies: + has-tostringtag: 1.0.2 + + is-subdir@1.2.0: + dependencies: + better-path-resolve: 1.0.0 + + is-symbol@1.0.4: + dependencies: + has-symbols: 1.0.3 + + is-typed-array@1.1.13: + dependencies: + which-typed-array: 1.1.15 + + is-typedarray@1.0.0: {} + + is-unicode-supported@0.1.0: {} + + is-upper-case@1.1.2: + dependencies: + upper-case: 1.1.3 + + is-url@1.2.4: {} + + is-utf8@0.2.1: {} + + is-weakref@1.0.2: + dependencies: + call-bind: 1.0.7 + + is-windows@1.0.2: {} + + isarray@0.0.1: {} + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isomorphic-fetch@3.0.0: + dependencies: + node-fetch: 2.7.0 + whatwg-fetch: 3.6.20 + transitivePeerDependencies: + - encoding + + isomorphic-ws@5.0.0(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + + isows@1.0.6(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + + isstream@0.1.2: {} + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-hook@3.0.0: + dependencies: + append-transform: 2.0.0 + + istanbul-lib-instrument@4.0.3: + dependencies: + '@babel/core': 7.25.9 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-processinfo@2.0.3: + dependencies: + archy: 1.0.0 + cross-spawn: 7.0.3 + istanbul-lib-coverage: 3.2.2 + p-map: 3.0.0 + rimraf: 3.0.2 + uuid: 8.3.2 + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@4.0.1: + dependencies: + debug: 4.3.7(supports-color@5.5.0) + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.1.7: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-get-type@29.6.3: {} + + jju@1.4.0: {} + + js-sha3@0.5.5: {} + + js-sha3@0.5.7: {} + + js-sha3@0.8.0: {} + + js-tokens@4.0.0: {} + + js-yaml@3.14.1: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + jsbn@0.1.1: {} + + jsesc@3.0.2: {} + + json-buffer@3.0.1: {} + + json-parse-even-better-errors@2.3.1: {} + + json-schema-traverse@0.3.1: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-schema@0.4.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json-stream-stringify@3.1.6: {} + + json-stringify-safe@5.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + jsonfile@2.4.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsonfile@4.0.0: + optionalDependencies: + graceful-fs: 4.2.11 + + jsonfile@6.1.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonschema@1.4.1: {} + + jsprim@1.4.2: + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + + just-extend@4.2.1: {} + + just-extend@6.2.0: {} + + katex@0.16.21: + dependencies: + commander: 8.3.0 + + keccak@3.0.4: + dependencies: + node-addon-api: 2.0.2 + node-gyp-build: 4.8.2 + readable-stream: 3.6.2 + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + khroma@2.1.0: {} + + kind-of@6.0.3: {} + + klaw@1.3.1: + optionalDependencies: + graceful-fs: 4.2.11 + + kleur@3.0.3: {} + + kleur@4.1.5: {} + + latest-version@7.0.0: + dependencies: + package-json: 8.1.1 + + layout-base@1.0.2: {} + + lcid@1.0.0: + dependencies: + invert-kv: 1.0.0 + + levn@0.3.0: + dependencies: + prelude-ls: 1.1.2 + type-check: 0.3.2 + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + lines-and-columns@1.2.4: {} + + load-json-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 2.2.0 + pify: 2.3.0 + pinkie-promise: 2.0.1 + strip-bom: 2.0.0 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + lodash-es@4.17.21: {} + + lodash.assign@4.2.0: {} + + lodash.camelcase@4.3.0: {} + + lodash.clonedeep@4.5.0: {} + + lodash.deburr@4.1.0: {} + + lodash.flattendeep@4.4.0: {} + + lodash.get@4.4.2: {} + + lodash.isequal@4.5.0: {} + + lodash.memoize@4.1.2: {} + + lodash.merge@4.6.2: {} + + lodash.snakecase@4.1.1: {} + + lodash.startcase@4.4.0: {} + + lodash.trim@4.5.1: {} + + lodash.truncate@4.4.2: {} + + lodash@4.17.21: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + loupe@2.3.7: + dependencies: + get-func-name: 2.0.2 + + lower-case-first@1.0.2: + dependencies: + lower-case: 1.1.4 + + lower-case@1.1.4: {} + + lower-case@2.0.2: + dependencies: + tslib: 2.8.0 + + lowercase-keys@2.0.0: {} + + lowercase-keys@3.0.0: {} + + lru-cache@4.1.5: + dependencies: + pseudomap: 1.0.2 + yallist: 2.1.2 + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + lru_map@0.3.3: {} + + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + + make-dir@4.0.0: + dependencies: + semver: 7.6.3 + + make-error@1.3.6: {} + + markdown-table@1.1.3: {} + + markdown-table@3.0.4: {} + + md5.js@1.3.5: + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + mdast-util-from-markdown@1.3.1: + dependencies: + '@types/mdast': 3.0.15 + '@types/unist': 2.0.11 + decode-named-character-reference: 1.0.2 + mdast-util-to-string: 3.2.0 + micromark: 3.2.0 + micromark-util-decode-numeric-character-reference: 1.1.0 + micromark-util-decode-string: 1.1.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + unist-util-stringify-position: 3.0.3 + uvu: 0.5.6 + transitivePeerDependencies: + - supports-color + + mdast-util-to-string@3.2.0: + dependencies: + '@types/mdast': 3.0.15 + + media-typer@0.3.0: {} + + memorystream@0.3.1: {} + + merge-descriptors@1.0.3: {} + + merge2@1.4.1: {} + + mermaid@10.9.3: + dependencies: + '@braintree/sanitize-url': 6.0.4 + '@types/d3-scale': 4.0.8 + '@types/d3-scale-chromatic': 3.1.0 + cytoscape: 3.31.0 + cytoscape-cose-bilkent: 4.1.0(cytoscape@3.31.0) + d3: 7.9.0 + d3-sankey: 0.12.3 + dagre-d3-es: 7.0.10 + dayjs: 1.11.13 + dompurify: 3.1.6 + elkjs: 0.9.3 + katex: 0.16.21 + khroma: 2.1.0 + lodash-es: 4.17.21 + mdast-util-from-markdown: 1.3.1 + non-layered-tidy-tree-layout: 2.0.2 + stylis: 4.3.5 + ts-dedent: 2.2.0 + uuid: 9.0.1 + web-worker: 1.3.0 + transitivePeerDependencies: + - supports-color + + methods@1.1.2: {} + + micro-eth-signer@0.14.0: + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + micro-packed: 0.7.2 + + micro-ftch@0.3.1: {} + + micro-packed@0.7.2: + dependencies: + '@scure/base': 1.2.4 + + micromark-core-commonmark@1.1.0: + dependencies: + decode-named-character-reference: 1.0.2 + micromark-factory-destination: 1.1.0 + micromark-factory-label: 1.1.0 + micromark-factory-space: 1.1.0 + micromark-factory-title: 1.1.0 + micromark-factory-whitespace: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-chunked: 1.1.0 + micromark-util-classify-character: 1.1.0 + micromark-util-html-tag-name: 1.2.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-resolve-all: 1.1.0 + micromark-util-subtokenize: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + + micromark-factory-destination@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-factory-label@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + + micromark-factory-space@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-types: 1.1.0 + + micromark-factory-title@1.1.0: + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-factory-whitespace@1.1.0: + dependencies: + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-util-character@1.2.0: + dependencies: + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-util-chunked@1.1.0: + dependencies: + micromark-util-symbol: 1.1.0 + + micromark-util-classify-character@1.1.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-util-combine-extensions@1.1.0: + dependencies: + micromark-util-chunked: 1.1.0 + micromark-util-types: 1.1.0 + + micromark-util-decode-numeric-character-reference@1.1.0: + dependencies: + micromark-util-symbol: 1.1.0 + + micromark-util-decode-string@1.1.0: + dependencies: + decode-named-character-reference: 1.0.2 + micromark-util-character: 1.2.0 + micromark-util-decode-numeric-character-reference: 1.1.0 + micromark-util-symbol: 1.1.0 + + micromark-util-encode@1.1.0: {} + + micromark-util-html-tag-name@1.2.0: {} + + micromark-util-normalize-identifier@1.1.0: + dependencies: + micromark-util-symbol: 1.1.0 + + micromark-util-resolve-all@1.1.0: + dependencies: + micromark-util-types: 1.1.0 + + micromark-util-sanitize-uri@1.2.0: + dependencies: + micromark-util-character: 1.2.0 + micromark-util-encode: 1.1.0 + micromark-util-symbol: 1.1.0 + + micromark-util-subtokenize@1.1.0: + dependencies: + micromark-util-chunked: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + + micromark-util-symbol@1.1.0: {} + + micromark-util-types@1.1.0: {} + + micromark@3.2.0: + dependencies: + '@types/debug': 4.1.12 + debug: 4.3.7(supports-color@5.5.0) + decode-named-character-reference: 1.0.2 + micromark-core-commonmark: 1.1.0 + micromark-factory-space: 1.1.0 + micromark-util-character: 1.2.0 + micromark-util-chunked: 1.1.0 + micromark-util-combine-extensions: 1.1.0 + micromark-util-decode-numeric-character-reference: 1.1.0 + micromark-util-encode: 1.1.0 + micromark-util-normalize-identifier: 1.1.0 + micromark-util-resolve-all: 1.1.0 + micromark-util-sanitize-uri: 1.2.0 + micromark-util-subtokenize: 1.1.0 + micromark-util-symbol: 1.1.0 + micromark-util-types: 1.1.0 + uvu: 0.5.6 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.1 + + mime-db@1.52.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + mimic-fn@2.1.0: {} + + mimic-response@1.0.1: {} + + mimic-response@3.1.0: {} + + mimic-response@4.0.0: {} + + min-document@2.19.0: + dependencies: + dom-walk: 0.1.2 + + minimalistic-assert@1.0.1: {} + + minimalistic-crypto-utils@1.0.1: {} + + minimatch@3.1.2: + dependencies: + brace-expansion: 1.1.11 + + minimatch@4.2.1: + dependencies: + brace-expansion: 1.1.11 + + minimatch@5.1.6: + dependencies: + brace-expansion: 2.0.1 + + minimist@1.2.8: {} + + minipass@2.9.0: + dependencies: + safe-buffer: 5.2.1 + yallist: 3.1.1 + + minizlib@1.3.3: + dependencies: + minipass: 2.9.0 + + mkdirp-classic@0.5.3: {} + + mkdirp-promise@5.0.1: + dependencies: + mkdirp: 3.0.1 + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mkdirp@1.0.4: {} + + mkdirp@3.0.1: {} + + mnemonist@0.38.5: + dependencies: + obliterator: 2.0.4 + + mocha@10.7.3: + dependencies: + ansi-colors: 4.1.3 + browser-stdout: 1.3.1 + chokidar: 3.6.0 + debug: 4.3.7(supports-color@8.1.1) + diff: 5.2.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 8.1.0 + he: 1.2.0 + js-yaml: 4.1.0 + log-symbols: 4.1.0 + minimatch: 5.1.6 + ms: 2.1.3 + serialize-javascript: 6.0.2 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + workerpool: 6.5.1 + yargs: 16.2.0 + yargs-parser: 20.2.9 + yargs-unparser: 2.0.0 + + mocha@9.2.2: + dependencies: + '@ungap/promise-all-settled': 1.1.2 + ansi-colors: 4.1.1 + browser-stdout: 1.3.1 + chokidar: 3.5.3 + debug: 4.3.3(supports-color@8.1.1) + diff: 5.0.0 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 7.2.0 + growl: 1.10.5 + he: 1.2.0 + js-yaml: 4.1.0 + log-symbols: 4.1.0 + minimatch: 4.2.1 + ms: 2.1.3 + nanoid: 3.3.1 + serialize-javascript: 6.0.0 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + which: 2.0.2 + workerpool: 6.2.0 + yargs: 16.2.0 + yargs-parser: 20.2.4 + yargs-unparser: 2.0.0 + + mock-fs@4.14.0: {} + + mri@1.2.0: {} + + ms@2.0.0: {} + + ms@2.1.2: {} + + ms@2.1.3: {} + + multibase@0.6.1: + dependencies: + base-x: 3.0.10 + buffer: 5.7.1 + + multibase@0.7.0: + dependencies: + base-x: 3.0.10 + buffer: 5.7.1 + + multicodec@0.5.7: + dependencies: + varint: 5.0.2 + + multicodec@1.0.4: + dependencies: + buffer: 5.7.1 + varint: 5.0.2 + + multihashes@0.4.21: + dependencies: + buffer: 5.7.1 + multibase: 0.7.0 + varint: 5.0.2 + + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + + nano-base32@1.0.1: {} + + nano-json-stream-parser@0.1.2: {} + + nanoid@3.3.1: {} + + nanoid@3.3.11: {} + + napi-build-utils@2.0.0: {} + + natural-compare-lite@1.4.0: {} + + natural-compare@1.4.0: {} + + ndjson@2.0.0: + dependencies: + json-stringify-safe: 5.0.1 + minimist: 1.2.8 + readable-stream: 3.6.2 + split2: 3.2.2 + through2: 4.0.2 + + negotiator@0.6.3: {} + + neo-async@2.6.2: {} + + next-tick@1.1.0: {} + + nise@4.1.0: + dependencies: + '@sinonjs/commons': 1.8.6 + '@sinonjs/fake-timers': 6.0.1 + '@sinonjs/text-encoding': 0.7.3 + just-extend: 4.2.1 + path-to-regexp: 1.9.0 + + nise@5.1.9: + dependencies: + '@sinonjs/commons': 3.0.1 + '@sinonjs/fake-timers': 11.3.1 + '@sinonjs/text-encoding': 0.7.3 + just-extend: 6.2.0 + path-to-regexp: 6.3.0 + + no-case@2.3.2: + dependencies: + lower-case: 1.1.4 + + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.8.0 + + node-abi@3.71.0: + dependencies: + semver: 7.6.3 + + node-addon-api@2.0.2: {} + + node-addon-api@3.2.1: {} + + node-addon-api@5.1.0: {} + + node-addon-api@6.1.0: {} + + node-emoji@1.11.0: + dependencies: + lodash: 4.17.21 + + node-fetch@2.7.0: + dependencies: + whatwg-url: 5.0.0 + + node-gyp-build@4.8.2: {} + + node-hid@2.1.2: + dependencies: + bindings: 1.5.0 + node-addon-api: 3.2.1 + prebuild-install: 7.1.3 + + node-preload@0.2.1: + dependencies: + process-on-spawn: 1.0.0 + + node-releases@2.0.18: {} + + nofilter@1.0.4: {} + + nofilter@3.1.0: {} + + non-layered-tidy-tree-layout@2.0.2: {} + + nopt@3.0.6: + dependencies: + abbrev: 1.0.9 + + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.17.0 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + + normalize-path@3.0.0: {} + + normalize-url@6.1.0: {} + + normalize-url@8.0.1: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + number-is-nan@1.0.1: {} + + number-to-bn@1.7.0: + dependencies: + bn.js: 4.11.6 + strip-hex-prefix: 1.0.0 + + nyc@15.1.0: + dependencies: + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + caching-transform: 4.0.0 + convert-source-map: 1.9.0 + decamelize: 1.2.0 + find-cache-dir: 3.3.2 + find-up: 4.1.0 + foreground-child: 2.0.0 + get-package-type: 0.1.0 + glob: 7.2.0 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-hook: 3.0.0 + istanbul-lib-instrument: 4.0.3 + istanbul-lib-processinfo: 2.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.7 + make-dir: 3.1.0 + node-preload: 0.2.1 + p-map: 3.0.0 + process-on-spawn: 1.0.0 + resolve-from: 5.0.0 + rimraf: 3.0.2 + signal-exit: 3.0.7 + spawn-wrap: 2.0.0 + test-exclude: 6.0.0 + yargs: 15.4.1 + transitivePeerDependencies: + - supports-color + + oauth-sign@0.9.0: {} + + object-assign@4.1.1: {} + + object-inspect@1.13.2: {} + + object-keys@1.1.1: {} + + object.assign@4.1.5: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + has-symbols: 1.0.3 + object-keys: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + + object.values@1.2.0: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + obliterator@2.0.4: {} + + oboe@2.1.5: + dependencies: + http-https: 1.0.0 + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + optionator@0.8.3: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.3.0 + prelude-ls: 1.1.2 + type-check: 0.3.2 + word-wrap: 1.2.5 + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + fast-levenshtein: 2.0.6 + levn: 0.4.1 + prelude-ls: 1.2.1 + type-check: 0.4.0 + word-wrap: 1.2.5 + + ora@5.4.1: + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.2 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + + ordinal@1.0.3: {} + + os-locale@1.4.0: + dependencies: + lcid: 1.0.0 + + os-tmpdir@1.0.2: {} + + outdent@0.5.0: {} + + p-cancelable@2.1.1: {} + + p-cancelable@3.0.0: {} + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-map@2.1.0: {} + + p-map@3.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-try@2.2.0: {} + + package-hash@4.0.0: + dependencies: + graceful-fs: 4.2.11 + hasha: 5.2.2 + lodash.flattendeep: 4.4.0 + release-zalgo: 1.0.0 + + package-json@8.1.1: + dependencies: + got: 12.6.1 + registry-auth-token: 5.0.2 + registry-url: 6.0.1 + semver: 7.6.3 + + package-manager-detector@0.2.2: {} + + pako@1.0.11: {} + + param-case@2.1.1: + dependencies: + no-case: 2.3.2 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-cache-control@1.0.1: {} + + parse-headers@2.0.5: {} + + parse-json@2.2.0: + dependencies: + error-ex: 1.3.2 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.25.9 + error-ex: 1.3.2 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse-ms@0.1.2: {} + + parse5-htmlparser2-tree-adapter@7.1.0: + dependencies: + domhandler: 5.0.3 + parse5: 7.2.0 + + parse5-parser-stream@7.1.2: + dependencies: + parse5: 7.2.0 + + parse5@7.2.0: + dependencies: + entities: 4.5.0 + + parseurl@1.3.3: {} + + pascal-case@2.0.1: + dependencies: + camel-case: 3.0.0 + upper-case-first: 1.1.2 + + path-case@2.1.1: + dependencies: + no-case: 2.3.2 + + path-exists@2.1.0: + dependencies: + pinkie-promise: 2.0.1 + + path-exists@4.0.0: {} + + path-is-absolute@1.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-to-regexp@0.1.10: {} + + path-to-regexp@1.9.0: + dependencies: + isarray: 0.0.1 + + path-to-regexp@6.3.0: {} + + path-type@1.1.0: + dependencies: + graceful-fs: 4.2.11 + pify: 2.3.0 + pinkie-promise: 2.0.1 + + path-type@4.0.0: {} + + pathval@1.1.1: {} + + pbkdf2@3.1.2: + dependencies: + create-hash: 1.2.0 + create-hmac: 1.1.7 + ripemd160: 2.0.2 + safe-buffer: 5.2.1 + sha.js: 2.4.11 + + performance-now@2.1.0: {} + + picocolors@1.1.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.1: {} + + picomatch@4.0.2: {} + + pify@2.3.0: {} + + pify@4.0.1: {} + + pinkie-promise@2.0.1: + dependencies: + pinkie: 2.0.4 + + pinkie@2.0.4: {} + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + pluralize@8.0.0: {} + + possible-typed-array-names@1.0.0: {} + + postcss-value-parser@4.2.0: {} + + postcss@8.5.3: + dependencies: + nanoid: 3.3.11 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prebuild-install@7.1.3: + dependencies: + detect-libc: 2.0.3 + expand-template: 2.0.3 + github-from-package: 0.0.0 + minimist: 1.2.8 + mkdirp-classic: 0.5.3 + napi-build-utils: 2.0.0 + node-abi: 3.71.0 + pump: 3.0.2 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.1 + tunnel-agent: 0.6.0 + + prelude-ls@1.1.2: {} + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.0: + dependencies: + fast-diff: 1.3.0 + + prettier@2.4.1: {} + + prettier@2.8.8: {} + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + pretty-ms@0.2.2: + dependencies: + parse-ms: 0.1.2 + + process-nextick-args@2.0.1: {} + + process-on-spawn@1.0.0: + dependencies: + fromentries: 1.3.2 + + process@0.11.10: {} + + promise@8.3.0: + dependencies: + asap: 2.0.6 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + proto-list@1.2.4: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + proxy-from-env@1.1.0: {} + + pseudomap@1.0.2: {} + + psl@1.9.0: {} + + pump@3.0.2: + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + + punycode@2.1.0: {} + + punycode@2.3.1: {} + + pure-rand@5.0.5: {} + + qs@6.13.0: + dependencies: + side-channel: 1.0.6 + + qs@6.5.3: {} + + query-string@5.1.1: + dependencies: + decode-uri-component: 0.2.2 + object-assign: 4.1.1 + strict-uri-encode: 1.1.0 + + queue-microtask@1.2.3: {} + + quick-lru@5.1.1: {} + + rambda@7.5.0: {} + + ramda@0.27.2: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + range-parser@1.2.1: {} + + raw-body@2.5.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + + react-dom@18.3.1(react@18.3.1): + dependencies: + loose-envify: 1.4.0 + react: 18.3.1 + scheduler: 0.23.2 + + react-is@16.13.1: {} + + react-is@18.3.1: {} + + react-refresh@0.14.2: {} + + react-router-dom@6.11.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@remix-run/router': 1.6.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-router: 6.11.0(react@18.3.1) + + react-router@6.11.0(react@18.3.1): + dependencies: + '@remix-run/router': 1.6.0 + react: 18.3.1 + + react-tooltip@5.28.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@floating-ui/dom': 1.6.13 + classnames: 2.5.1 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + + react@18.3.1: + dependencies: + loose-envify: 1.4.0 + + read-pkg-up@1.0.1: + dependencies: + find-up: 1.1.2 + read-pkg: 1.1.0 + + read-pkg@1.1.0: + dependencies: + load-json-file: 1.1.0 + normalize-package-data: 2.5.0 + path-type: 1.1.0 + + read-yaml-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + js-yaml: 3.14.1 + pify: 4.0.1 + strip-bom: 3.0.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.1 + + readdirp@4.0.2: {} + + rechoir@0.6.2: + dependencies: + resolve: 1.17.0 + + recursive-readdir@2.2.3: + dependencies: + minimatch: 3.1.2 + + reduce-flatten@2.0.0: {} + + regenerator-runtime@0.14.1: {} + + regexp.prototype.flags@1.5.3: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 + + registry-auth-token@5.0.2: + dependencies: + '@pnpm/npm-conf': 2.3.1 + + registry-url@6.0.1: + dependencies: + rc: 1.2.8 + + release-zalgo@1.0.0: + dependencies: + es6-error: 4.1.1 + + req-cwd@2.0.0: + dependencies: + req-from: 2.0.0 + + req-from@2.0.0: + dependencies: + resolve-from: 3.0.0 + + request@2.88.2: + dependencies: + aws-sign2: 0.7.0 + aws4: 1.13.2 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 2.3.3 + har-validator: 5.1.5 + http-signature: 1.2.0 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.35 + oauth-sign: 0.9.0 + performance-now: 2.1.0 + qs: 6.5.3 + safe-buffer: 5.2.1 + tough-cookie: 2.5.0 + tunnel-agent: 0.6.0 + uuid: 3.4.0 + + require-directory@2.1.1: {} + + require-from-string@1.2.1: {} + + require-from-string@2.0.2: {} + + require-main-filename@1.0.1: {} + + require-main-filename@2.0.0: {} + + requireindex@1.2.0: {} + + resolve-alpn@1.2.1: {} + + resolve-from@3.0.0: {} + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve@1.1.7: {} + + resolve@1.17.0: + dependencies: + path-parse: 1.0.7 + + resolve@1.19.0: + dependencies: + is-core-module: 2.15.1 + path-parse: 1.0.7 + + resolve@1.22.8: + dependencies: + is-core-module: 2.15.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + responselike@2.0.1: + dependencies: + lowercase-keys: 2.0.0 + + responselike@3.0.0: + dependencies: + lowercase-keys: 3.0.0 + + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + reusify@1.0.4: {} + + rimraf@2.7.1: + dependencies: + glob: 7.2.0 + + rimraf@3.0.2: + dependencies: + glob: 7.2.0 + + ripemd160-min@0.0.6: {} + + ripemd160@2.0.2: + dependencies: + hash-base: 3.1.0 + inherits: 2.0.4 + + rlp@2.2.7: + dependencies: + bn.js: 5.2.1 + + robust-predicates@3.0.2: {} + + rollup@4.39.0: + dependencies: + '@types/estree': 1.0.7 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.39.0 + '@rollup/rollup-android-arm64': 4.39.0 + '@rollup/rollup-darwin-arm64': 4.39.0 + '@rollup/rollup-darwin-x64': 4.39.0 + '@rollup/rollup-freebsd-arm64': 4.39.0 + '@rollup/rollup-freebsd-x64': 4.39.0 + '@rollup/rollup-linux-arm-gnueabihf': 4.39.0 + '@rollup/rollup-linux-arm-musleabihf': 4.39.0 + '@rollup/rollup-linux-arm64-gnu': 4.39.0 + '@rollup/rollup-linux-arm64-musl': 4.39.0 + '@rollup/rollup-linux-loongarch64-gnu': 4.39.0 + '@rollup/rollup-linux-powerpc64le-gnu': 4.39.0 + '@rollup/rollup-linux-riscv64-gnu': 4.39.0 + '@rollup/rollup-linux-riscv64-musl': 4.39.0 + '@rollup/rollup-linux-s390x-gnu': 4.39.0 + '@rollup/rollup-linux-x64-gnu': 4.39.0 + '@rollup/rollup-linux-x64-musl': 4.39.0 + '@rollup/rollup-win32-arm64-msvc': 4.39.0 + '@rollup/rollup-win32-ia32-msvc': 4.39.0 + '@rollup/rollup-win32-x64-msvc': 4.39.0 + fsevents: 2.3.3 + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + rw@1.3.3: {} + + rxjs@7.8.1: + dependencies: + tslib: 2.8.0 + + sade@1.8.1: + dependencies: + mri: 1.2.0 + + safe-array-concat@1.1.2: + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-regex-test@1.0.3: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-regex: 1.1.4 + + safer-buffer@2.1.2: {} + + sc-istanbul@0.4.6: + dependencies: + abbrev: 1.0.9 + async: 1.5.2 + escodegen: 1.8.1 + esprima: 2.7.3 + glob: 5.0.15 + handlebars: 4.7.8 + js-yaml: 3.14.1 + mkdirp: 0.5.6 + nopt: 3.0.6 + once: 1.4.0 + resolve: 1.1.7 + supports-color: 3.2.3 + which: 1.3.1 + wordwrap: 1.0.0 + + scheduler@0.23.2: + dependencies: + loose-envify: 1.4.0 + + scrypt-js@2.0.4: {} + + scrypt-js@3.0.1: {} + + secp256k1@4.0.4: + dependencies: + elliptic: 6.5.7 + node-addon-api: 5.1.0 + node-gyp-build: 4.8.2 + + semver@5.7.2: {} + + semver@6.3.1: {} + + semver@7.5.4: + dependencies: + lru-cache: 6.0.0 + + semver@7.6.3: {} + + send@0.19.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + + sentence-case@2.1.1: + dependencies: + no-case: 2.3.2 + upper-case-first: 1.1.2 + + serialize-javascript@6.0.0: + dependencies: + randombytes: 2.1.0 + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + serve-static@1.16.2: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.0 + transitivePeerDependencies: + - supports-color + + servify@0.1.12: + dependencies: + body-parser: 1.20.3 + cors: 2.8.5 + express: 4.21.1 + request: 2.88.2 + xhr: 2.6.0 + transitivePeerDependencies: + - supports-color + + set-blocking@2.0.0: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + setimmediate@1.0.4: {} + + setimmediate@1.0.5: {} + + setprototypeof@1.2.0: {} + + sha.js@2.4.11: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + sha1@1.1.1: + dependencies: + charenc: 0.0.2 + crypt: 0.0.2 + + sha3@2.1.4: + dependencies: + buffer: 6.0.3 + + shallowequal@1.1.0: {} + + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@1.0.0: {} + + shebang-regex@3.0.0: {} + + shelljs@0.8.5: + dependencies: + glob: 7.2.0 + interpret: 1.4.0 + rechoir: 0.6.2 + + side-channel@1.0.6: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + object-inspect: 1.13.2 + + signal-exit@3.0.7: {} + + simple-concat@1.0.1: {} + + simple-get@2.8.2: + dependencies: + decompress-response: 3.3.0 + once: 1.4.0 + simple-concat: 1.0.1 + + simple-get@4.0.1: + dependencies: + decompress-response: 6.0.0 + once: 1.4.0 + simple-concat: 1.0.1 + + sinon-chai@3.7.0(chai@4.5.0)(sinon@9.2.4): + dependencies: + chai: 4.5.0 + sinon: 9.2.4 + + sinon@14.0.2: + dependencies: + '@sinonjs/commons': 2.0.0 + '@sinonjs/fake-timers': 9.1.2 + '@sinonjs/samsam': 7.0.1 + diff: 5.2.0 + nise: 5.1.9 + supports-color: 7.2.0 + + sinon@9.2.4: + dependencies: + '@sinonjs/commons': 1.8.6 + '@sinonjs/fake-timers': 6.0.1 + '@sinonjs/samsam': 5.3.1 + diff: 4.0.2 + nise: 4.1.0 + supports-color: 7.2.0 + + sisteransi@1.0.5: {} + + slash@3.0.0: {} + + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + + snake-case@2.1.0: + dependencies: + no-case: 2.3.2 + + solc@0.4.26: + dependencies: + fs-extra: 0.30.0 + memorystream: 0.3.1 + require-from-string: 1.2.1 + semver: 5.7.2 + yargs: 4.8.1 + + solc@0.8.26(debug@4.3.7): + dependencies: + command-exists: 1.2.9 + commander: 8.3.0 + follow-redirects: 1.15.9(debug@4.3.7) + js-sha3: 0.8.0 + memorystream: 0.3.1 + semver: 5.7.2 + tmp: 0.0.33 + transitivePeerDependencies: + - debug + + solhint@5.0.3(typescript@5.0.4): + dependencies: + '@solidity-parser/parser': 0.18.0 + ajv: 6.12.6 + antlr4: 4.13.2 + ast-parents: 0.0.1 + chalk: 4.1.2 + commander: 10.0.1 + cosmiconfig: 8.3.6(typescript@5.0.4) + fast-diff: 1.3.0 + glob: 8.1.0 + ignore: 5.3.2 + js-yaml: 4.1.0 + latest-version: 7.0.0 + lodash: 4.17.21 + pluralize: 8.0.0 + semver: 7.6.3 + strip-ansi: 6.0.1 + table: 6.8.2 + text-table: 0.2.0 + optionalDependencies: + prettier: 2.8.8 + transitivePeerDependencies: + - typescript + + solidity-coverage@0.8.13(hardhat@packages+hardhat-core): + dependencies: + '@ethersproject/abi': 5.7.0 + '@solidity-parser/parser': 0.18.0 + chalk: 2.4.2 + death: 1.1.0 + difflib: 0.2.4 + fs-extra: 8.1.0 + ghost-testrpc: 0.0.2 + global-modules: 2.0.0 + globby: 10.0.2 + hardhat: link:packages/hardhat-core + jsonschema: 1.4.1 + lodash: 4.17.21 + mocha: 10.7.3 + node-emoji: 1.11.0 + pify: 4.0.1 + recursive-readdir: 2.2.3 + sc-istanbul: 0.4.6 + semver: 7.6.3 + shelljs: 0.8.5 + web3-utils: 1.10.4 + + solpp@0.11.5: + dependencies: + antlr4: 4.8.0 + axios: 0.21.4 + bn-str-256: 1.9.1 + commander: 2.20.3 + ethereumjs-util: 6.2.1 + lodash: 4.17.21 + mz: 2.7.0 + resolve: 1.17.0 + semver: 5.7.2 + transitivePeerDependencies: + - debug + + source-map-js@1.2.1: {} + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.2.0: + dependencies: + amdefine: 1.0.1 + optional: true + + source-map@0.6.1: {} + + spawn-wrap@2.0.0: + dependencies: + foreground-child: 2.0.0 + is-windows: 1.0.2 + make-dir: 3.1.0 + rimraf: 3.0.2 + signal-exit: 3.0.7 + which: 2.0.2 + + spawndamnit@2.0.0: + dependencies: + cross-spawn: 5.1.0 + signal-exit: 3.0.7 + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.20 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.20 + + spdx-license-ids@3.0.20: {} + + split2@3.2.2: + dependencies: + readable-stream: 3.6.2 + + sprintf-js@1.0.3: {} + + sshpk@1.18.0: + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 + + stable-hash@0.0.4: {} + + stacktrace-parser@0.1.10: + dependencies: + type-fest: 0.7.1 + + statuses@2.0.1: {} + + strict-uri-encode@1.1.0: {} + + string-argv@0.3.2: {} + + string-format@2.0.0: {} + + string-width@1.0.2: + dependencies: + code-point-at: 1.1.0 + is-fullwidth-code-point: 1.0.0 + strip-ansi: 3.0.1 + + string-width@2.1.1: + dependencies: + is-fullwidth-code-point: 2.0.0 + strip-ansi: 4.0.0 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string.prototype.trim@1.2.9: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.3 + es-object-atoms: 1.0.0 + + string.prototype.trimend@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-ansi@0.1.1: {} + + strip-ansi@3.0.1: + dependencies: + ansi-regex: 2.1.1 + + strip-ansi@4.0.0: + dependencies: + ansi-regex: 3.0.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-bom@2.0.0: + dependencies: + is-utf8: 0.2.1 + + strip-bom@3.0.0: {} + + strip-bom@4.0.0: {} + + strip-hex-prefix@1.0.0: + dependencies: + is-hex-prefixed: 1.0.0 + + strip-indent@2.0.0: {} + + strip-json-comments@2.0.1: {} + + strip-json-comments@3.1.1: {} + + styled-components@5.3.10(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1): + dependencies: + '@babel/helper-module-imports': 7.25.9(supports-color@5.5.0) + '@babel/traverse': 7.25.9(supports-color@5.5.0) + '@emotion/is-prop-valid': 1.3.1 + '@emotion/stylis': 0.8.5 + '@emotion/unitless': 0.7.5 + babel-plugin-styled-components: 2.1.4(@babel/core@7.26.0)(styled-components@5.3.10(@babel/core@7.26.0)(react-dom@18.3.1(react@18.3.1))(react-is@18.3.1)(react@18.3.1))(supports-color@5.5.0) + css-to-react-native: 3.2.0 + hoist-non-react-statics: 3.3.2 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + react-is: 18.3.1 + shallowequal: 1.1.0 + supports-color: 5.5.0 + transitivePeerDependencies: + - '@babel/core' + + stylis@4.3.5: {} + + supports-color@3.2.3: + dependencies: + has-flag: 1.0.0 + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svg-pan-zoom@3.6.2: {} + + swap-case@1.1.2: + dependencies: + lower-case: 1.1.4 + upper-case: 1.1.3 + + swarm-js@0.1.42(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + bluebird: 3.7.2 + buffer: 5.7.1 + eth-lib: 0.1.29(bufferutil@4.0.8)(utf-8-validate@5.0.10) + fs-extra: 4.0.3 + got: 11.8.6 + mime-types: 2.1.35 + mkdirp-promise: 5.0.1 + mock-fs: 4.14.0 + setimmediate: 1.0.5 + tar: 4.4.19 + xhr-request: 1.1.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + sync-request@6.1.0: + dependencies: + http-response-object: 3.0.2 + sync-rpc: 1.3.6 + then-request: 6.0.2 + + sync-rpc@1.3.6: + dependencies: + get-port: 3.2.0 + + table-layout@1.0.2: + dependencies: + array-back: 4.0.2 + deep-extend: 0.6.0 + typical: 5.2.0 + wordwrapjs: 4.0.1 + + table@6.8.2: + dependencies: + ajv: 8.17.1 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + tapable@2.2.1: {} + + tar-fs@2.1.1: + dependencies: + chownr: 1.1.4 + mkdirp-classic: 0.5.3 + pump: 3.0.2 + tar-stream: 2.2.0 + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.4 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + tar@4.4.19: + dependencies: + chownr: 1.1.4 + fs-minipass: 1.2.7 + minipass: 2.9.0 + minizlib: 1.3.3 + mkdirp: 0.5.6 + safe-buffer: 5.2.1 + yallist: 3.1.1 + + term-size@2.2.1: {} + + test-exclude@6.0.0: + dependencies: + '@istanbuljs/schema': 0.1.3 + glob: 7.2.0 + minimatch: 3.1.2 + + testrpc@0.0.1: {} + + text-table@0.2.0: {} + + then-request@6.0.2: + dependencies: + '@types/concat-stream': 1.6.1 + '@types/form-data': 0.0.33 + '@types/node': 8.10.66 + '@types/qs': 6.9.16 + caseless: 0.12.0 + concat-stream: 1.6.2 + form-data: 2.5.2 + http-basic: 8.1.3 + http-response-object: 3.0.2 + promise: 8.3.0 + qs: 6.13.0 + + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + + through2@4.0.2: + dependencies: + readable-stream: 3.6.2 + + time-require@0.1.2: + dependencies: + chalk: 0.4.0 + date-time: 0.1.1 + pretty-ms: 0.2.2 + text-table: 0.2.0 + + timed-out@4.0.1: {} + + tinyglobby@0.2.6: + dependencies: + fdir: 6.3.0(picomatch@4.0.2) + picomatch: 4.0.2 + + title-case@2.1.1: + dependencies: + no-case: 2.3.2 + upper-case: 1.1.3 + + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + tough-cookie@2.5.0: + dependencies: + psl: 1.9.0 + punycode: 2.3.1 + + tr46@0.0.3: {} + + truffle-blockchain-utils@0.0.5: {} + + truffle-contract-schema@2.0.3: + dependencies: + ajv: 5.5.2 + crypto-js: 3.3.0 + debug: 3.2.7 + transitivePeerDependencies: + - supports-color + + truffle-contract@3.0.8: + dependencies: + ethjs-abi: 0.1.8 + truffle-blockchain-utils: 0.0.5 + truffle-contract-schema: 2.0.3 + truffle-error: 0.0.3 + web3: 0.20.6 + transitivePeerDependencies: + - supports-color + + truffle-error@0.0.3: {} + + ts-command-line-args@2.5.1: + dependencies: + chalk: 4.1.2 + command-line-args: 5.2.1 + command-line-usage: 6.1.3 + string-format: 2.0.0 + + ts-dedent@2.2.0: {} + + ts-essentials@7.0.3(typescript@5.0.4): + dependencies: + typescript: 5.0.4 + + ts-node@10.9.1(@types/node@18.19.59)(typescript@5.0.4): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 18.19.59 + acorn: 8.13.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.0.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + ts-node@10.9.1(@types/node@22.7.5)(typescript@5.0.4): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 22.7.5 + acorn: 8.13.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.0.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + ts-node@10.9.2(@types/node@18.19.59)(typescript@5.0.4): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.11 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 18.19.59 + acorn: 8.13.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.2 + make-error: 1.3.6 + typescript: 5.0.4 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@1.14.1: {} + + tslib@2.7.0: {} + + tslib@2.8.0: {} + + tsort@0.0.1: {} + + tsutils@3.21.0(typescript@5.0.4): + dependencies: + tslib: 1.14.1 + typescript: 5.0.4 + + tsutils@3.21.0(typescript@5.3.3): + dependencies: + tslib: 1.14.1 + typescript: 5.3.3 + + tunnel-agent@0.6.0: + dependencies: + safe-buffer: 5.2.1 + + tweetnacl@0.14.5: {} + + type-check@0.3.2: + dependencies: + prelude-ls: 1.1.2 + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-detect@4.0.8: {} + + type-detect@4.1.0: {} + + type-fest@0.20.2: {} + + type-fest@0.21.3: {} + + type-fest@0.7.1: {} + + type-fest@0.8.1: {} + + type-fest@2.19.0: {} + + type-fest@3.13.1: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + type@2.7.3: {} + + typechain@8.3.2(typescript@5.0.4): + dependencies: + '@types/prettier': 2.7.3 + debug: 4.3.7(supports-color@5.5.0) + fs-extra: 7.0.1 + glob: 7.1.7 + js-sha3: 0.8.0 + lodash: 4.17.21 + mkdirp: 1.0.4 + prettier: 2.8.8 + ts-command-line-args: 2.5.1 + ts-essentials: 7.0.3(typescript@5.0.4) + typescript: 5.0.4 + transitivePeerDependencies: + - supports-color + + typed-array-buffer@1.0.2: + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + + typed-array-byte-length@1.0.1: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-byte-offset@1.0.2: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + typed-array-length@1.0.6: + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 + + typedarray-to-buffer@3.1.5: + dependencies: + is-typedarray: 1.0.0 + + typedarray@0.0.6: {} + + typescript@5.0.4: {} + + typescript@5.3.3: {} + + typical@4.0.0: {} + + typical@5.2.0: {} + + uglify-js@3.19.3: + optional: true + + ultron@1.1.1: {} + + unbox-primitive@1.0.2: + dependencies: + call-bind: 1.0.7 + has-bigints: 1.0.2 + has-symbols: 1.0.3 + which-boxed-primitive: 1.0.2 + + underscore@1.13.7: {} + + undici-types@5.26.5: {} + + undici-types@6.19.8: {} + + undici@5.28.4: + dependencies: + '@fastify/busboy': 2.1.1 + + undici@6.20.1: {} + + unist-util-stringify-position@3.0.3: + dependencies: + '@types/unist': 2.0.11 + + universalify@0.1.2: {} + + universalify@2.0.1: {} + + unpipe@1.0.0: {} + + untildify@4.0.0: {} + + update-browserslist-db@1.1.1(browserslist@4.24.2): + dependencies: + browserslist: 4.24.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + upper-case-first@1.1.2: + dependencies: + upper-case: 1.1.3 + + upper-case@1.1.3: {} + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + url-set-query@1.0.0: {} + + usb@2.9.0: + dependencies: + '@types/w3c-web-usb': 1.0.10 + node-addon-api: 6.1.0 + node-gyp-build: 4.8.2 + + utf-8-validate@5.0.10: + dependencies: + node-gyp-build: 4.8.2 + + utf8@2.1.2: {} + + utf8@3.0.0: {} + + util-deprecate@1.0.2: {} + + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.1.1 + is-generator-function: 1.0.10 + is-typed-array: 1.1.13 + which-typed-array: 1.1.15 + + utils-merge@1.0.1: {} + + uuid@2.0.1: {} + + uuid@3.4.0: {} + + uuid@8.3.2: {} + + uuid@9.0.1: {} + + uvu@0.5.6: + dependencies: + dequal: 2.0.3 + diff: 5.2.0 + kleur: 4.1.5 + sade: 1.8.1 + + v8-compile-cache-lib@3.0.1: {} + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + validator@13.12.0: {} + + varint@5.0.2: {} + + vary@1.1.2: {} + + verror@1.10.0: + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.3.0 + + viem@2.21.34(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + '@scure/bip32': 1.5.0 + '@scure/bip39': 1.4.0 + abitype: 1.0.6(typescript@5.0.4)(zod@3.23.8) + isows: 1.0.6(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + webauthn-p256: 0.0.10 + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.0.4 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + vite-plugin-singlefile@2.1.0(rollup@4.39.0)(vite@5.4.17(@types/node@22.7.5)): + dependencies: + micromatch: 4.0.8 + rollup: 4.39.0 + vite: 5.4.17(@types/node@22.7.5) + + vite@5.4.17(@types/node@22.7.5): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.3 + rollup: 4.39.0 + optionalDependencies: + '@types/node': 22.7.5 + fsevents: 2.3.3 + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + + web-worker@1.3.0: {} + + web3-bzz@1.10.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@types/node': 12.20.55 + got: 12.1.0 + swarm-js: 0.1.42(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + web3-bzz@1.10.4(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@types/node': 12.20.55 + got: 12.1.0 + swarm-js: 0.1.42(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + web3-core-helpers@1.10.0: + dependencies: + web3-eth-iban: 1.10.0 + web3-utils: 1.10.0 + + web3-core-helpers@1.10.4: + dependencies: + web3-eth-iban: 1.10.4 + web3-utils: 1.10.4 + + web3-core-method@1.10.0: + dependencies: + '@ethersproject/transactions': 5.7.0 + web3-core-helpers: 1.10.0 + web3-core-promievent: 1.10.0 + web3-core-subscriptions: 1.10.0 + web3-utils: 1.10.0 + + web3-core-method@1.10.4: + dependencies: + '@ethersproject/transactions': 5.7.0 + web3-core-helpers: 1.10.4 + web3-core-promievent: 1.10.4 + web3-core-subscriptions: 1.10.4 + web3-utils: 1.10.4 + + web3-core-promievent@1.10.0: + dependencies: + eventemitter3: 4.0.4 + + web3-core-promievent@1.10.4: + dependencies: + eventemitter3: 4.0.4 + + web3-core-requestmanager@1.10.0: + dependencies: + util: 0.12.5 + web3-core-helpers: 1.10.0 + web3-providers-http: 1.10.0 + web3-providers-ipc: 1.10.0 + web3-providers-ws: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-core-requestmanager@1.10.4: + dependencies: + util: 0.12.5 + web3-core-helpers: 1.10.4 + web3-providers-http: 1.10.4 + web3-providers-ipc: 1.10.4 + web3-providers-ws: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-core-subscriptions@1.10.0: + dependencies: + eventemitter3: 4.0.4 + web3-core-helpers: 1.10.0 + + web3-core-subscriptions@1.10.4: + dependencies: + eventemitter3: 4.0.4 + web3-core-helpers: 1.10.4 + + web3-core@1.10.0: + dependencies: + '@types/bn.js': 5.1.6 + '@types/node': 12.20.55 + bignumber.js: 9.2.1 + web3-core-helpers: 1.10.0 + web3-core-method: 1.10.0 + web3-core-requestmanager: 1.10.0 + web3-utils: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-core@1.10.4: + dependencies: + '@types/bn.js': 5.1.6 + '@types/node': 12.20.55 + bignumber.js: 9.1.2 + web3-core-helpers: 1.10.4 + web3-core-method: 1.10.4 + web3-core-requestmanager: 1.10.4 + web3-utils: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-core@4.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + web3-errors: 1.3.0 + web3-eth-accounts: 4.2.1 + web3-eth-iban: 4.0.7 + web3-providers-http: 4.2.0 + web3-providers-ws: 4.0.8(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-types: 1.8.1 + web3-utils: 4.3.2 + web3-validator: 2.0.6 + optionalDependencies: + web3-providers-ipc: 4.0.7 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + web3-errors@1.3.0: + dependencies: + web3-types: 1.8.1 + + web3-eth-abi@1.10.0: + dependencies: + '@ethersproject/abi': 5.7.0 + web3-utils: 1.10.0 + + web3-eth-abi@1.10.4: + dependencies: + '@ethersproject/abi': 5.7.0 + web3-utils: 1.10.4 + + web3-eth-abi@4.3.0(typescript@5.0.4)(zod@3.23.8): + dependencies: + abitype: 0.7.1(typescript@5.0.4)(zod@3.23.8) + web3-errors: 1.3.0 + web3-types: 1.8.1 + web3-utils: 4.3.2 + web3-validator: 2.0.6 + transitivePeerDependencies: + - typescript + - zod + + web3-eth-accounts@1.10.0: + dependencies: + '@ethereumjs/common': 2.5.0 + '@ethereumjs/tx': 3.3.2 + eth-lib: 0.2.8 + ethereumjs-util: 7.1.5 + scrypt-js: 3.0.1 + uuid: 9.0.1 + web3-core: 1.10.0 + web3-core-helpers: 1.10.0 + web3-core-method: 1.10.0 + web3-utils: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-accounts@1.10.4: + dependencies: + '@ethereumjs/common': 2.6.5 + '@ethereumjs/tx': 3.5.2 + '@ethereumjs/util': 8.1.0 + eth-lib: 0.2.8 + scrypt-js: 3.0.1 + uuid: 9.0.1 + web3-core: 1.10.4 + web3-core-helpers: 1.10.4 + web3-core-method: 1.10.4 + web3-utils: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-accounts@4.2.1: + dependencies: + '@ethereumjs/rlp': 4.0.1 + crc-32: 1.2.2 + ethereum-cryptography: 2.2.1 + web3-errors: 1.3.0 + web3-types: 1.8.1 + web3-utils: 4.3.2 + web3-validator: 2.0.6 + + web3-eth-contract@1.10.0: + dependencies: + '@types/bn.js': 5.1.6 + web3-core: 1.10.0 + web3-core-helpers: 1.10.0 + web3-core-method: 1.10.0 + web3-core-promievent: 1.10.0 + web3-core-subscriptions: 1.10.0 + web3-eth-abi: 1.10.0 + web3-utils: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-contract@1.10.4: + dependencies: + '@types/bn.js': 5.1.6 + web3-core: 1.10.4 + web3-core-helpers: 1.10.4 + web3-core-method: 1.10.4 + web3-core-promievent: 1.10.4 + web3-core-subscriptions: 1.10.4 + web3-eth-abi: 1.10.4 + web3-utils: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-contract@4.7.0(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8): + dependencies: + '@ethereumjs/rlp': 5.0.2 + web3-core: 4.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-errors: 1.3.0 + web3-eth: 4.10.0(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8) + web3-eth-abi: 4.3.0(typescript@5.0.4)(zod@3.23.8) + web3-types: 1.8.1 + web3-utils: 4.3.2 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + web3-eth-ens@1.10.0: + dependencies: + content-hash: 2.5.2 + eth-ens-namehash: 2.0.8 + web3-core: 1.10.0 + web3-core-helpers: 1.10.0 + web3-core-promievent: 1.10.0 + web3-eth-abi: 1.10.0 + web3-eth-contract: 1.10.0 + web3-utils: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-ens@1.10.4: + dependencies: + content-hash: 2.5.2 + eth-ens-namehash: 2.0.8 + web3-core: 1.10.4 + web3-core-helpers: 1.10.4 + web3-core-promievent: 1.10.4 + web3-eth-abi: 1.10.4 + web3-eth-contract: 1.10.4 + web3-utils: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-ens@4.4.0(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8): + dependencies: + '@adraffy/ens-normalize': 1.11.0 + web3-core: 4.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-errors: 1.3.0 + web3-eth: 4.10.0(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8) + web3-eth-contract: 4.7.0(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8) + web3-net: 4.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-types: 1.8.1 + web3-utils: 4.3.2 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + web3-eth-iban@1.10.0: + dependencies: + bn.js: 5.2.1 + web3-utils: 1.10.0 + + web3-eth-iban@1.10.4: + dependencies: + bn.js: 5.2.1 + web3-utils: 1.10.4 + + web3-eth-iban@4.0.7: + dependencies: + web3-errors: 1.3.0 + web3-types: 1.8.1 + web3-utils: 4.3.2 + web3-validator: 2.0.6 + + web3-eth-personal@1.10.0: + dependencies: + '@types/node': 12.20.55 + web3-core: 1.10.0 + web3-core-helpers: 1.10.0 + web3-core-method: 1.10.0 + web3-net: 1.10.0 + web3-utils: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-personal@1.10.4: + dependencies: + '@types/node': 12.20.55 + web3-core: 1.10.4 + web3-core-helpers: 1.10.4 + web3-core-method: 1.10.4 + web3-net: 1.10.4 + web3-utils: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth-personal@4.1.0(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8): + dependencies: + web3-core: 4.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-eth: 4.10.0(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8) + web3-rpc-methods: 1.3.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-types: 1.8.1 + web3-utils: 4.3.2 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + web3-eth@1.10.0: + dependencies: + web3-core: 1.10.0 + web3-core-helpers: 1.10.0 + web3-core-method: 1.10.0 + web3-core-subscriptions: 1.10.0 + web3-eth-abi: 1.10.0 + web3-eth-accounts: 1.10.0 + web3-eth-contract: 1.10.0 + web3-eth-ens: 1.10.0 + web3-eth-iban: 1.10.0 + web3-eth-personal: 1.10.0 + web3-net: 1.10.0 + web3-utils: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth@1.10.4: + dependencies: + web3-core: 1.10.4 + web3-core-helpers: 1.10.4 + web3-core-method: 1.10.4 + web3-core-subscriptions: 1.10.4 + web3-eth-abi: 1.10.4 + web3-eth-accounts: 1.10.4 + web3-eth-contract: 1.10.4 + web3-eth-ens: 1.10.4 + web3-eth-iban: 1.10.4 + web3-eth-personal: 1.10.4 + web3-net: 1.10.4 + web3-utils: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-eth@4.10.0(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8): + dependencies: + setimmediate: 1.0.5 + web3-core: 4.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-errors: 1.3.0 + web3-eth-abi: 4.3.0(typescript@5.0.4)(zod@3.23.8) + web3-eth-accounts: 4.2.1 + web3-net: 4.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-providers-ws: 4.0.8(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-rpc-methods: 1.3.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-types: 1.8.1 + web3-utils: 4.3.2 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + web3-net@1.10.0: + dependencies: + web3-core: 1.10.0 + web3-core-method: 1.10.0 + web3-utils: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-net@1.10.4: + dependencies: + web3-core: 1.10.4 + web3-core-method: 1.10.4 + web3-utils: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-net@4.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + web3-core: 4.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-rpc-methods: 1.3.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-types: 1.8.1 + web3-utils: 4.3.2 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + web3-providers-http@1.10.0: + dependencies: + abortcontroller-polyfill: 1.7.5 + cross-fetch: 3.1.8 + es6-promise: 4.2.8 + web3-core-helpers: 1.10.0 + transitivePeerDependencies: + - encoding + + web3-providers-http@1.10.4: + dependencies: + abortcontroller-polyfill: 1.7.5 + cross-fetch: 4.0.0 + es6-promise: 4.2.8 + web3-core-helpers: 1.10.4 + transitivePeerDependencies: + - encoding + + web3-providers-http@4.2.0: + dependencies: + cross-fetch: 4.0.0 + web3-errors: 1.3.0 + web3-types: 1.8.1 + web3-utils: 4.3.2 + transitivePeerDependencies: + - encoding + + web3-providers-ipc@1.10.0: + dependencies: + oboe: 2.1.5 + web3-core-helpers: 1.10.0 + + web3-providers-ipc@1.10.4: + dependencies: + oboe: 2.1.5 + web3-core-helpers: 1.10.4 + + web3-providers-ipc@4.0.7: + dependencies: + web3-errors: 1.3.0 + web3-types: 1.8.1 + web3-utils: 4.3.2 + optional: true + + web3-providers-ws@1.10.0: + dependencies: + eventemitter3: 4.0.4 + web3-core-helpers: 1.10.0 + websocket: 1.0.35 + transitivePeerDependencies: + - supports-color + + web3-providers-ws@1.10.4: + dependencies: + eventemitter3: 4.0.4 + web3-core-helpers: 1.10.4 + websocket: 1.0.35 + transitivePeerDependencies: + - supports-color + + web3-providers-ws@4.0.8(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + '@types/ws': 8.5.3 + isomorphic-ws: 5.0.0(ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10)) + web3-errors: 1.3.0 + web3-types: 1.8.1 + web3-utils: 4.3.2 + ws: 8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + web3-rpc-methods@1.3.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + web3-core: 4.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-types: 1.8.1 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + web3-rpc-providers@1.0.0-rc.2(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + web3-errors: 1.3.0 + web3-providers-http: 4.2.0 + web3-providers-ws: 4.0.8(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-types: 1.8.1 + web3-utils: 4.3.2 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - utf-8-validate + + web3-shh@1.10.0: + dependencies: + web3-core: 1.10.0 + web3-core-method: 1.10.0 + web3-core-subscriptions: 1.10.0 + web3-net: 1.10.0 + transitivePeerDependencies: + - encoding + - supports-color + + web3-shh@1.10.4: + dependencies: + web3-core: 1.10.4 + web3-core-method: 1.10.4 + web3-core-subscriptions: 1.10.4 + web3-net: 1.10.4 + transitivePeerDependencies: + - encoding + - supports-color + + web3-types@1.8.1: {} + + web3-utils@1.10.0: + dependencies: + bn.js: 5.2.1 + ethereum-bloom-filters: 1.2.0 + ethereumjs-util: 7.1.5 + ethjs-unit: 0.1.6 + number-to-bn: 1.7.0 + randombytes: 2.1.0 + utf8: 3.0.0 + + web3-utils@1.10.4: + dependencies: + '@ethereumjs/util': 8.1.0 + bn.js: 5.2.1 + ethereum-bloom-filters: 1.2.0 + ethereum-cryptography: 2.2.1 + ethjs-unit: 0.1.6 + number-to-bn: 1.7.0 + randombytes: 2.1.0 + utf8: 3.0.0 + + web3-utils@4.3.2: + dependencies: + ethereum-cryptography: 2.2.1 + eventemitter3: 5.0.1 + web3-errors: 1.3.0 + web3-types: 1.8.1 + web3-validator: 2.0.6 + + web3-validator@2.0.6: + dependencies: + ethereum-cryptography: 2.2.1 + util: 0.12.5 + web3-errors: 1.3.0 + web3-types: 1.8.1 + zod: 3.23.8 + + web3@0.20.6: + dependencies: + bignumber.js: https://codeload.github.com/frozeman/bignumber.js-nolookahead/tar.gz/57692b3ecfc98bbdd6b3a516cb2353652ea49934 + crypto-js: 3.3.0 + utf8: 2.1.2 + xhr2: 0.2.1 + xmlhttprequest: 1.8.0 + + web3@0.20.7: + dependencies: + bignumber.js: https://codeload.github.com/frozeman/bignumber.js-nolookahead/tar.gz/57692b3ecfc98bbdd6b3a516cb2353652ea49934 + crypto-js: 3.3.0 + utf8: 2.1.2 + xhr2-cookies: 1.1.0 + xmlhttprequest: 1.8.0 + + web3@1.10.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + web3-bzz: 1.10.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-core: 1.10.0 + web3-eth: 1.10.0 + web3-eth-personal: 1.10.0 + web3-net: 1.10.0 + web3-shh: 1.10.0 + web3-utils: 1.10.0 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + web3@1.10.4(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + web3-bzz: 1.10.4(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-core: 1.10.4 + web3-eth: 1.10.4 + web3-eth-personal: 1.10.4 + web3-net: 1.10.4 + web3-shh: 1.10.4 + web3-utils: 1.10.4 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + web3@4.14.0(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8): + dependencies: + web3-core: 4.7.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-errors: 1.3.0 + web3-eth: 4.10.0(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8) + web3-eth-abi: 4.3.0(typescript@5.0.4)(zod@3.23.8) + web3-eth-accounts: 4.2.1 + web3-eth-contract: 4.7.0(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8) + web3-eth-ens: 4.4.0(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8) + web3-eth-iban: 4.0.7 + web3-eth-personal: 4.1.0(bufferutil@4.0.8)(typescript@5.0.4)(utf-8-validate@5.0.10)(zod@3.23.8) + web3-net: 4.1.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-providers-http: 4.2.0 + web3-providers-ws: 4.0.8(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-rpc-methods: 1.3.0(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-rpc-providers: 1.0.0-rc.2(bufferutil@4.0.8)(utf-8-validate@5.0.10) + web3-types: 1.8.1 + web3-utils: 4.3.2 + web3-validator: 2.0.6 + transitivePeerDependencies: + - bufferutil + - encoding + - typescript + - utf-8-validate + - zod + + webauthn-p256@0.0.10: + dependencies: + '@noble/curves': 1.6.0 + '@noble/hashes': 1.5.0 + + webidl-conversions@3.0.1: {} + + websocket@1.0.35: + dependencies: + bufferutil: 4.0.8 + debug: 2.6.9 + es5-ext: 0.10.64 + typedarray-to-buffer: 3.1.5 + utf-8-validate: 5.0.10 + yaeti: 0.0.6 + transitivePeerDependencies: + - supports-color + + whatwg-encoding@3.1.1: + dependencies: + iconv-lite: 0.6.3 + + whatwg-fetch@3.6.20: {} + + whatwg-mimetype@4.0.0: {} + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + which-boxed-primitive@1.0.2: + dependencies: + is-bigint: 1.0.4 + is-boolean-object: 1.1.2 + is-number-object: 1.0.7 + is-string: 1.0.7 + is-symbol: 1.0.4 + + which-module@1.0.0: {} + + which-module@2.0.1: {} + + which-typed-array@1.1.15: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-tostringtag: 1.0.2 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + widest-line@3.1.0: + dependencies: + string-width: 4.2.3 + + window-size@0.2.0: {} + + word-wrap@1.2.5: {} + + wordwrap@1.0.0: {} + + wordwrapjs@4.0.1: + dependencies: + reduce-flatten: 2.0.0 + typical: 5.2.0 + + workerpool@6.2.0: {} + + workerpool@6.5.1: {} + + wrap-ansi@2.1.0: + dependencies: + string-width: 1.0.2 + strip-ansi: 3.0.1 + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrappy@1.0.2: {} + + write-file-atomic@3.0.3: + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.7 + typedarray-to-buffer: 3.1.5 + + ws@3.3.3(bufferutil@4.0.8)(utf-8-validate@5.0.10): + dependencies: + async-limiter: 1.0.1 + safe-buffer: 5.1.2 + ultron: 1.1.1 + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + ws@7.4.6(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + ws@7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + ws@8.17.1(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + ws@8.18.0(bufferutil@4.0.8)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.8 + utf-8-validate: 5.0.10 + + xhr-request-promise@0.1.3: + dependencies: + xhr-request: 1.1.0 + + xhr-request@1.1.0: + dependencies: + buffer-to-arraybuffer: 0.0.5 + object-assign: 4.1.1 + query-string: 5.1.1 + simple-get: 2.8.2 + timed-out: 4.0.1 + url-set-query: 1.0.0 + xhr: 2.6.0 + + xhr2-cookies@1.1.0: + dependencies: + cookiejar: 2.1.4 + + xhr2@0.2.1: {} + + xhr@2.6.0: + dependencies: + global: 4.4.0 + is-function: 1.0.2 + parse-headers: 2.0.5 + xtend: 4.0.2 + + xmlhttprequest@1.8.0: {} + + xtend@4.0.2: {} + + y18n@3.2.2: {} + + y18n@4.0.3: {} + + y18n@5.0.8: {} + + yaeti@0.0.6: {} + + yallist@2.1.2: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yargs-parser@18.1.3: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + + yargs-parser@2.4.1: + dependencies: + camelcase: 3.0.0 + lodash.assign: 4.2.0 + + yargs-parser@20.2.4: {} + + yargs-parser@20.2.9: {} + + yargs-unparser@2.0.0: + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + + yargs@15.4.1: + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + + yargs@4.8.1: + dependencies: + cliui: 3.2.0 + decamelize: 1.2.0 + get-caller-file: 1.0.3 + lodash.assign: 4.2.0 + os-locale: 1.4.0 + read-pkg-up: 1.0.1 + require-directory: 2.1.1 + require-main-filename: 1.0.1 + set-blocking: 2.0.0 + string-width: 1.0.2 + which-module: 1.0.0 + window-size: 0.2.0 + y18n: 3.2.2 + yargs-parser: 2.4.1 + + yn@3.1.1: {} + + yocto-queue@0.1.0: {} + + z-schema@5.0.5: + dependencies: + lodash.get: 4.4.2 + lodash.isequal: 4.5.0 + validator: 13.12.0 + optionalDependencies: + commander: 9.5.0 + + zod@3.23.8: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000000..bb0d1e032a --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,3 @@ +packages: + - "packages/*" + - "!packages/hardhat-ignition-examples" diff --git a/scripts/check-dependencies.js b/scripts/check-dependencies.js index a9012784e5..6dd0ac0700 100644 --- a/scripts/check-dependencies.js +++ b/scripts/check-dependencies.js @@ -1,6 +1,16 @@ const fs = require("fs"); const path = require("path"); +// Ignition packages are allowed to have different versions of the same +// dependency for now as we will sync them properly in Hardhat v3 +const IGNORE_SAME_VERSION_FOR_IGNITION_PACKAGES = [ + "@nomicfoundation/hardhat-ignition", + "@nomicfoundation/ignition-core", + "@nomicfoundation/hardhat-ignition-ethers", + "@nomicfoundation/hardhat-ignition-viem", + "@nomicfoundation/ignition-ui", +]; + // An array of dependencies whose version checks are ignored for all the // packages const IGNORE_SAME_VERSION_FROM_ALL = ["web3", "hardhat"]; @@ -14,16 +24,8 @@ const IGNORE_SAME_VERSION_FOR_PACKAGES = { "@nomiclabs/hardhat-truffle5", ], ethers: ["@nomicfoundation/hardhat-verify"], - ["@types/node"]: ["docs"], - ["@typescript-eslint/eslint-plugin"]: ["docs"], - ["@typescript-eslint/parser"]: ["docs"], - eslint: ["docs"], - ["eslint-config-prettier"]: ["docs"], - ["eslint-plugin-prettier"]: ["docs"], - ["glob"]: ["docs"], - ["undici"]: ["docs"], - ["ts-node"]: ["docs", "hardhat"], - ["typescript"]: ["docs", "hardhat"], + ["ts-node"]: ["hardhat"], + ["typescript"]: ["hardhat"], }; const IGNORE_PEER_DEPENDENCIES_CHECK_FOR_PACKAGES = { @@ -31,7 +33,7 @@ const IGNORE_PEER_DEPENDENCIES_CHECK_FOR_PACKAGES = { ["ts-node"]: ["hardhat"], }; -function checkPeerDepedencies(packageJson) { +function checkPeerDependencies(packageJson) { if (packageJson.peerDependencies === undefined) { return true; } @@ -64,10 +66,10 @@ function checkPeerDepedencies(packageJson) { continue; } - if ( - packageJson.peerDependencies[dependency] !== - packageJson.devDependencies[dependency] - ) { + const peerDep = packageJson.peerDependencies[dependency]; + const devDep = packageJson.devDependencies[dependency]; + + if (peerDep !== devDep) { console.error( `${packageJson.name} has different versions of ${dependency} as peerDependency and devDependency` ); @@ -84,14 +86,16 @@ function addDependencies(packageName, dependenciesToAdd, allDependenciesMap) { return; } - for (const [name, spec] of Object.entries(dependenciesToAdd)) { + for (const [name, specWithWorspace] of Object.entries(dependenciesToAdd)) { + const spec = specWithWorspace.replace(/^workspace:/, ""); if (IGNORE_SAME_VERSION_FROM_ALL.includes(name)) { continue; } if ( - IGNORE_SAME_VERSION_FOR_PACKAGES[name] !== undefined && - IGNORE_SAME_VERSION_FOR_PACKAGES[name].includes(packageName) + (IGNORE_SAME_VERSION_FOR_PACKAGES[name] !== undefined && + IGNORE_SAME_VERSION_FOR_PACKAGES[name].includes(packageName)) || + IGNORE_SAME_VERSION_FOR_IGNITION_PACKAGES.includes(packageName) ) { continue; } @@ -147,12 +151,12 @@ function mergeDependenciesMap(dependencyMaps) { function getAllPackageJsonPaths() { const packageNames = fs.readdirSync(path.join(__dirname, "..", "packages")); - const packageJsons = packageNames.map((p) => - path.join(__dirname, "..", "packages", p, "package.json") - ); + const packageJsons = packageNames + // ignore hh-etherscan and hh-waffle because they only have a readme + .filter((p) => !["hardhat-etherscan", "hardhat-waffle"].includes(p)) + .map((p) => path.join(__dirname, "..", "packages", p, "package.json")); packageJsons.push(path.join(__dirname, "..", "package.json")); - packageJsons.push(path.join(__dirname, "..", "docs", "package.json")); return packageJsons; } @@ -168,12 +172,15 @@ function main() { const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8")); - // temporarily ignore hardhat-toolbox - if (packageJson.name === "@nomicfoundation/hardhat-toolbox") { + // temporarily ignore hardhat toolboxs + if ( + packageJson.name === "@nomicfoundation/hardhat-toolbox" || + packageJson.name === "@nomicfoundation/hardhat-toolbox-viem" + ) { continue; } - const peersOk = checkPeerDepedencies(packageJson); + const peersOk = checkPeerDependencies(packageJson); const dependencyMap = getDependencyMap(packageJson); dependencyMaps.push(dependencyMap); diff --git a/scripts/generate-filters.js b/scripts/generate-filters.js new file mode 100644 index 0000000000..8218059b29 --- /dev/null +++ b/scripts/generate-filters.js @@ -0,0 +1,76 @@ +// @ts-check +/** + * This script generates filters for https://github.com/dorny/paths-filter + * + * It is used in CI to find all the packages which have been modified or + * have a dependency (including transitive) that has been modified. + * + * This enables running checks only for the packages affected by the changes. + */ +const fs = require("fs"); +const path = require("path"); + +function main() { + const packageIgnore = JSON.parse(process.env.PACKAGE_IGNORE || "[]"); + const commonFilters = JSON.parse(process.env.COMMON_FILTERS || "[]"); + + const pnpmLockfilePath = path.join(__dirname, "..", "pnpm-lock.json"); + if (!fs.existsSync(pnpmLockfilePath)) { + console.warn( + `${pnpmLockfilePath} doesn't exist, please run: yq -p yaml -o json pnpm-lock.yaml | tee pnpm-lock.json` + ); + process.exit(1); + } + + const pnpmLockfile = JSON.parse(fs.readFileSync(pnpmLockfilePath, "utf8")); + + // Find all direct internal dependencies for all packages + const internalDependenciesMap = {}; + for (const [package, allDependencies] of Object.entries( + pnpmLockfile.importers + )) { + const internalDependencies = Object.values(allDependencies) + .flatMap((dependencies) => Object.values(dependencies)) + .map((dependency) => dependency.version) + .filter((version) => version.startsWith("link:")) + .map((version) => version.replace("link:", "")) + .map((version) => path.join(package, version)); + internalDependenciesMap[package] = internalDependencies; + } + + // Add transitive internal dependencies + for (const dependencies of Object.values(internalDependenciesMap)) { + const dependencyQueue = [...dependencies]; + while (dependencyQueue.length !== 0) { + const dependency = dependencyQueue.pop(); + for (const transitiveDependency of internalDependenciesMap[dependency]) { + if (!dependencies.includes(transitiveDependency)) { + dependencies.push(transitiveDependency); + dependencyQueue.push(transitiveDependency); + } + } + } + } + + // Generate filters + const filters = {}; + for (const [package, dependencies] of Object.entries( + internalDependenciesMap + )) { + // Ignore packages that start with one of the prefixes in PACKAGE_IGNORE + if (packageIgnore.some((prefix) => package.startsWith(prefix))) { + continue; + } + // Calculate glob patterns for the package and its dependencies + const packageFilters = [package, ...dependencies].map((dependency) => + path.join(dependency, "**") + ); + // Set filters for the package + filters[package] = [...commonFilters, ...packageFilters]; + } + + // Pretty print the filters + console.log(JSON.stringify(filters, null, 2)); +} + +main(); diff --git a/scripts/run-tests-with-custom-solc.sh b/scripts/run-tests-with-custom-solc.sh index 7497d6f093..3a1c680140 100755 --- a/scripts/run-tests-with-custom-solc.sh +++ b/scripts/run-tests-with-custom-solc.sh @@ -11,8 +11,8 @@ fi cd "$(git rev-parse --show-toplevel)" # install dependencies -yarn +pnpm install # run hardhat tests cd packages/hardhat-core -yarn test +pnpm test diff --git a/scripts/run-tests.js b/scripts/run-tests.js index ed6aa38096..c9cf5ea804 100644 --- a/scripts/run-tests.js +++ b/scripts/run-tests.js @@ -13,7 +13,7 @@ const isGithubActions = process.env.GITHUB_WORKFLOW !== undefined; const isLinux = os.type() === "Linux"; const isWindows = os.type() === "Windows_NT"; -shell.exec("yarn build"); +shell.exec("pnpm build"); // ** check for packages to be ignored ** // @@ -23,7 +23,7 @@ const shouldIgnoreSolppTests = isWindows; const ignoredPackagesList = []; if (shouldIgnoreSolppTests) { - ignoredPackagesList.push("--exclude @nomiclabs/hardhat-solpp"); + ignoredPackagesList.push("--filter=!@nomiclabs/hardhat-solpp"); } const ignoredPackages = ignoredPackagesList.join(" "); @@ -32,8 +32,8 @@ function runTests() { console.time("Total test time"); try { - const fastExit = process.env.NO_FAST_EXIT ? "" : "--fast-exit"; - const command = `yarn wsrun --serial ${fastExit} --exclude-missing ${ignoredPackages} test`; + const fastExit = process.env.NO_FAST_EXIT ? "--no-bail" : "--bail"; + const command = `pnpm run --recursive --workspace-concurrency 1 ${fastExit} ${ignoredPackages} test`; shell.exec(command); } finally { diff --git a/scripts/setup.sh b/scripts/setup.sh new file mode 100755 index 0000000000..7a961a91cb --- /dev/null +++ b/scripts/setup.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -euo pipefail + +sudo apt update + +# TODO: nodejs, npm, yarn +# libudev-dev is required by hardhat-ledger +sudo apt install -y libudev-dev diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index 8f15159e61..0000000000 --- a/yarn.lock +++ /dev/null @@ -1,9843 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@ampproject/remapping@^2.2.0": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" - integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - -"@babel/code-frame@^7.0.0": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" - integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== - dependencies: - "@babel/highlight" "^7.18.6" - -"@babel/code-frame@^7.18.6", "@babel/code-frame@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.21.4.tgz#d0fa9e4413aca81f2b23b9442797bda1826edb39" - integrity sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g== - dependencies: - "@babel/highlight" "^7.18.6" - -"@babel/compat-data@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.4.tgz#457ffe647c480dff59c2be092fc3acf71195c87f" - integrity sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g== - -"@babel/core@^7.7.5": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.4.tgz#c6dc73242507b8e2a27fd13a9c1814f9fa34a659" - integrity sha512-qt/YV149Jman/6AfmlxJ04LMIu8bMoyl3RB91yTFrxQmgbrSvQMy7cI8Q62FHx1t8wJ8B5fu0UDoLwHAhUo1QA== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.21.4" - "@babel/generator" "^7.21.4" - "@babel/helper-compilation-targets" "^7.21.4" - "@babel/helper-module-transforms" "^7.21.2" - "@babel/helpers" "^7.21.0" - "@babel/parser" "^7.21.4" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.4" - "@babel/types" "^7.21.4" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.2" - semver "^6.3.0" - -"@babel/generator@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.4.tgz#64a94b7448989f421f919d5239ef553b37bb26bc" - integrity sha512-NieM3pVIYW2SwGzKoqfPrQsf4xGs9M9AIG3ThppsSRmO+m7eQhmI6amajKMUeIO37wFfsvnvcxQFx6x6iqxDnA== - dependencies: - "@babel/types" "^7.21.4" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/helper-compilation-targets@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.21.4.tgz#770cd1ce0889097ceacb99418ee6934ef0572656" - integrity sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg== - dependencies: - "@babel/compat-data" "^7.21.4" - "@babel/helper-validator-option" "^7.21.0" - browserslist "^4.21.3" - lru-cache "^5.1.1" - semver "^6.3.0" - -"@babel/helper-environment-visitor@^7.18.9": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" - integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== - -"@babel/helper-function-name@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4" - integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== - dependencies: - "@babel/template" "^7.20.7" - "@babel/types" "^7.21.0" - -"@babel/helper-hoist-variables@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" - integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-module-imports@^7.18.6": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.21.4.tgz#ac88b2f76093637489e718a90cec6cf8a9b029af" - integrity sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg== - dependencies: - "@babel/types" "^7.21.4" - -"@babel/helper-module-transforms@^7.21.2": - version "7.21.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz#160caafa4978ac8c00ac66636cb0fa37b024e2d2" - integrity sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ== - dependencies: - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-simple-access" "^7.20.2" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/helper-validator-identifier" "^7.19.1" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.2" - "@babel/types" "^7.21.2" - -"@babel/helper-simple-access@^7.20.2": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9" - integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA== - dependencies: - "@babel/types" "^7.20.2" - -"@babel/helper-split-export-declaration@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" - integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== - dependencies: - "@babel/types" "^7.18.6" - -"@babel/helper-string-parser@^7.19.4": - version "7.19.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63" - integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw== - -"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1": - version "7.19.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" - integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== - -"@babel/helper-validator-option@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180" - integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== - -"@babel/helpers@^7.21.0": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.0.tgz#9dd184fb5599862037917cdc9eecb84577dc4e7e" - integrity sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA== - dependencies: - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.21.0" - "@babel/types" "^7.21.0" - -"@babel/highlight@^7.10.4", "@babel/highlight@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" - integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== - dependencies: - "@babel/helper-validator-identifier" "^7.18.6" - chalk "^2.0.0" - js-tokens "^4.0.0" - -"@babel/parser@^7.20.7", "@babel/parser@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.4.tgz#94003fdfc520bbe2875d4ae557b43ddb6d880f17" - integrity sha512-alVJj7k7zIxqBZ7BTRhz0IqJFxW1VJbm6N8JbcYhQ186df9ZBPbZBmWSqAMXwHGsCJdYks7z/voa3ibiS5bCIw== - -"@babel/runtime@^7.20.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5": - version "7.20.13" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.13.tgz#7055ab8a7cff2b8f6058bf6ae45ff84ad2aded4b" - integrity sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA== - dependencies: - regenerator-runtime "^0.13.11" - -"@babel/template@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8" - integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - -"@babel/traverse@^7.21.0", "@babel/traverse@^7.21.2", "@babel/traverse@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.4.tgz#a836aca7b116634e97a6ed99976236b3282c9d36" - integrity sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q== - dependencies: - "@babel/code-frame" "^7.21.4" - "@babel/generator" "^7.21.4" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.21.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.21.4" - "@babel/types" "^7.21.4" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.18.6", "@babel/types@^7.20.2", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.2", "@babel/types@^7.21.4": - version "7.21.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.4.tgz#2d5d6bb7908699b3b416409ffd3b5daa25b030d4" - integrity sha512-rU2oY501qDxE8Pyo7i/Orqma4ziCOrby0/9mvbDUGEfvZjb279Nk9k19e2fiCxHbRRpY2ZyrgW1eq22mvmOIzA== - dependencies: - "@babel/helper-string-parser" "^7.19.4" - "@babel/helper-validator-identifier" "^7.19.1" - to-fast-properties "^2.0.0" - -"@chainsafe/as-sha256@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@chainsafe/as-sha256/-/as-sha256-0.3.1.tgz#3639df0e1435cab03f4d9870cc3ac079e57a6fc9" - integrity sha512-hldFFYuf49ed7DAakWVXSJODuq3pzJEguD8tQ7h+sGkM18vja+OFoJI9krnGmgzyuZC2ETX0NOIcCTy31v2Mtg== - -"@chainsafe/persistent-merkle-tree@^0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.4.2.tgz#4c9ee80cc57cd3be7208d98c40014ad38f36f7ff" - integrity sha512-lLO3ihKPngXLTus/L7WHKaw9PnNJWizlOF1H9NNzHP6Xvh82vzg9F2bzkXhYIFshMZ2gTCEz8tq6STe7r5NDfQ== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - -"@chainsafe/persistent-merkle-tree@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@chainsafe/persistent-merkle-tree/-/persistent-merkle-tree-0.5.0.tgz#2b4a62c9489a5739dedd197250d8d2f5427e9f63" - integrity sha512-l0V1b5clxA3iwQLXP40zYjyZYospQLZXzBVIhhr9kDg/1qHZfzzHw0jj4VPBijfYCArZDlPkRi1wZaV2POKeuw== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - -"@chainsafe/ssz@^0.10.0": - version "0.10.2" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.10.2.tgz#c782929e1bb25fec66ba72e75934b31fd087579e" - integrity sha512-/NL3Lh8K+0q7A3LsiFq09YXS9fPE+ead2rr7vM2QK8PLzrNsw3uqrif9bpRX5UxgeRjM+vYi+boCM3+GM4ovXg== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.5.0" - -"@chainsafe/ssz@^0.9.2": - version "0.9.4" - resolved "https://registry.yarnpkg.com/@chainsafe/ssz/-/ssz-0.9.4.tgz#696a8db46d6975b600f8309ad3a12f7c0e310497" - integrity sha512-77Qtg2N1ayqs4Bg/wvnWfg5Bta7iy7IRh8XqXh7oNMeP2HBbBwx8m6yTpA8p0EHItWPEBkgZd5S5/LSlp3GXuQ== - dependencies: - "@chainsafe/as-sha256" "^0.3.1" - "@chainsafe/persistent-merkle-tree" "^0.4.2" - case "^1.6.3" - -"@changesets/apply-release-plan@^6.1.3": - version "6.1.3" - resolved "https://registry.yarnpkg.com/@changesets/apply-release-plan/-/apply-release-plan-6.1.3.tgz#3bcc0bd57ba00d50d20df7d0141f1a9b2134eaf7" - integrity sha512-ECDNeoc3nfeAe1jqJb5aFQX7CqzQhD2klXRez2JDb/aVpGUbX673HgKrnrgJRuQR/9f2TtLoYIzrGB9qwD77mg== - dependencies: - "@babel/runtime" "^7.20.1" - "@changesets/config" "^2.3.0" - "@changesets/get-version-range-type" "^0.3.2" - "@changesets/git" "^2.0.0" - "@changesets/types" "^5.2.1" - "@manypkg/get-packages" "^1.1.3" - detect-indent "^6.0.0" - fs-extra "^7.0.1" - lodash.startcase "^4.4.0" - outdent "^0.5.0" - prettier "^2.7.1" - resolve-from "^5.0.0" - semver "^5.4.1" - -"@changesets/assemble-release-plan@^5.2.3": - version "5.2.3" - resolved "https://registry.yarnpkg.com/@changesets/assemble-release-plan/-/assemble-release-plan-5.2.3.tgz#5ce6191c6e193d40b566a7b0e01690cfb106f4db" - integrity sha512-g7EVZCmnWz3zMBAdrcKhid4hkHT+Ft1n0mLussFMcB1dE2zCuwcvGoy9ec3yOgPGF4hoMtgHaMIk3T3TBdvU9g== - dependencies: - "@babel/runtime" "^7.20.1" - "@changesets/errors" "^0.1.4" - "@changesets/get-dependents-graph" "^1.3.5" - "@changesets/types" "^5.2.1" - "@manypkg/get-packages" "^1.1.3" - semver "^5.4.1" - -"@changesets/changelog-git@^0.1.14": - version "0.1.14" - resolved "https://registry.yarnpkg.com/@changesets/changelog-git/-/changelog-git-0.1.14.tgz#852caa7727dcf91497c131d05bc2cd6248532ada" - integrity sha512-+vRfnKtXVWsDDxGctOfzJsPhaCdXRYoe+KyWYoq5X/GqoISREiat0l3L8B0a453B2B4dfHGcZaGyowHbp9BSaA== - dependencies: - "@changesets/types" "^5.2.1" - -"@changesets/cli@^2.16.0": - version "2.26.0" - resolved "https://registry.yarnpkg.com/@changesets/cli/-/cli-2.26.0.tgz#f215ddb2b41574ffd0dda9cd77fac927ba048fd3" - integrity sha512-0cbTiDms+ICTVtEwAFLNW0jBNex9f5+fFv3I771nBvdnV/mOjd1QJ4+f8KtVSOrwD9SJkk9xbDkWFb0oXd8d1Q== - dependencies: - "@babel/runtime" "^7.20.1" - "@changesets/apply-release-plan" "^6.1.3" - "@changesets/assemble-release-plan" "^5.2.3" - "@changesets/changelog-git" "^0.1.14" - "@changesets/config" "^2.3.0" - "@changesets/errors" "^0.1.4" - "@changesets/get-dependents-graph" "^1.3.5" - "@changesets/get-release-plan" "^3.0.16" - "@changesets/git" "^2.0.0" - "@changesets/logger" "^0.0.5" - "@changesets/pre" "^1.0.14" - "@changesets/read" "^0.5.9" - "@changesets/types" "^5.2.1" - "@changesets/write" "^0.2.3" - "@manypkg/get-packages" "^1.1.3" - "@types/is-ci" "^3.0.0" - "@types/semver" "^6.0.0" - ansi-colors "^4.1.3" - chalk "^2.1.0" - enquirer "^2.3.0" - external-editor "^3.1.0" - fs-extra "^7.0.1" - human-id "^1.0.2" - is-ci "^3.0.1" - meow "^6.0.0" - outdent "^0.5.0" - p-limit "^2.2.0" - preferred-pm "^3.0.0" - resolve-from "^5.0.0" - semver "^5.4.1" - spawndamnit "^2.0.0" - term-size "^2.1.0" - tty-table "^4.1.5" - -"@changesets/config@^2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@changesets/config/-/config-2.3.0.tgz#bff074d6492fa772cee139f9a04efa4cd56445bb" - integrity sha512-EgP/px6mhCx8QeaMAvWtRrgyxW08k/Bx2tpGT+M84jEdX37v3VKfh4Cz1BkwrYKuMV2HZKeHOh8sHvja/HcXfQ== - dependencies: - "@changesets/errors" "^0.1.4" - "@changesets/get-dependents-graph" "^1.3.5" - "@changesets/logger" "^0.0.5" - "@changesets/types" "^5.2.1" - "@manypkg/get-packages" "^1.1.3" - fs-extra "^7.0.1" - micromatch "^4.0.2" - -"@changesets/errors@^0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@changesets/errors/-/errors-0.1.4.tgz#f79851746c43679a66b383fdff4c012f480f480d" - integrity sha512-HAcqPF7snsUJ/QzkWoKfRfXushHTu+K5KZLJWPb34s4eCZShIf8BFO3fwq6KU8+G7L5KdtN2BzQAXOSXEyiY9Q== - dependencies: - extendable-error "^0.1.5" - -"@changesets/get-dependents-graph@^1.3.5": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@changesets/get-dependents-graph/-/get-dependents-graph-1.3.5.tgz#f94c6672d2f9a87aa35512eea74550585ba41c21" - integrity sha512-w1eEvnWlbVDIY8mWXqWuYE9oKhvIaBhzqzo4ITSJY9hgoqQ3RoBqwlcAzg11qHxv/b8ReDWnMrpjpKrW6m1ZTA== - dependencies: - "@changesets/types" "^5.2.1" - "@manypkg/get-packages" "^1.1.3" - chalk "^2.1.0" - fs-extra "^7.0.1" - semver "^5.4.1" - -"@changesets/get-release-plan@^3.0.16": - version "3.0.16" - resolved "https://registry.yarnpkg.com/@changesets/get-release-plan/-/get-release-plan-3.0.16.tgz#5d9cfc4ffda02c496ef0fde407210de8e3a0fb19" - integrity sha512-OpP9QILpBp1bY2YNIKFzwigKh7Qe9KizRsZomzLe6pK8IUo8onkAAVUD8+JRKSr8R7d4+JRuQrfSSNlEwKyPYg== - dependencies: - "@babel/runtime" "^7.20.1" - "@changesets/assemble-release-plan" "^5.2.3" - "@changesets/config" "^2.3.0" - "@changesets/pre" "^1.0.14" - "@changesets/read" "^0.5.9" - "@changesets/types" "^5.2.1" - "@manypkg/get-packages" "^1.1.3" - -"@changesets/get-version-range-type@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@changesets/get-version-range-type/-/get-version-range-type-0.3.2.tgz#8131a99035edd11aa7a44c341cbb05e668618c67" - integrity sha512-SVqwYs5pULYjYT4op21F2pVbcrca4qA/bAA3FmFXKMN7Y+HcO8sbZUTx3TAy2VXulP2FACd1aC7f2nTuqSPbqg== - -"@changesets/git@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@changesets/git/-/git-2.0.0.tgz#8de57649baf13a86eb669a25fa51bcad5cea517f" - integrity sha512-enUVEWbiqUTxqSnmesyJGWfzd51PY4H7mH9yUw0hPVpZBJ6tQZFMU3F3mT/t9OJ/GjyiM4770i+sehAn6ymx6A== - dependencies: - "@babel/runtime" "^7.20.1" - "@changesets/errors" "^0.1.4" - "@changesets/types" "^5.2.1" - "@manypkg/get-packages" "^1.1.3" - is-subdir "^1.1.1" - micromatch "^4.0.2" - spawndamnit "^2.0.0" - -"@changesets/logger@^0.0.5": - version "0.0.5" - resolved "https://registry.yarnpkg.com/@changesets/logger/-/logger-0.0.5.tgz#68305dd5a643e336be16a2369cb17cdd8ed37d4c" - integrity sha512-gJyZHomu8nASHpaANzc6bkQMO9gU/ib20lqew1rVx753FOxffnCrJlGIeQVxNWCqM+o6OOleCo/ivL8UAO5iFw== - dependencies: - chalk "^2.1.0" - -"@changesets/parse@^0.3.16": - version "0.3.16" - resolved "https://registry.yarnpkg.com/@changesets/parse/-/parse-0.3.16.tgz#f8337b70aeb476dc81745ab3294022909bc4a84a" - integrity sha512-127JKNd167ayAuBjUggZBkmDS5fIKsthnr9jr6bdnuUljroiERW7FBTDNnNVyJ4l69PzR57pk6mXQdtJyBCJKg== - dependencies: - "@changesets/types" "^5.2.1" - js-yaml "^3.13.1" - -"@changesets/pre@^1.0.14": - version "1.0.14" - resolved "https://registry.yarnpkg.com/@changesets/pre/-/pre-1.0.14.tgz#9df73999a4d15804da7381358d77bb37b00ddf0f" - integrity sha512-dTsHmxQWEQekHYHbg+M1mDVYFvegDh9j/kySNuDKdylwfMEevTeDouR7IfHNyVodxZXu17sXoJuf2D0vi55FHQ== - dependencies: - "@babel/runtime" "^7.20.1" - "@changesets/errors" "^0.1.4" - "@changesets/types" "^5.2.1" - "@manypkg/get-packages" "^1.1.3" - fs-extra "^7.0.1" - -"@changesets/read@^0.5.9": - version "0.5.9" - resolved "https://registry.yarnpkg.com/@changesets/read/-/read-0.5.9.tgz#a1b63a82b8e9409738d7a0f9cc39b6d7c28cbab0" - integrity sha512-T8BJ6JS6j1gfO1HFq50kU3qawYxa4NTbI/ASNVVCBTsKquy2HYwM9r7ZnzkiMe8IEObAJtUVGSrePCOxAK2haQ== - dependencies: - "@babel/runtime" "^7.20.1" - "@changesets/git" "^2.0.0" - "@changesets/logger" "^0.0.5" - "@changesets/parse" "^0.3.16" - "@changesets/types" "^5.2.1" - chalk "^2.1.0" - fs-extra "^7.0.1" - p-filter "^2.1.0" - -"@changesets/types@^4.0.1": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@changesets/types/-/types-4.1.0.tgz#fb8f7ca2324fd54954824e864f9a61a82cb78fe0" - integrity sha512-LDQvVDv5Kb50ny2s25Fhm3d9QSZimsoUGBsUioj6MC3qbMUCuC8GPIvk/M6IvXx3lYhAs0lwWUQLb+VIEUCECw== - -"@changesets/types@^5.2.1": - version "5.2.1" - resolved "https://registry.yarnpkg.com/@changesets/types/-/types-5.2.1.tgz#a228c48004aa8a93bce4be2d1d31527ef3bf21f6" - integrity sha512-myLfHbVOqaq9UtUKqR/nZA/OY7xFjQMdfgfqeZIBK4d0hA6pgxArvdv8M+6NUzzBsjWLOtvApv8YHr4qM+Kpfg== - -"@changesets/write@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@changesets/write/-/write-0.2.3.tgz#baf6be8ada2a67b9aba608e251bfea4fdc40bc63" - integrity sha512-Dbamr7AIMvslKnNYsLFafaVORx4H0pvCA2MHqgtNCySMe1blImEyAEOzDmcgKAkgz4+uwoLz7demIrX+JBr/Xw== - dependencies: - "@babel/runtime" "^7.20.1" - "@changesets/types" "^5.2.1" - fs-extra "^7.0.1" - human-id "^1.0.2" - prettier "^2.7.1" - -"@cspotcode/source-map-support@^0.8.0": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" - integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" - -"@ensdomains/address-encoder@^0.1.7": - version "0.1.9" - resolved "https://registry.yarnpkg.com/@ensdomains/address-encoder/-/address-encoder-0.1.9.tgz#f948c485443d9ef7ed2c0c4790e931c33334d02d" - integrity sha512-E2d2gP4uxJQnDu2Kfg1tHNspefzbLT8Tyjrm5sEuim32UkU2sm5xL4VXtgc2X33fmPEw9+jUMpGs4veMbf+PYg== - dependencies: - bech32 "^1.1.3" - blakejs "^1.1.0" - bn.js "^4.11.8" - bs58 "^4.0.1" - crypto-addr-codec "^0.1.7" - nano-base32 "^1.0.1" - ripemd160 "^2.0.2" - -"@ensdomains/ens@0.4.5": - version "0.4.5" - resolved "https://registry.yarnpkg.com/@ensdomains/ens/-/ens-0.4.5.tgz#e0aebc005afdc066447c6e22feb4eda89a5edbfc" - integrity sha512-JSvpj1iNMFjK6K+uVl4unqMoa9rf5jopb8cya5UGBWz23Nw8hSNT7efgUx4BTlAPAgpNlEioUfeTyQ6J9ZvTVw== - dependencies: - bluebird "^3.5.2" - eth-ens-namehash "^2.0.8" - solc "^0.4.20" - testrpc "0.0.1" - web3-utils "^1.0.0-beta.31" - -"@ensdomains/ensjs@^2.0.1": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@ensdomains/ensjs/-/ensjs-2.1.0.tgz#0a7296c1f3d735ef019320d863a7846a0760c460" - integrity sha512-GRbGPT8Z/OJMDuxs75U/jUNEC0tbL0aj7/L/QQznGYKm/tiasp+ndLOaoULy9kKJFC0TBByqfFliEHDgoLhyog== - dependencies: - "@babel/runtime" "^7.4.4" - "@ensdomains/address-encoder" "^0.1.7" - "@ensdomains/ens" "0.4.5" - "@ensdomains/resolver" "0.2.4" - content-hash "^2.5.2" - eth-ens-namehash "^2.0.8" - ethers "^5.0.13" - js-sha3 "^0.8.0" - -"@ensdomains/resolver@0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@ensdomains/resolver/-/resolver-0.2.4.tgz#c10fe28bf5efbf49bff4666d909aed0265efbc89" - integrity sha512-bvaTH34PMCbv6anRa9I/0zjLJgY4EuznbEMgbV77JBCQ9KNC46rzi0avuxpOfu+xDjPEtSFGqVEOr5GlUSGudA== - -"@eslint/eslintrc@^0.4.3": - version "0.4.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" - integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== - dependencies: - ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^13.9.0" - ignore "^4.0.6" - import-fresh "^3.2.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" - strip-json-comments "^3.1.1" - -"@ethereumjs/common@2.5.0": - version "2.5.0" - resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.5.0.tgz#ec61551b31bef7a69d1dc634d8932468866a4268" - integrity sha512-DEHjW6e38o+JmB/NO3GZBpW4lpaiBpkFgXF6jLcJ6gETBYpEyaA5nTimsWBUJR3Vmtm/didUEbNjajskugZORg== - dependencies: - crc-32 "^1.2.0" - ethereumjs-util "^7.1.1" - -"@ethereumjs/common@^2.5.0": - version "2.6.5" - resolved "https://registry.yarnpkg.com/@ethereumjs/common/-/common-2.6.5.tgz#0a75a22a046272579d91919cb12d84f2756e8d30" - integrity sha512-lRyVQOeCDaIVtgfbowla32pzeDv2Obr8oR8Put5RdUBNRGr1VGPGQNGP6elWIpgK3YdpzqTOh4GyUGOureVeeA== - dependencies: - crc-32 "^1.2.0" - ethereumjs-util "^7.1.5" - -"@ethereumjs/tx@3.3.2": - version "3.3.2" - resolved "https://registry.yarnpkg.com/@ethereumjs/tx/-/tx-3.3.2.tgz#348d4624bf248aaab6c44fec2ae67265efe3db00" - integrity sha512-6AaJhwg4ucmwTvw/1qLaZUX5miWrwZ4nLOUsKyb/HtzS3BMw/CasKhdi1ims9mBKeK9sOJCH4qGKOBGyJCeeog== - dependencies: - "@ethereumjs/common" "^2.5.0" - ethereumjs-util "^7.1.2" - -"@ethersproject/abi@5.7.0", "@ethersproject/abi@^5.0.0-beta.146", "@ethersproject/abi@^5.0.9", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.4.7", "@ethersproject/abi@^5.6.3", "@ethersproject/abi@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" - integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/abstract-provider@5.7.0", "@ethersproject/abstract-provider@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef" - integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - -"@ethersproject/abstract-signer@5.7.0", "@ethersproject/abstract-signer@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2" - integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/address@5.7.0", "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" - integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - -"@ethersproject/base64@5.7.0", "@ethersproject/base64@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c" - integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - -"@ethersproject/basex@5.7.0", "@ethersproject/basex@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/basex/-/basex-5.7.0.tgz#97034dc7e8938a8ca943ab20f8a5e492ece4020b" - integrity sha512-ywlh43GwZLv2Voc2gQVTKBoVQ1mti3d8HK5aMxsfu/nRDnMmNqaSJ3r3n85HBByT8OpoY96SXM1FogC533T4zw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - -"@ethersproject/bignumber@5.7.0", "@ethersproject/bignumber@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" - integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - bn.js "^5.2.1" - -"@ethersproject/bytes@5.7.0", "@ethersproject/bytes@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" - integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/constants@5.7.0", "@ethersproject/constants@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e" - integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - -"@ethersproject/contracts@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e" - integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== - dependencies: - "@ethersproject/abi" "^5.7.0" - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - -"@ethersproject/hash@5.7.0", "@ethersproject/hash@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" - integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/hdnode@5.7.0", "@ethersproject/hdnode@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.7.0.tgz#e627ddc6b466bc77aebf1a6b9e47405ca5aef9cf" - integrity sha512-OmyYo9EENBPPf4ERhR7oj6uAtUAhYGqOnIS+jE5pTXvdKBS99ikzq1E7Iv0ZQZ5V36Lqx1qZLeak0Ra16qpeOg== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/json-wallets@5.7.0", "@ethersproject/json-wallets@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.7.0.tgz#5e3355287b548c32b368d91014919ebebddd5360" - integrity sha512-8oee5Xgu6+RKgJTkvEMl2wDgSPSAQ9MB/3JYjFV9jlKvcYHUXZC+cQp0njgmxdHkYWn8s6/IqIZYm0YWCjO/0g== - dependencies: - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/pbkdf2" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - aes-js "3.0.0" - scrypt-js "3.0.1" - -"@ethersproject/keccak256@5.7.0", "@ethersproject/keccak256@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" - integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - js-sha3 "0.8.0" - -"@ethersproject/logger@5.7.0", "@ethersproject/logger@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" - integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== - -"@ethersproject/networks@5.7.1", "@ethersproject/networks@^5.7.0": - version "5.7.1" - resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" - integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/pbkdf2@5.7.0", "@ethersproject/pbkdf2@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.7.0.tgz#d2267d0a1f6e123f3771007338c47cccd83d3102" - integrity sha512-oR/dBRZR6GTyaofd86DehG72hY6NpAjhabkhxgr3X2FpJtJuodEl2auADWBZfhDHgVCbu3/H/Ocq2uC6dpNjjw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - -"@ethersproject/properties@5.7.0", "@ethersproject/properties@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" - integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== - dependencies: - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/providers@5.7.2", "@ethersproject/providers@^5.4.7", "@ethersproject/providers@^5.7.1", "@ethersproject/providers@^5.7.2": - version "5.7.2" - resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.7.2.tgz#f8b1a4f275d7ce58cf0a2eec222269a08beb18cb" - integrity sha512-g34EWZ1WWAVgr4aptGlVBF8mhl3VWjv+8hoAnzStu8Ah22VHBsuGzP17eb6xDVRzw895G4W7vvx60lFFur/1Rg== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/base64" "^5.7.0" - "@ethersproject/basex" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/networks" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/web" "^5.7.0" - bech32 "1.1.4" - ws "7.4.6" - -"@ethersproject/random@5.7.0", "@ethersproject/random@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.7.0.tgz#af19dcbc2484aae078bb03656ec05df66253280c" - integrity sha512-19WjScqRA8IIeWclFme75VMXSBvi4e6InrUNuaR4s5pTF2qNhcGdCUwdxUVGtDDqC00sDLCO93jPQoDUH4HVmQ== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/rlp@5.7.0", "@ethersproject/rlp@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" - integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/sha2@5.7.0", "@ethersproject/sha2@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.7.0.tgz#9a5f7a7824ef784f7f7680984e593a800480c9fb" - integrity sha512-gKlH42riwb3KYp0reLsFTokByAKoJdgFCwI+CCiX/k+Jm2mbNs6oOaCjYQSlI1+XBVejwH2KrmCbMAT/GnRDQw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - hash.js "1.1.7" - -"@ethersproject/signing-key@5.7.0", "@ethersproject/signing-key@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3" - integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - bn.js "^5.2.1" - elliptic "6.5.4" - hash.js "1.1.7" - -"@ethersproject/solidity@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.7.0.tgz#5e9c911d8a2acce2a5ebb48a5e2e0af20b631cb8" - integrity sha512-HmabMd2Dt/raavyaGukF4XxizWKhKQ24DoLtdNbBmNKUOPqwjsKQSdV9GQtj9CBEea9DlzETlVER1gYeXXBGaA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/sha2" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/strings@5.7.0", "@ethersproject/strings@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" - integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/transactions@5.7.0", "@ethersproject/transactions@^5.6.2", "@ethersproject/transactions@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" - integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== - dependencies: - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - -"@ethersproject/units@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.7.0.tgz#637b563d7e14f42deeee39245275d477aae1d8b1" - integrity sha512-pD3xLMy3SJu9kG5xDGI7+xhTEmGXlEqXU4OfNapmfnxLVY4EMSSRp7j1k7eezutBPH7RBN/7QPnwR7hzNlEFeg== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/constants" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - -"@ethersproject/wallet@5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.7.0.tgz#4e5d0790d96fe21d61d38fb40324e6c7ef350b2d" - integrity sha512-MhmXlJXEJFBFVKrDLB4ZdDzxcBxQ3rLyCkhNqVu3CDYvR97E+8r01UgrI+TI99Le+aYm/in/0vp86guJuM7FCA== - dependencies: - "@ethersproject/abstract-provider" "^5.7.0" - "@ethersproject/abstract-signer" "^5.7.0" - "@ethersproject/address" "^5.7.0" - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/hdnode" "^5.7.0" - "@ethersproject/json-wallets" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/random" "^5.7.0" - "@ethersproject/signing-key" "^5.7.0" - "@ethersproject/transactions" "^5.7.0" - "@ethersproject/wordlists" "^5.7.0" - -"@ethersproject/web@5.7.1", "@ethersproject/web@^5.7.0": - version "5.7.1" - resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" - integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== - dependencies: - "@ethersproject/base64" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@ethersproject/wordlists@5.7.0", "@ethersproject/wordlists@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.7.0.tgz#8fb2c07185d68c3e09eb3bfd6e779ba2774627f5" - integrity sha512-S2TFNJNfHWVHNE6cNDjbVlZ6MgE17MIxMbMg2zv3wn+3XSJGosL1m9ZVv3GXCf/2ymSsQ+hRI5IzoMJTG6aoVA== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/hash" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/properties" "^5.7.0" - "@ethersproject/strings" "^5.7.0" - -"@fvictorio/tabtab@^0.0.3": - version "0.0.3" - resolved "https://registry.yarnpkg.com/@fvictorio/tabtab/-/tabtab-0.0.3.tgz#1b97981424386490fa2a5818706d2afd1f6e4659" - integrity sha512-bT/BSy8MJThrTebqTCjXRnGSgZWthHLigZ4k2AvfNtC79vPyBS1myaxw8gRU6RxIcdDD3HBtm7pOsOoyC086Zg== - dependencies: - debug "^4.1.1" - enquirer "^2.3.4" - minimist "^1.2.0" - mkdirp "^1.0.3" - untildify "^4.0.0" - -"@humanwhocodes/config-array@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" - integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== - dependencies: - "@humanwhocodes/object-schema" "^1.2.0" - debug "^4.1.1" - minimatch "^3.0.4" - -"@humanwhocodes/object-schema@^1.2.0": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== - dependencies: - camelcase "^5.3.1" - find-up "^4.1.0" - get-package-type "^0.1.0" - js-yaml "^3.13.1" - resolve-from "^5.0.0" - -"@istanbuljs/schema@^0.1.2": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" - integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== - -"@jest/types@^24.9.0": - version "24.9.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.9.0.tgz#63cb26cb7500d069e5a389441a7c6ab5e909fc59" - integrity sha512-XKK7ze1apu5JWQ5eZjHITP66AX+QsLlbaJRBGYr8pNzwcAE2JVkwnf0yqjHTsDRcjR0mujy/NmZMXw5kl+kGBw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^13.0.0" - -"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" - integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/resolve-uri@3.1.0", "@jridgewell/resolve-uri@^3.0.3": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - -"@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - -"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.18" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" - integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== - dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" - -"@manypkg/find-root@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@manypkg/find-root/-/find-root-1.1.0.tgz#a62d8ed1cd7e7d4c11d9d52a8397460b5d4ad29f" - integrity sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA== - dependencies: - "@babel/runtime" "^7.5.5" - "@types/node" "^12.7.1" - find-up "^4.1.0" - fs-extra "^8.1.0" - -"@manypkg/get-packages@^1.1.3": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@manypkg/get-packages/-/get-packages-1.1.3.tgz#e184db9bba792fa4693de4658cfb1463ac2c9c47" - integrity sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A== - dependencies: - "@babel/runtime" "^7.5.5" - "@changesets/types" "^4.0.1" - "@manypkg/find-root" "^1.1.0" - fs-extra "^8.1.0" - globby "^11.0.0" - read-yaml-file "^1.1.0" - -"@metamask/eth-sig-util@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088" - integrity sha512-tghyZKLHZjcdlDqCA3gNZmLeR0XvOE9U1qoQO9ohyAZT6Pya+H9vkBPcsyXytmYLNgVoin7CKCmweo/R43V+tQ== - dependencies: - ethereumjs-abi "^0.6.8" - ethereumjs-util "^6.2.1" - ethjs-util "^0.1.6" - tweetnacl "^1.0.3" - tweetnacl-util "^0.15.1" - -"@morgan-stanley/ts-mocking-bird@^0.6.2": - version "0.6.4" - resolved "https://registry.yarnpkg.com/@morgan-stanley/ts-mocking-bird/-/ts-mocking-bird-0.6.4.tgz#2e4b60d42957bab3b50b67dbf14c3da2f62a39f7" - integrity sha512-57VJIflP8eR2xXa9cD1LUawh+Gh+BVQfVu0n6GALyg/AqV/Nz25kDRvws3i9kIe1PTrbsZZOYpsYp6bXPd6nVA== - dependencies: - lodash "^4.17.16" - uuid "^7.0.3" - -"@noble/hashes@1.2.0", "@noble/hashes@~1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" - integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== - -"@noble/secp256k1@1.7.1", "@noble/secp256k1@~1.7.0": - version "1.7.1" - resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" - integrity sha512-hOUk6AyBFmqVrv7k5WAw/LpszxVbj9gGN4JRkIX52fdFAj1UA61KXmZDvqVEm+pOyec3+fIeZB02LYa/pWOArw== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@nomicfoundation/ethereumjs-block@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-block/-/ethereumjs-block-5.0.1.tgz#6f89664f55febbd723195b6d0974773d29ee133d" - integrity sha512-u1Yioemi6Ckj3xspygu/SfFvm8vZEO8/Yx5a1QLzi6nVU0jz3Pg2OmHKJ5w+D9Ogk1vhwRiqEBAqcb0GVhCyHw== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-trie" "6.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - ethereum-cryptography "0.1.3" - ethers "^5.7.1" - -"@nomicfoundation/ethereumjs-blockchain@7.0.1": - version "7.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-blockchain/-/ethereumjs-blockchain-7.0.1.tgz#80e0bd3535bfeb9baa29836b6f25123dab06a726" - integrity sha512-NhzndlGg829XXbqJEYrF1VeZhAwSPgsK/OB7TVrdzft3y918hW5KNd7gIZ85sn6peDZOdjBsAXIpXZ38oBYE5A== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.1" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-ethash" "3.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-trie" "6.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - abstract-level "^1.0.3" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - level "^8.0.0" - lru-cache "^5.1.1" - memory-level "^1.0.0" - -"@nomicfoundation/ethereumjs-common@4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-common/-/ethereumjs-common-4.0.1.tgz#4702d82df35b07b5407583b54a45bf728e46a2f0" - integrity sha512-OBErlkfp54GpeiE06brBW/TTbtbuBJV5YI5Nz/aB2evTDo+KawyEzPjBlSr84z/8MFfj8wS2wxzQX1o32cev5g== - dependencies: - "@nomicfoundation/ethereumjs-util" "9.0.1" - crc-32 "^1.2.0" - -"@nomicfoundation/ethereumjs-ethash@3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-ethash/-/ethereumjs-ethash-3.0.1.tgz#65ca494d53e71e8415c9a49ef48bc921c538fc41" - integrity sha512-KDjGIB5igzWOp8Ik5I6QiRH5DH+XgILlplsHR7TEuWANZA759G6krQ6o8bvj+tRUz08YygMQu/sGd9mJ1DYT8w== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - abstract-level "^1.0.3" - bigint-crypto-utils "^3.0.23" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-evm@2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-evm/-/ethereumjs-evm-2.0.1.tgz#f35681e203363f69ce2b3d3bf9f44d4e883ca1f1" - integrity sha512-oL8vJcnk0Bx/onl+TgQOQ1t/534GKFaEG17fZmwtPFeH8S5soiBYPCLUrvANOl4sCp9elYxIMzIiTtMtNNN8EQ== - dependencies: - "@ethersproject/providers" "^5.7.1" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" - -"@nomicfoundation/ethereumjs-rlp@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-rlp/-/ethereumjs-rlp-5.0.1.tgz#0b30c1cf77d125d390408e391c4bb5291ef43c28" - integrity sha512-xtxrMGa8kP4zF5ApBQBtjlSbN5E2HI8m8FYgVSYAnO6ssUoY5pVPGy2H8+xdf/bmMa22Ce8nWMH3aEW8CcqMeQ== - -"@nomicfoundation/ethereumjs-statemanager@2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-statemanager/-/ethereumjs-statemanager-2.0.1.tgz#8824a97938db4471911e2d2f140f79195def5935" - integrity sha512-B5ApMOnlruVOR7gisBaYwFX+L/AP7i/2oAahatssjPIBVDF6wTX1K7Qpa39E/nzsH8iYuL3krkYeUFIdO3EMUQ== - dependencies: - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - ethers "^5.7.1" - js-sdsl "^4.1.4" - -"@nomicfoundation/ethereumjs-trie@6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-trie/-/ethereumjs-trie-6.0.1.tgz#662c55f6b50659fd4b22ea9f806a7401cafb7717" - integrity sha512-A64It/IMpDVODzCgxDgAAla8jNjNtsoQZIzZUfIV5AY6Coi4nvn7+VReBn5itlxMiL2yaTlQr9TRWp3CSI6VoA== - dependencies: - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - "@types/readable-stream" "^2.3.13" - ethereum-cryptography "0.1.3" - readable-stream "^3.6.0" - -"@nomicfoundation/ethereumjs-tx@5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-tx/-/ethereumjs-tx-5.0.1.tgz#7629dc2036b4a33c34e9f0a592b43227ef4f0c7d" - integrity sha512-0HwxUF2u2hrsIM1fsasjXvlbDOq1ZHFV2dd1yGq8CA+MEYhaxZr8OTScpVkkxqMwBcc5y83FyPl0J9MZn3kY0w== - dependencies: - "@chainsafe/ssz" "^0.9.2" - "@ethersproject/providers" "^5.7.2" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-util@9.0.1": - version "9.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-util/-/ethereumjs-util-9.0.1.tgz#530cda8bae33f8b5020a8f199ed1d0a2ce48ec89" - integrity sha512-TwbhOWQ8QoSCFhV/DDfSmyfFIHjPjFBj957219+V3jTZYZ2rf9PmDtNOeZWAE3p3vlp8xb02XGpd0v6nTUPbsA== - dependencies: - "@chainsafe/ssz" "^0.10.0" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - ethereum-cryptography "0.1.3" - -"@nomicfoundation/ethereumjs-vm@7.0.1": - version "7.0.1" - resolved "https://registry.yarnpkg.com/@nomicfoundation/ethereumjs-vm/-/ethereumjs-vm-7.0.1.tgz#7d035e0993bcad10716c8b36e61dfb87fa3ca05f" - integrity sha512-rArhyn0jPsS/D+ApFsz3yVJMQ29+pVzNZ0VJgkzAZ+7FqXSRtThl1C1prhmlVr3YNUlfpZ69Ak+RUT4g7VoOuQ== - dependencies: - "@nomicfoundation/ethereumjs-block" "5.0.1" - "@nomicfoundation/ethereumjs-blockchain" "7.0.1" - "@nomicfoundation/ethereumjs-common" "4.0.1" - "@nomicfoundation/ethereumjs-evm" "2.0.1" - "@nomicfoundation/ethereumjs-rlp" "5.0.1" - "@nomicfoundation/ethereumjs-statemanager" "2.0.1" - "@nomicfoundation/ethereumjs-trie" "6.0.1" - "@nomicfoundation/ethereumjs-tx" "5.0.1" - "@nomicfoundation/ethereumjs-util" "9.0.1" - debug "^4.3.3" - ethereum-cryptography "0.1.3" - mcl-wasm "^0.7.1" - rustbn.js "~0.2.0" - -"@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-arm64/-/solidity-analyzer-darwin-arm64-0.1.0.tgz#83a7367342bd053a76d04bbcf4f373fef07cf760" - integrity sha512-vEF3yKuuzfMHsZecHQcnkUrqm8mnTWfJeEVFHpg+cO+le96xQA4lAJYdUan8pXZohQxv1fSReQsn4QGNuBNuCw== - -"@nomicfoundation/solidity-analyzer-darwin-x64@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-darwin-x64/-/solidity-analyzer-darwin-x64-0.1.0.tgz#1225f7da647ae1ad25a87125664704ecc0af6ccc" - integrity sha512-dlHeIg0pTL4dB1l9JDwbi/JG6dHQaU1xpDK+ugYO8eJ1kxx9Dh2isEUtA4d02cQAl22cjOHTvifAk96A+ItEHA== - -"@nomicfoundation/solidity-analyzer-freebsd-x64@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-freebsd-x64/-/solidity-analyzer-freebsd-x64-0.1.0.tgz#dbc052dcdfd50ae50fd5ae1788b69b4e0fa40040" - integrity sha512-WFCZYMv86WowDA4GiJKnebMQRt3kCcFqHeIomW6NMyqiKqhK1kIZCxSLDYsxqlx396kKLPN1713Q1S8tu68GKg== - -"@nomicfoundation/solidity-analyzer-linux-arm64-gnu@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-gnu/-/solidity-analyzer-linux-arm64-gnu-0.1.0.tgz#e6b2eea633995b557e74e881d2a43eab4760903d" - integrity sha512-DTw6MNQWWlCgc71Pq7CEhEqkb7fZnS7oly13pujs4cMH1sR0JzNk90Mp1zpSCsCs4oKan2ClhMlLKtNat/XRKQ== - -"@nomicfoundation/solidity-analyzer-linux-arm64-musl@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-arm64-musl/-/solidity-analyzer-linux-arm64-musl-0.1.0.tgz#af81107f5afa794f19988a368647727806e18dc4" - integrity sha512-wUpUnR/3GV5Da88MhrxXh/lhb9kxh9V3Jya2NpBEhKDIRCDmtXMSqPMXHZmOR9DfCwCvG6vLFPr/+YrPCnUN0w== - -"@nomicfoundation/solidity-analyzer-linux-x64-gnu@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-gnu/-/solidity-analyzer-linux-x64-gnu-0.1.0.tgz#6877e1da1a06a9f08446070ab6e0a5347109f868" - integrity sha512-lR0AxK1x/MeKQ/3Pt923kPvwigmGX3OxeU5qNtQ9pj9iucgk4PzhbS3ruUeSpYhUxG50jN4RkIGwUMoev5lguw== - -"@nomicfoundation/solidity-analyzer-linux-x64-musl@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-linux-x64-musl/-/solidity-analyzer-linux-x64-musl-0.1.0.tgz#bb6cd83a0c259eccef4183796b6329a66cf7ebd9" - integrity sha512-A1he/8gy/JeBD3FKvmI6WUJrGrI5uWJNr5Xb9WdV+DK0F8msuOqpEByLlnTdLkXMwW7nSl3awvLezOs9xBHJEg== - -"@nomicfoundation/solidity-analyzer-win32-arm64-msvc@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-arm64-msvc/-/solidity-analyzer-win32-arm64-msvc-0.1.0.tgz#9d4bca1cc9a1333fde985675083b0b7d165f6076" - integrity sha512-7x5SXZ9R9H4SluJZZP8XPN+ju7Mx+XeUMWZw7ZAqkdhP5mK19I4vz3x0zIWygmfE8RT7uQ5xMap0/9NPsO+ykw== - -"@nomicfoundation/solidity-analyzer-win32-ia32-msvc@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-ia32-msvc/-/solidity-analyzer-win32-ia32-msvc-0.1.0.tgz#0db5bfc6aa952bea4098d8d2c8947b4e5c4337ee" - integrity sha512-m7w3xf+hnE774YRXu+2mGV7RiF3QJtUoiYU61FascCkQhX3QMQavh7saH/vzb2jN5D24nT/jwvaHYX/MAM9zUw== - -"@nomicfoundation/solidity-analyzer-win32-x64-msvc@0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer-win32-x64-msvc/-/solidity-analyzer-win32-x64-msvc-0.1.0.tgz#2e0f39a2924dcd77db6b419828595e984fabcb33" - integrity sha512-xCuybjY0sLJQnJhupiFAXaek2EqF0AP0eBjgzaalPXSNvCEN6ZYHvUzdA50ENDVeSYFXcUsYf3+FsD3XKaeptA== - -"@nomicfoundation/solidity-analyzer@^0.1.0": - version "0.1.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/solidity-analyzer/-/solidity-analyzer-0.1.0.tgz#e5ddc43ad5c0aab96e5054520d8e16212e125f50" - integrity sha512-xGWAiVCGOycvGiP/qrlf9f9eOn7fpNbyJygcB0P21a1MDuVPlKt0Srp7rvtBEutYQ48ouYnRXm33zlRnlTOPHg== - optionalDependencies: - "@nomicfoundation/solidity-analyzer-darwin-arm64" "0.1.0" - "@nomicfoundation/solidity-analyzer-darwin-x64" "0.1.0" - "@nomicfoundation/solidity-analyzer-freebsd-x64" "0.1.0" - "@nomicfoundation/solidity-analyzer-linux-arm64-gnu" "0.1.0" - "@nomicfoundation/solidity-analyzer-linux-arm64-musl" "0.1.0" - "@nomicfoundation/solidity-analyzer-linux-x64-gnu" "0.1.0" - "@nomicfoundation/solidity-analyzer-linux-x64-musl" "0.1.0" - "@nomicfoundation/solidity-analyzer-win32-arm64-msvc" "0.1.0" - "@nomicfoundation/solidity-analyzer-win32-ia32-msvc" "0.1.0" - "@nomicfoundation/solidity-analyzer-win32-x64-msvc" "0.1.0" - -"@nomiclabs/hardhat-etherscan@^3.0.0": - version "3.1.7" - resolved "https://registry.yarnpkg.com/@nomiclabs/hardhat-etherscan/-/hardhat-etherscan-3.1.7.tgz#72e3d5bd5d0ceb695e097a7f6f5ff6fcbf062b9a" - integrity sha512-tZ3TvSgpvsQ6B6OGmo1/Au6u8BrAkvs1mIC/eURA3xgIfznUZBhmpne8hv7BXUzw9xNL3fXdpOYgOQlVMTcoHQ== - dependencies: - "@ethersproject/abi" "^5.1.2" - "@ethersproject/address" "^5.0.2" - cbor "^8.1.0" - chalk "^2.4.2" - debug "^4.1.1" - fs-extra "^7.0.1" - lodash "^4.17.11" - semver "^6.3.0" - table "^6.8.0" - undici "^5.14.0" - -"@nomiclabs/truffle-contract@^4.2.23": - version "4.5.10" - resolved "https://registry.yarnpkg.com/@nomiclabs/truffle-contract/-/truffle-contract-4.5.10.tgz#52adcca1068647e1c2b44bf0e6a89fc4ad7f9213" - integrity sha512-nF/6InFV+0hUvutyFgsdOMCoYlr//2fJbRER4itxYtQtc4/O1biTwZIKRu+5l2J5Sq6LU2WX7vZHtDgQdhWxIQ== - dependencies: - "@ensdomains/ensjs" "^2.0.1" - "@truffle/blockchain-utils" "^0.1.3" - "@truffle/contract-schema" "^3.4.7" - "@truffle/debug-utils" "^6.0.22" - "@truffle/error" "^0.1.0" - "@truffle/interface-adapter" "^0.5.16" - bignumber.js "^7.2.1" - ethereum-ens "^0.8.0" - ethers "^4.0.0-beta.1" - source-map-support "^0.5.19" - -"@scure/base@~1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" - integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== - -"@scure/bip32@1.1.5": - version "1.1.5" - resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.1.5.tgz#d2ccae16dcc2e75bc1d75f5ef3c66a338d1ba300" - integrity sha512-XyNh1rB0SkEqd3tXcXMi+Xe1fvg+kUIcoRIEujP1Jgv7DqW2r9lg3Ah0NkFaCs9sTkQAQA8kw7xiRXzENi9Rtw== - dependencies: - "@noble/hashes" "~1.2.0" - "@noble/secp256k1" "~1.7.0" - "@scure/base" "~1.1.0" - -"@scure/bip39@1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.1.1.tgz#b54557b2e86214319405db819c4b6a370cf340c5" - integrity sha512-t+wDck2rVkh65Hmv280fYdVdY25J9YeEUIgn2LG1WM6gxFkGzcksoDiUkWVpVp3Oex9xGC68JU2dSbUfwZ2jPg== - dependencies: - "@noble/hashes" "~1.2.0" - "@scure/base" "~1.1.0" - -"@sentry/core@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-5.30.0.tgz#6b203664f69e75106ee8b5a2fe1d717379b331f3" - integrity sha512-TmfrII8w1PQZSZgPpUESqjB+jC6MvZJZdLtE/0hZ+SrnKhW3x5WlYLvTXZpcWePYBku7rl2wn1RZu6uT0qCTeg== - dependencies: - "@sentry/hub" "5.30.0" - "@sentry/minimal" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/hub@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/hub/-/hub-5.30.0.tgz#2453be9b9cb903404366e198bd30c7ca74cdc100" - integrity sha512-2tYrGnzb1gKz2EkMDQcfLrDTvmGcQPuWxLnJKXJvYTQDGLlEvi2tWz1VIHjunmOvJrB5aIQLhm+dcMRwFZDCqQ== - dependencies: - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/minimal@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/minimal/-/minimal-5.30.0.tgz#ce3d3a6a273428e0084adcb800bc12e72d34637b" - integrity sha512-BwWb/owZKtkDX+Sc4zCSTNcvZUq7YcH3uAVlmh/gtR9rmUvbzAA3ewLuB3myi4wWRAMEtny6+J/FN/x+2wn9Xw== - dependencies: - "@sentry/hub" "5.30.0" - "@sentry/types" "5.30.0" - tslib "^1.9.3" - -"@sentry/node@^5.18.1": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/node/-/node-5.30.0.tgz#4ca479e799b1021285d7fe12ac0858951c11cd48" - integrity sha512-Br5oyVBF0fZo6ZS9bxbJZG4ApAjRqAnqFFurMVJJdunNb80brh7a5Qva2kjhm+U6r9NJAB5OmDyPkA1Qnt+QVg== - dependencies: - "@sentry/core" "5.30.0" - "@sentry/hub" "5.30.0" - "@sentry/tracing" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - cookie "^0.4.1" - https-proxy-agent "^5.0.0" - lru_map "^0.3.3" - tslib "^1.9.3" - -"@sentry/tracing@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/tracing/-/tracing-5.30.0.tgz#501d21f00c3f3be7f7635d8710da70d9419d4e1f" - integrity sha512-dUFowCr0AIMwiLD7Fs314Mdzcug+gBVo/+NCMyDw8tFxJkwWAKl7Qa2OZxLQ0ZHjakcj1hNKfCQJ9rhyfOl4Aw== - dependencies: - "@sentry/hub" "5.30.0" - "@sentry/minimal" "5.30.0" - "@sentry/types" "5.30.0" - "@sentry/utils" "5.30.0" - tslib "^1.9.3" - -"@sentry/types@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-5.30.0.tgz#19709bbe12a1a0115bc790b8942917da5636f402" - integrity sha512-R8xOqlSTZ+htqrfteCWU5Nk0CDN5ApUTvrlvBuiH1DyP6czDZ4ktbZB0hAgBlVcK0U+qpD3ag3Tqqpa5Q67rPw== - -"@sentry/utils@5.30.0": - version "5.30.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-5.30.0.tgz#9a5bd7ccff85ccfe7856d493bffa64cabc41e980" - integrity sha512-zaYmoH0NWWtvnJjC9/CBseXMtKHm/tm40sz3YfJRxeQjyzRqNQPgivpd9R/oDJCYj999mzdW382p/qi2ypjLww== - dependencies: - "@sentry/types" "5.30.0" - tslib "^1.9.3" - -"@sindresorhus/is@^4.0.0", "@sindresorhus/is@^4.6.0": - version "4.6.0" - resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.6.0.tgz#3c7c9c46e678feefe7a2e5bb609d3dbd665ffb3f" - integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== - -"@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.8.1": - version "1.8.6" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" - integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== - dependencies: - type-detect "4.0.8" - -"@sinonjs/fake-timers@^6.0.0", "@sinonjs/fake-timers@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40" - integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA== - dependencies: - "@sinonjs/commons" "^1.7.0" - -"@sinonjs/samsam@^5.3.1": - version "5.3.1" - resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-5.3.1.tgz#375a45fe6ed4e92fca2fb920e007c48232a6507f" - integrity sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg== - dependencies: - "@sinonjs/commons" "^1.6.0" - lodash.get "^4.4.2" - type-detect "^4.0.8" - -"@sinonjs/text-encoding@^0.7.1": - version "0.7.2" - resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz#5981a8db18b56ba38ef0efb7d995b12aa7b51918" - integrity sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ== - -"@solidity-parser/parser@^0.14.0", "@solidity-parser/parser@^0.14.1": - version "0.14.5" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.14.5.tgz#87bc3cc7b068e08195c219c91cd8ddff5ef1a804" - integrity sha512-6dKnHZn7fg/iQATVEzqyUOyEidbn05q7YA2mQ9hC0MMXhhV3/JrsxmFSYZAcr7j1yUP700LLhTruvJ3MiQmjJg== - dependencies: - antlr4ts "^0.5.0-alpha.4" - -"@solidity-parser/parser@^0.15.0": - version "0.15.0" - resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.15.0.tgz#1d359be40be84f174dd616ccfadcf43346c6bf63" - integrity sha512-5UFJJTzWi1hgFk6aGCZ5rxG2DJkCJOzJ74qg7UkWSNCDSigW+CJLoYUb5bLiKrtI34Nr9rpFSUNHfkqtlL+N/w== - dependencies: - antlr4ts "^0.5.0-alpha.4" - -"@szmarczak/http-timer@^4.0.5": - version "4.0.6" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" - integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== - dependencies: - defer-to-connect "^2.0.0" - -"@szmarczak/http-timer@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-5.0.1.tgz#c7c1bf1141cdd4751b0399c8fc7b8b664cd5be3a" - integrity sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw== - dependencies: - defer-to-connect "^2.0.1" - -"@truffle/abi-utils@^0.3.7": - version "0.3.7" - resolved "https://registry.yarnpkg.com/@truffle/abi-utils/-/abi-utils-0.3.7.tgz#db2fa6080af712709021ffc19eb3d75baa8c146d" - integrity sha512-IhX+Hxu9fTEOxR+34r3Tt/AJS1gkqdEBZDzERG/9X43bLGzu5pLWzDgDBpNDqYM3lTICIg3UHfqLdUzSC7g4pg== - dependencies: - change-case "3.0.2" - fast-check "3.1.1" - web3-utils "1.8.2" - -"@truffle/blockchain-utils@^0.1.3": - version "0.1.6" - resolved "https://registry.yarnpkg.com/@truffle/blockchain-utils/-/blockchain-utils-0.1.6.tgz#7ea0a16b8135e5aeb688bf3bd014fa8f6ba45adb" - integrity sha512-SldoNRIFSm3+HMBnSc2jFsu5TWDkCN4X6vL3wrd0t6DIeF7nD6EoPPjxwbFSoqCnkkRxMuZeL6sUx7UMJS/wSA== - -"@truffle/codec@^0.14.14": - version "0.14.14" - resolved "https://registry.yarnpkg.com/@truffle/codec/-/codec-0.14.14.tgz#c91cdb8672f11b85272aaac6e07538fe0a96f8f8" - integrity sha512-EP+iTGowElaJJgQI4Ztizmb+hYOHwOv4OiX09sjqX/v/GdmnvyWoS8RGHtERze8DoBi5cs4ZY8vlM3nVDbRv5A== - dependencies: - "@truffle/abi-utils" "^0.3.7" - "@truffle/compile-common" "^0.9.2" - big.js "^6.0.3" - bn.js "^5.1.3" - cbor "^5.2.0" - debug "^4.3.1" - lodash "^4.17.21" - semver "7.3.7" - utf8 "^3.0.0" - web3-utils "1.8.2" - -"@truffle/compile-common@^0.9.2": - version "0.9.2" - resolved "https://registry.yarnpkg.com/@truffle/compile-common/-/compile-common-0.9.2.tgz#da8aed5c9c8da119cb4b7ee5a425d2559a99bfb7" - integrity sha512-n7MF/4/dntccj44RGe3PRMD8Vk46PU8dJtzd1VLAfgokK2Y2N+SjAzDskBnmAydZVWAM315nZIUQsgnY8xoATw== - dependencies: - "@truffle/error" "^0.2.0" - colors "1.4.0" - -"@truffle/contract-schema@^3.4.7": - version "3.4.11" - resolved "https://registry.yarnpkg.com/@truffle/contract-schema/-/contract-schema-3.4.11.tgz#ac5fc8be656b786c2bd5d3a2ca6faeb2949e7ff3" - integrity sha512-wReyVZUPyU9Zy5PSCugBLG1nnruBmRAJ/gmoirQiJ9N2n+s1iGBTY49tkDqFMz3XUUE0kplfdb9YKZJlLkTWzQ== - dependencies: - ajv "^6.10.0" - debug "^4.3.1" - -"@truffle/debug-utils@^6.0.22": - version "6.0.45" - resolved "https://registry.yarnpkg.com/@truffle/debug-utils/-/debug-utils-6.0.45.tgz#a4df479872f82d3d314248be43114431469b8792" - integrity sha512-yrEM8znplrVzxczzsvRlFrA56S3KSLD0XZpAQ8nDRd82Omn4Y7AaJtkAoOILjkPHeuBS1bvHm7FjKhszgOe3mg== - dependencies: - "@truffle/codec" "^0.14.14" - "@trufflesuite/chromafi" "^3.0.0" - bn.js "^5.1.3" - chalk "^2.4.2" - debug "^4.3.1" - highlightjs-solidity "^2.0.6" - -"@truffle/error@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.1.1.tgz#e52026ac8ca7180d83443dca73c03e07ace2a301" - integrity sha512-sE7c9IHIGdbK4YayH4BC8i8qMjoAOeg6nUXUDZZp8wlU21/EMpaG+CLx+KqcIPyR+GSWIW3Dm0PXkr2nlggFDA== - -"@truffle/error@^0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@truffle/error/-/error-0.2.0.tgz#65de6f03f5c041f883cc87677eecf8231428f1ab" - integrity sha512-Fe0/z4WWb7IP2gBnv3l6zqP87Y0kSMs7oiSLakKJq17q3GUunrHSdioKuNspdggxkXIBhEQLhi8C+LJdwmHKWQ== - -"@truffle/interface-adapter@^0.5.16": - version "0.5.28" - resolved "https://registry.yarnpkg.com/@truffle/interface-adapter/-/interface-adapter-0.5.28.tgz#814f8090dc845015d3b43c702aa90fbae3ef72e8" - integrity sha512-xnjWXiOihApI+XLrs0xpw9s+av6Qvrc2lkXAfrBluuKgaJOQIdLVz6vi2Bt6oiTQAoWUkUGa0hne78mxFI2J1w== - dependencies: - bn.js "^5.1.3" - ethers "^4.0.32" - web3 "1.8.2" - -"@trufflesuite/chromafi@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@trufflesuite/chromafi/-/chromafi-3.0.0.tgz#f6956408c1af6a38a6ed1657783ce59504a1eb8b" - integrity sha512-oqWcOqn8nT1bwlPPfidfzS55vqcIDdpfzo3HbU9EnUmcSTX+I8z0UyUFI3tZQjByVJulbzxHxUGS3ZJPwK/GPQ== - dependencies: - camelcase "^4.1.0" - chalk "^2.3.2" - cheerio "^1.0.0-rc.2" - detect-indent "^5.0.0" - highlight.js "^10.4.1" - lodash.merge "^4.6.2" - strip-ansi "^4.0.0" - strip-indent "^2.0.0" - -"@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== - -"@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - -"@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== - -"@tsconfig/node16@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" - integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== - -"@typechain/ethers-v5@^10.1.0": - version "10.2.0" - resolved "https://registry.yarnpkg.com/@typechain/ethers-v5/-/ethers-v5-10.2.0.tgz#68f5963efb5214cb2d881477228e4b5b315473e1" - integrity sha512-ikaq0N/w9fABM+G01OFmU3U3dNnyRwEahkdvi9mqy1a3XwKiPZaF/lu54OcNaEWnpvEYyhhS0N7buCtLQqC92w== - dependencies: - lodash "^4.17.15" - ts-essentials "^7.0.1" - -"@typechain/hardhat@^6.1.2": - version "6.1.5" - resolved "https://registry.yarnpkg.com/@typechain/hardhat/-/hardhat-6.1.5.tgz#caad58a1d3e9cd88061a584eb4f4fa763d5dcad1" - integrity sha512-lg7LW4qDZpxFMknp3Xool61Fg6Lays8F8TXdFGBG+MxyYcYU5795P1U2XdStuzGq9S2Dzdgh+1jGww9wvZ6r4Q== - dependencies: - fs-extra "^9.1.0" - -"@types/async-eventemitter@^0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@types/async-eventemitter/-/async-eventemitter-0.2.1.tgz#f8e6280e87e8c60b2b938624b0a3530fb3e24712" - integrity sha512-M2P4Ng26QbAeITiH7w1d7OxtldgfAe0wobpyJzVK/XOb0cUGKU2R4pfAhqcJBXAe2ife5ZOhSv4wk7p+ffURtg== - -"@types/bignumber.js@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@types/bignumber.js/-/bignumber.js-5.0.0.tgz#d9f1a378509f3010a3255e9cc822ad0eeb4ab969" - integrity sha512-0DH7aPGCClywOFaxxjE6UwpN2kQYe9LwuDQMv+zYA97j5GkOMo8e66LYT+a8JYU7jfmUFRZLa9KycxHDsKXJCA== - dependencies: - bignumber.js "*" - -"@types/bn.js@^4.11.3": - version "4.11.6" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" - integrity sha512-pqr857jrp2kPuO9uRjZ3PwnJTjoQy+fcdxvBTvHm6dkmEL9q+hDD/2j/0ELOBPtPnS8LjCX0gI9nbl8lVkadpg== - dependencies: - "@types/node" "*" - -"@types/bn.js@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.1.tgz#b51e1b55920a4ca26e9285ff79936bbdec910682" - integrity sha512-qNrYbZqMx0uJAfKnKclPh+dTwK33KfLHYqtyODwd5HnXOjnkhc4qgn3BrK6RWyGZm5+sIFE7Q7Vz6QQtJB7w7g== - dependencies: - "@types/node" "*" - -"@types/cacheable-request@^6.0.1", "@types/cacheable-request@^6.0.2": - version "6.0.3" - resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.3.tgz#a430b3260466ca7b5ca5bfd735693b36e7a9d183" - integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== - dependencies: - "@types/http-cache-semantics" "*" - "@types/keyv" "^3.1.4" - "@types/node" "*" - "@types/responselike" "^1.0.0" - -"@types/chai-as-promised@^7.1.3": - version "7.1.5" - resolved "https://registry.yarnpkg.com/@types/chai-as-promised/-/chai-as-promised-7.1.5.tgz#6e016811f6c7a64f2eed823191c3a6955094e255" - integrity sha512-jStwss93SITGBwt/niYrkf2C+/1KTeZCZl1LaeezTlqppAKeoQC7jxyqYuP72sxBGKCIbw7oHgbYssIRzT5FCQ== - dependencies: - "@types/chai" "*" - -"@types/chai@*", "@types/chai@^4.2.0": - version "4.3.4" - resolved "https://registry.yarnpkg.com/@types/chai/-/chai-4.3.4.tgz#e913e8175db8307d78b4e8fa690408ba6b65dee4" - integrity sha512-KnRanxnpfpjUTqTCXslZSEdLfXExwgNxYPdiO2WGUj8+HDjFi8R3k5RVKPeSCzLjCcshCAtVO2QBbVuAV4kTnw== - -"@types/ci-info@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@types/ci-info/-/ci-info-2.0.0.tgz#51848cc0f5c30c064f4b25f7f688bf35825b3971" - integrity sha512-5R2/MHILQLDCzTuhs1j4Qqq8AaKUf7Ma4KSSkCtc12+fMs47zfa34qhto9goxpyX00tQK1zxB885VCiawZ5Qhg== - -"@types/concat-stream@^1.6.0": - version "1.6.1" - resolved "https://registry.yarnpkg.com/@types/concat-stream/-/concat-stream-1.6.1.tgz#24bcfc101ecf68e886aaedce60dfd74b632a1b74" - integrity sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA== - dependencies: - "@types/node" "*" - -"@types/debug@^4.1.4": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.7.tgz#7cc0ea761509124709b8b2d1090d8f6c17aadb82" - integrity sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg== - dependencies: - "@types/ms" "*" - -"@types/find-up@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@types/find-up/-/find-up-2.1.1.tgz#1cd2d240f1ad1f48d32346074724dc3107248a11" - integrity sha512-60LC501bQRN9/3yfVaEEMd7IndaufffL56PBRAejPpUrY304Ps1jfnjNqPw5jmM5R8JHWiKBAe5IHzNcPV41AA== - -"@types/form-data@0.0.33": - version "0.0.33" - resolved "https://registry.yarnpkg.com/@types/form-data/-/form-data-0.0.33.tgz#c9ac85b2a5fd18435b8c85d9ecb50e6d6c893ff8" - integrity sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw== - dependencies: - "@types/node" "*" - -"@types/fs-extra@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.1.0.tgz#2a325ef97901504a3828718c390d34b8426a10a1" - integrity sha512-AInn5+UBFIK9FK5xc9yP5e3TQSPNNgjHByqYcj9g5elVBnDQcQL7PlO1CIRy2gWlbwK7UPYqi7vRvFA44dCmYQ== - dependencies: - "@types/node" "*" - -"@types/glob@^7.1.1": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - -"@types/http-cache-semantics@*": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz#0ea7b61496902b95890dc4c3a116b60cb8dae812" - integrity sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ== - -"@types/is-ci@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/is-ci/-/is-ci-3.0.0.tgz#7e8910af6857601315592436f030aaa3ed9783c3" - integrity sha512-Q0Op0hdWbYd1iahB+IFNQcWXFq4O0Q5MwQP7uN0souuQ4rPg1vEYcnIOfr1gY+M+6rc8FGoRaBO1mOOvL29sEQ== - dependencies: - ci-info "^3.1.0" - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== - -"@types/istanbul-lib-report@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" - integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^1.1.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz#e875cc689e47bce549ec81f3df5e6f6f11cfaeb2" - integrity sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw== - dependencies: - "@types/istanbul-lib-coverage" "*" - "@types/istanbul-lib-report" "*" - -"@types/json-schema@^7.0.7", "@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== - -"@types/keccak@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/keccak/-/keccak-3.0.1.tgz#1dfad12395f32927cf409707534dd796d57aa84c" - integrity sha512-/MxAVmtyyeOvZ6dGf3ciLwFRuV5M8DRIyYNFGHYI6UyBW4/XqyO0LZw+JFMvaeY3cHItQAkELclBU1x5ank6mg== - dependencies: - "@types/node" "*" - -"@types/keyv@^3.1.4": - version "3.1.4" - resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" - integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== - dependencies: - "@types/node" "*" - -"@types/lodash.clonedeep@^4.5.7": - version "4.5.7" - resolved "https://registry.yarnpkg.com/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.7.tgz#0e119f582ed6f9e6b373c04a644651763214f197" - integrity sha512-ccNqkPptFIXrpVqUECi60/DFxjNKsfoQxSQsgcBJCX/fuX1wgyQieojkcWH/KpE3xzLoWN/2k+ZeGqIN3paSvw== - dependencies: - "@types/lodash" "*" - -"@types/lodash@*": - version "4.14.194" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.194.tgz#b71eb6f7a0ff11bff59fc987134a093029258a76" - integrity sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g== - -"@types/lodash@^4.14.123": - version "4.14.191" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.191.tgz#09511e7f7cba275acd8b419ddac8da9a6a79e2fa" - integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ== - -"@types/lru-cache@^5.1.0": - version "5.1.1" - resolved "https://registry.yarnpkg.com/@types/lru-cache/-/lru-cache-5.1.1.tgz#c48c2e27b65d2a153b19bfc1a317e30872e01eef" - integrity sha512-ssE3Vlrys7sdIzs5LOxCzTVMsU7i9oa/IaW92wF32JFb3CVczqOkru2xspuKczHEbG3nvmPY7IFqVmGGHdNbYw== - -"@types/minimatch@*": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" - integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== - -"@types/minimist@^1.2.0": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c" - integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== - -"@types/mocha@>=9.1.0": - version "10.0.1" - resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b" - integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== - -"@types/ms@*": - version "0.7.31" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" - integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== - -"@types/node@*": - version "18.13.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.13.0.tgz#0400d1e6ce87e9d3032c19eb6c58205b0d3f7850" - integrity sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg== - -"@types/node@^10.0.3": - version "10.17.60" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" - integrity sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw== - -"@types/node@^12.12.6", "@types/node@^12.7.1": - version "12.20.55" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.55.tgz#c329cbd434c42164f846b909bd6f85b5537f6240" - integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ== - -"@types/node@^14.0.0": - version "14.18.36" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.36.tgz#c414052cb9d43fab67d679d5f3c641be911f5835" - integrity sha512-FXKWbsJ6a1hIrRxv+FoukuHnGTgEzKYGi7kilfMae96AL9UNkPFNWJEEYWzdRI9ooIkbr4AKldyuSTLql06vLQ== - -"@types/node@^8.0.0": - version "8.10.66" - resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" - integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw== - -"@types/normalize-package-data@^2.4.0": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" - integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== - -"@types/pbkdf2@^3.0.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" - integrity sha512-Cf63Rv7jCQ0LaL8tNXmEyqTHuIJxRdlS5vMh1mj5voN4+QFhVZnlZruezqpWYDiJ8UTzhP0VmeLXCmBk66YrMQ== - dependencies: - "@types/node" "*" - -"@types/prettier@^2.1.1": - version "2.7.2" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.2.tgz#6c2324641cc4ba050a8c710b2b251b377581fbf0" - integrity sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg== - -"@types/qs@^6.2.31", "@types/qs@^6.5.3": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== - -"@types/readable-stream@^2.3.13": - version "2.3.15" - resolved "https://registry.yarnpkg.com/@types/readable-stream/-/readable-stream-2.3.15.tgz#3d79c9ceb1b6a57d5f6e6976f489b9b5384321ae" - integrity sha512-oM5JSKQCcICF1wvGgmecmHldZ48OZamtMxcGGVICOJA8o8cahXC1zEVAif8iwoc5j8etxFaRFnf095+CDsuoFQ== - dependencies: - "@types/node" "*" - safe-buffer "~5.1.1" - -"@types/resolve@^1.17.1": - version "1.20.2" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" - integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== - -"@types/responselike@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29" - integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== - dependencies: - "@types/node" "*" - -"@types/secp256k1@^4.0.1": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/secp256k1/-/secp256k1-4.0.3.tgz#1b8e55d8e00f08ee7220b4d59a6abe89c37a901c" - integrity sha512-Da66lEIFeIz9ltsdMZcpQvmrmmoqrfju8pm1BH8WbYjZSwUgCwXLb9C+9XYogwBITnbsSaMdVPb2ekf7TV+03w== - dependencies: - "@types/node" "*" - -"@types/semver@^6.0.0", "@types/semver@^6.0.2": - version "6.2.3" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-6.2.3.tgz#5798ecf1bec94eaa64db39ee52808ec0693315aa" - integrity sha512-KQf+QAMWKMrtBMsB8/24w53tEsxllMj6TuA80TT/5igJalLI/zm0L3oXRbIAl4Ohfc85gyHX/jhMwsVkmhLU4A== - -"@types/semver@^7.3.12": - version "7.3.13" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.13.tgz#da4bfd73f49bd541d28920ab0e2bf0ee80f71c91" - integrity sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw== - -"@types/sinon-chai@^3.2.9": - version "3.2.9" - resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.9.tgz#71feb938574bbadcb176c68e5ff1a6014c5e69d4" - integrity sha512-/19t63pFYU0ikrdbXKBWj9PCdnKyTd0Qkz0X91Ta081cYsq90OxYdcWwK/dwEoDa6dtXgj2HJfmzgq+QZTHdmQ== - dependencies: - "@types/chai" "*" - "@types/sinon" "*" - -"@types/sinon@*": - version "10.0.14" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-10.0.14.tgz#6bd18b088ea5ef1e5153fa37d0b68e91eff09e22" - integrity sha512-mn72up6cjaMyMuaPaa/AwKf6WtsSRysQC7wxFkCm1XcOKXPM1z+5Y4H5wjIVBz4gdAkjvZxVVfjA6ba1nHr5WQ== - dependencies: - "@types/sinonjs__fake-timers" "*" - -"@types/sinon@^9.0.8": - version "9.0.11" - resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-9.0.11.tgz#7af202dda5253a847b511c929d8b6dda170562eb" - integrity sha512-PwP4UY33SeeVKodNE37ZlOsR9cReypbMJOhZ7BVE0lB+Hix3efCOxiJWiE5Ia+yL9Cn2Ch72EjFTRze8RZsNtg== - dependencies: - "@types/sinonjs__fake-timers" "*" - -"@types/sinonjs__fake-timers@*": - version "8.1.2" - resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-8.1.2.tgz#bf2e02a3dbd4aecaf95942ecd99b7402e03fad5e" - integrity sha512-9GcLXF0/v3t80caGs5p2rRfkB+a8VBGLJZVih6CNFkx8IZ994wiKKLSRs9nuFwk1HevWs/1mnUmkApGrSGsShA== - -"@types/uuid@^8.3.1": - version "8.3.4" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" - integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== - -"@types/ws@^7.2.1": - version "7.4.7" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" - integrity sha512-JQbbmxZTZehdc2iszGKs5oC3NFnjeay7mtAWrdt7qNtAVK0g19muApzAy4bm9byz79xa2ZnO/BOBC2R8RC5Lww== - dependencies: - "@types/node" "*" - -"@types/yargs-parser@*": - version "21.0.0" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" - integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== - -"@types/yargs@^13.0.0": - version "13.0.12" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-13.0.12.tgz#d895a88c703b78af0465a9de88aa92c61430b092" - integrity sha512-qCxJE1qgz2y0hA4pIxjBR+PelCH0U5CK1XJXFwCNqfmliatKp47UCXXE9Dyk1OXBDLvsCF57TqQEJaeLfDYEOQ== - dependencies: - "@types/yargs-parser" "*" - -"@typescript-eslint/eslint-plugin@4.29.2": - version "4.29.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.2.tgz#f54dc0a32b8f61c6024ab8755da05363b733838d" - integrity sha512-x4EMgn4BTfVd9+Z+r+6rmWxoAzBaapt4QFqE+d8L8sUtYZYLDTK6VG/y/SMMWA5t1/BVU5Kf+20rX4PtWzUYZg== - dependencies: - "@typescript-eslint/experimental-utils" "4.29.2" - "@typescript-eslint/scope-manager" "4.29.2" - debug "^4.3.1" - functional-red-black-tree "^1.0.1" - regexpp "^3.1.0" - semver "^7.3.5" - tsutils "^3.21.0" - -"@typescript-eslint/eslint-plugin@5.53.0": - version "5.53.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.53.0.tgz#24b8b4a952f3c615fe070e3c461dd852b5056734" - integrity sha512-alFpFWNucPLdUOySmXCJpzr6HKC3bu7XooShWM+3w/EL6J2HIoB2PFxpLnq4JauWVk6DiVeNKzQlFEaE+X9sGw== - dependencies: - "@typescript-eslint/scope-manager" "5.53.0" - "@typescript-eslint/type-utils" "5.53.0" - "@typescript-eslint/utils" "5.53.0" - debug "^4.3.4" - grapheme-splitter "^1.0.4" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - regexpp "^3.2.0" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/experimental-utils@4.29.2": - version "4.29.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-4.29.2.tgz#5f67fb5c5757ef2cb3be64817468ba35c9d4e3b7" - integrity sha512-P6mn4pqObhftBBPAv4GQtEK7Yos1fz/MlpT7+YjH9fTxZcALbiiPKuSIfYP/j13CeOjfq8/fr9Thr2glM9ub7A== - dependencies: - "@types/json-schema" "^7.0.7" - "@typescript-eslint/scope-manager" "4.29.2" - "@typescript-eslint/types" "4.29.2" - "@typescript-eslint/typescript-estree" "4.29.2" - eslint-scope "^5.1.1" - eslint-utils "^3.0.0" - -"@typescript-eslint/parser@4.29.2": - version "4.29.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.29.2.tgz#1c7744f4c27aeb74610c955d3dce9250e95c370a" - integrity sha512-WQ6BPf+lNuwteUuyk1jD/aHKqMQ9jrdCn7Gxt9vvBnzbpj7aWEf+aZsJ1zvTjx5zFxGCt000lsbD9tQPEL8u6g== - dependencies: - "@typescript-eslint/scope-manager" "4.29.2" - "@typescript-eslint/types" "4.29.2" - "@typescript-eslint/typescript-estree" "4.29.2" - debug "^4.3.1" - -"@typescript-eslint/parser@5.53.0": - version "5.53.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.53.0.tgz#a1f2b9ae73b83181098747e96683f1b249ecab52" - integrity sha512-MKBw9i0DLYlmdOb3Oq/526+al20AJZpANdT6Ct9ffxcV8nKCHz63t/S0IhlTFNsBIHJv+GY5SFJ0XfqVeydQrQ== - dependencies: - "@typescript-eslint/scope-manager" "5.53.0" - "@typescript-eslint/types" "5.53.0" - "@typescript-eslint/typescript-estree" "5.53.0" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@4.29.2": - version "4.29.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.29.2.tgz#442b0f029d981fa402942715b1718ac7fcd5aa1b" - integrity sha512-mfHmvlQxmfkU8D55CkZO2sQOueTxLqGvzV+mG6S/6fIunDiD2ouwsAoiYCZYDDK73QCibYjIZmGhpvKwAB5BOA== - dependencies: - "@typescript-eslint/types" "4.29.2" - "@typescript-eslint/visitor-keys" "4.29.2" - -"@typescript-eslint/scope-manager@5.53.0": - version "5.53.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.53.0.tgz#42b54f280e33c82939275a42649701024f3fafef" - integrity sha512-Opy3dqNsp/9kBBeCPhkCNR7fmdSQqA+47r21hr9a14Bx0xnkElEQmhoHga+VoaoQ6uDHjDKmQPIYcUcKJifS7w== - dependencies: - "@typescript-eslint/types" "5.53.0" - "@typescript-eslint/visitor-keys" "5.53.0" - -"@typescript-eslint/type-utils@5.53.0": - version "5.53.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.53.0.tgz#41665449935ba9b4e6a1ba6e2a3f4b2c31d6cf97" - integrity sha512-HO2hh0fmtqNLzTAme/KnND5uFNwbsdYhCZghK2SoxGp3Ifn2emv+hi0PBUjzzSh0dstUIFqOj3bp0AwQlK4OWw== - dependencies: - "@typescript-eslint/typescript-estree" "5.53.0" - "@typescript-eslint/utils" "5.53.0" - debug "^4.3.4" - tsutils "^3.21.0" - -"@typescript-eslint/types@4.29.2": - version "4.29.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.2.tgz#fc0489c6b89773f99109fb0aa0aaddff21f52fcd" - integrity sha512-K6ApnEXId+WTGxqnda8z4LhNMa/pZmbTFkDxEBLQAbhLZL50DjeY0VIDCml/0Y3FlcbqXZrABqrcKxq+n0LwzQ== - -"@typescript-eslint/types@5.53.0": - version "5.53.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.53.0.tgz#f79eca62b97e518ee124086a21a24f3be267026f" - integrity sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A== - -"@typescript-eslint/typescript-estree@4.29.2": - version "4.29.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.2.tgz#a0ea8b98b274adbb2577100ba545ddf8bf7dc219" - integrity sha512-TJ0/hEnYxapYn9SGn3dCnETO0r+MjaxtlWZ2xU+EvytF0g4CqTpZL48SqSNn2hXsPolnewF30pdzR9a5Lj3DNg== - dependencies: - "@typescript-eslint/types" "4.29.2" - "@typescript-eslint/visitor-keys" "4.29.2" - debug "^4.3.1" - globby "^11.0.3" - is-glob "^4.0.1" - semver "^7.3.5" - tsutils "^3.21.0" - -"@typescript-eslint/typescript-estree@5.53.0": - version "5.53.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.53.0.tgz#bc651dc28cf18ab248ecd18a4c886c744aebd690" - integrity sha512-eKmipH7QyScpHSkhbptBBYh9v8FxtngLquq292YTEQ1pxVs39yFBlLC1xeIZcPPz1RWGqb7YgERJRGkjw8ZV7w== - dependencies: - "@typescript-eslint/types" "5.53.0" - "@typescript-eslint/visitor-keys" "5.53.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/utils@5.53.0": - version "5.53.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.53.0.tgz#e55eaad9d6fffa120575ffaa530c7e802f13bce8" - integrity sha512-VUOOtPv27UNWLxFwQK/8+7kvxVC+hPHNsJjzlJyotlaHjLSIgOCKj9I0DBUjwOOA64qjBwx5afAPjksqOxMO0g== - dependencies: - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.53.0" - "@typescript-eslint/types" "5.53.0" - "@typescript-eslint/typescript-estree" "5.53.0" - eslint-scope "^5.1.1" - eslint-utils "^3.0.0" - semver "^7.3.7" - -"@typescript-eslint/visitor-keys@4.29.2": - version "4.29.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.2.tgz#d2da7341f3519486f50655159f4e5ecdcb2cd1df" - integrity sha512-bDgJLQ86oWHJoZ1ai4TZdgXzJxsea3Ee9u9wsTAvjChdj2WLcVsgWYAPeY7RQMn16tKrlQaBnpKv7KBfs4EQag== - dependencies: - "@typescript-eslint/types" "4.29.2" - eslint-visitor-keys "^2.0.0" - -"@typescript-eslint/visitor-keys@5.53.0": - version "5.53.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.53.0.tgz#8a5126623937cdd909c30d8fa72f79fa56cc1a9f" - integrity sha512-JqNLnX3leaHFZEN0gCh81sIvgrp/2GOACZNgO4+Tkf64u51kTpAyWFOY8XHx8XuXr3N2C9zgPPHtcpMg6z1g0w== - dependencies: - "@typescript-eslint/types" "5.53.0" - eslint-visitor-keys "^3.3.0" - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -abbrev@1.0.x: - version "1.0.9" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.0.9.tgz#91b4792588a7738c25f35dd6f63752a2f8776135" - integrity sha512-LEyx4aLEC3x6T0UguF6YILf+ntvmOaWsVfENmIW0E9H09vKlLDGelMjjSm0jkDHALj8A8quZ/HapKNigzwge+Q== - -abort-controller@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" - integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== - dependencies: - event-target-shim "^5.0.0" - -abortcontroller-polyfill@^1.7.3: - version "1.7.5" - resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz#6738495f4e901fbb57b6c0611d0c75f76c485bed" - integrity sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ== - -abstract-level@^1.0.0, abstract-level@^1.0.2, abstract-level@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/abstract-level/-/abstract-level-1.0.3.tgz#78a67d3d84da55ee15201486ab44c09560070741" - integrity sha512-t6jv+xHy+VYwc4xqZMn2Pa9DjcdzvzZmQGRjTFc8spIbRGHgBrEKbPq+rYXc7CCo0lxgYvSgKVg9qZAhpVQSjA== - dependencies: - buffer "^6.0.3" - catering "^2.1.0" - is-buffer "^2.0.5" - level-supports "^4.0.0" - level-transcoder "^1.0.1" - module-error "^1.0.1" - queue-microtask "^1.2.3" - -accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -acorn-jsx@^5.3.1: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== - -acorn@^7.4.0: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -acorn@^8.4.1: - version "8.8.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== - -address@^1.0.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" - integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== - -adm-zip@^0.4.16: - version "0.4.16" - resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.16.tgz#cf4c508fdffab02c269cbc7f471a875f05570365" - integrity sha512-TFi4HBKSGfIKsK5YCkKaaFG2m4PEDyViZmEwof3MTIgzimHLto6muaHVpbrljdIvIrFZzEq/p4nafOeLcYegrg== - -aes-js@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/aes-js/-/aes-js-3.0.0.tgz#e21df10ad6c2053295bcbb8dab40b09dbea87e4d" - integrity sha512-H7wUZRn8WpTq9jocdxQ2c8x2sKo9ZVmzfRE13GiNJXfp7NcKYEdvl3vspKjXox6RIG2VtaRe4JFvxG4rqp2Zuw== - -agent-base@6: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ajv@^5.1.1: - version "5.5.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" - integrity sha512-Ajr4IcMXq/2QmMkEmSvxqfLN5zGmJ92gHXAeOXq1OekoH2rfDNsgdDoL2f7QaRCy7G/E6TpxBVdRuNraMztGHw== - dependencies: - co "^4.6.0" - fast-deep-equal "^1.0.0" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.3.0" - -ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.6: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^8.0.1: - version "8.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -amdefine@>=0.0.4: - version "1.0.1" - resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" - integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg== - -ansi-colors@3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" - integrity sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw== - -ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - -ansi-colors@^4.1.1, ansi-colors@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - -ansi-escapes@^4.3.0: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== - -ansi-regex@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1" - integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw== - -ansi-regex@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed" - integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-styles@^3.2.0, ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" - integrity sha512-3iF4FIKdxaVYT3JqQuY3Wat/T2t7TRbbQ94Fu50ZUCbLy4TFbTzr90NOHQodQkNqmeEGCw8WbeP78WNi6SKYUA== - -antlr4@4.7.1, antlr4@^4.11.0, antlr4@~4.8.0: - version "4.7.1" - resolved "https://registry.yarnpkg.com/antlr4/-/antlr4-4.7.1.tgz#69984014f096e9e775f53dd9744bf994d8959773" - integrity sha512-haHyTW7Y9joE5MVs37P2lNYfU2RWBLfcRDD8OWldcdZm5TiCE91B5Xl1oWSwiDUSd4rlExpt2pu1fksYQjRBYQ== - -antlr4ts@^0.5.0-alpha.4: - version "0.5.0-alpha.4" - resolved "https://registry.yarnpkg.com/antlr4ts/-/antlr4ts-0.5.0-alpha.4.tgz#71702865a87478ed0b40c0709f422cf14d51652a" - integrity sha512-WPQDt1B74OfPv/IMS2ekXAKkTZIHl88uMetg6q3OTqgFxZ/dxDXI0EWLyZid/1Pe6hTftyg5N7gel5wNAGxXyQ== - -any-promise@^1.0.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" - integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== - -anymatch@~3.1.1, anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -append-transform@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-2.0.0.tgz#99d9d29c7b38391e6f428d28ce136551f0b77e12" - integrity sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg== - dependencies: - default-require-extensions "^3.0.0" - -archy@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" - integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== - -arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -array-back@^3.0.1, array-back@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-3.1.0.tgz#b8859d7a508871c9a7b2cf42f99428f65e96bfb0" - integrity sha512-TkuxA4UCOvxuDK6NZYXCalszEzj+TLszyASooky+i742l9TqsOdYCMJJupxRic61hwquNtppB3hgcuq9SVSH1Q== - -array-back@^4.0.1, array-back@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/array-back/-/array-back-4.0.2.tgz#8004e999a6274586beeb27342168652fdb89fa1e" - integrity sha512-NbdMezxqf94cnNfWLL7V/im0Ub+Anbb0IoZhvzie8+4HJ4nMQuzHuy49FkGYCJK2yAloZ3meiB6AVMClbrI1vg== - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - -array-includes@^3.1.3: - version "3.1.6" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" - integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - get-intrinsic "^1.1.3" - is-string "^1.0.7" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array-uniq@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== - -array.prototype.flat@^1.2.3, array.prototype.flat@^1.2.4: - version "1.3.1" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" - integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - es-shim-unscopables "^1.0.0" - -array.prototype.reduce@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz#6b20b0daa9d9734dd6bc7ea66b5bbce395471eac" - integrity sha512-kDdugMl7id9COE8R7MHF5jWk7Dqt/fs4Pv+JXoICnYwqpjjjbUurz6w5fT5IG6brLdJhv6/VoHB0H7oyIBXd+Q== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - es-array-method-boxes-properly "^1.0.0" - is-string "^1.0.7" - -arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== - -asap@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" - integrity sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA== - -asn1@~0.2.3: - version "0.2.6" - resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.6.tgz#0d3a7bb6e64e02a90c0303b31f292868ea09a08d" - integrity sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ== - dependencies: - safer-buffer "~2.1.0" - -assert-plus@1.0.0, assert-plus@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" - integrity sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw== - -assertion-error@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" - integrity sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw== - -ast-parents@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/ast-parents/-/ast-parents-0.0.1.tgz#508fd0f05d0c48775d9eccda2e174423261e8dd3" - integrity sha512-XHusKxKz3zoYk1ic8Un640joHbFMhbqneyoZfoKnEGtf2ey9Uh/IdpcQplODdO/kENaMIWsD0nJm4+wX3UNLHA== - -astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - -async@1.x: - version "1.5.2" - resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" - integrity sha512-nSVgobk4rv61R9PUSDtYt7mPVB2olxNR5RWJcAsH676/ef11bUZwvu7+RGYrYauVdDPcO519v68wRhXQtxsV9w== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== - -aws-sign2@~0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" - integrity sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA== - -aws4@^1.8.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.12.0.tgz#ce1c9d143389679e253b314241ea9aa5cec980d3" - integrity sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg== - -axios@^0.21.1: - version "0.21.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" - integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== - dependencies: - follow-redirects "^1.14.0" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base-x@^3.0.2, base-x@^3.0.8: - version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" - integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -bcrypt-pbkdf@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" - integrity sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w== - dependencies: - tweetnacl "^0.14.3" - -bech32@1.1.4, bech32@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" - integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== - -better-path-resolve@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/better-path-resolve/-/better-path-resolve-1.0.0.tgz#13a35a1104cdd48a7b74bf8758f96a1ee613f99d" - integrity sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g== - dependencies: - is-windows "^1.0.0" - -big-integer@1.6.36: - version "1.6.36" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.36.tgz#78631076265d4ae3555c04f85e7d9d2f3a071a36" - integrity sha512-t70bfa7HYEA1D9idDbmuv7YbsbVkQ+Hp+8KFSul4aE5e/i1bjCNIRYJZlA8Q8p0r9T8cF/RVvwUgRA//FydEyg== - -big.js@^6.0.3: - version "6.2.1" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.1.tgz#7205ce763efb17c2e41f26f121c420c6a7c2744f" - integrity sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ== - -bigint-crypto-utils@^3.0.23: - version "3.1.8" - resolved "https://registry.yarnpkg.com/bigint-crypto-utils/-/bigint-crypto-utils-3.1.8.tgz#e2e0f40cf45488f9d7f0e32ff84152aa73819d5d" - integrity sha512-+VMV9Laq8pXLBKKKK49nOoq9bfR3j7NNQAtbA617a4nw9bVLo8rsqkKMBgM2AJWlNX9fEIyYaYX+d0laqYV4tw== - dependencies: - bigint-mod-arith "^3.1.0" - -bigint-mod-arith@^3.1.0: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bigint-mod-arith/-/bigint-mod-arith-3.1.2.tgz#658e416bc593a463d97b59766226d0a3021a76b1" - integrity sha512-nx8J8bBeiRR+NlsROFH9jHswW5HO8mgfOSqW0AmjicMMvaONDa8AO+5ViKDUUNytBPWiwfvZP4/Bj4Y3lUfvgQ== - -bignumber.js@*, bignumber.js@^9.0.0, bignumber.js@^9.0.1, bignumber.js@^9.0.2: - version "9.1.1" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6" - integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig== - -bignumber.js@^7.2.1: - version "7.2.1" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" - integrity sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ== - -"bignumber.js@git+https://github.com/frozeman/bignumber.js-nolookahead.git": - version "2.0.7" - resolved "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -blakejs@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.2.1.tgz#5057e4206eadb4a97f7c0b6e197a505042fc3814" - integrity sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ== - -bluebird@^3.4.7, bluebird@^3.5.0, bluebird@^3.5.1, bluebird@^3.5.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -bn-str-256@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/bn-str-256/-/bn-str-256-1.9.1.tgz#898cebee70a3edc3968f97b4cebbc4771025aa82" - integrity sha512-u3muv3WO5sYv9nUQsPnDGLg731yNt/MOlKPK5pmBVqClcl7tY97tyfKxw8ed44HVrpi+7dkgJgQpbXP47a3GoQ== - dependencies: - decimal.js-light "^2.5.0" - lodash "^4.17.11" - -bn.js@4.11.6: - version "4.11.6" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" - integrity sha512-XWwnNNFCuuSQ0m3r3C4LE3EiORltHd9M05pq6FOlVeiophzRbMo50Sbz1ehl8K3Z+jw9+vmgnXefY1hz8X+2wA== - -bn.js@^4.11.0, bn.js@^4.11.6, bn.js@^4.11.8, bn.js@^4.11.9: - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== - -bn.js@^5.1.0, bn.js@^5.1.2, bn.js@^5.1.3, bn.js@^5.2.0, bn.js@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - -body-parser@1.20.1, body-parser@^1.16.0: - version "1.20.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" - integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== - dependencies: - bytes "3.1.2" - content-type "~1.0.4" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.1" - type-is "~1.6.18" - unpipe "1.0.0" - -boolbase@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -breakword@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/breakword/-/breakword-1.0.5.tgz#fd420a417f55016736b5b615161cae1c8f819810" - integrity sha512-ex5W9DoOQ/LUEU3PMdLs9ua/CYZl1678NUkKOdUSi8Aw5F1idieaiRURCBFJCwVcrD1J8Iy3vfWSloaMwO2qFg== - dependencies: - wcwidth "^1.0.1" - -brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== - -browser-level@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browser-level/-/browser-level-1.0.1.tgz#36e8c3183d0fe1c405239792faaab5f315871011" - integrity sha512-XECYKJ+Dbzw0lbydyQuJzwNXtOpbMSq737qxJN11sIRTErOMShvDpbzTlgju7orJKvx4epULolZAuJGLzCmWRQ== - dependencies: - abstract-level "^1.0.2" - catering "^2.1.1" - module-error "^1.0.2" - run-parallel-limit "^1.1.0" - -browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - -browserify-aes@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserslist@^4.21.3: - version "4.21.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" - integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== - dependencies: - caniuse-lite "^1.0.30001449" - electron-to-chromium "^1.4.284" - node-releases "^2.0.8" - update-browserslist-db "^1.0.10" - -bs58@^4.0.0, bs58@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== - dependencies: - base-x "^3.0.2" - -bs58check@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" - integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer-to-arraybuffer@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" - integrity sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ== - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== - -buffer@6.0.3, buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -buffer@^5.0.5, buffer@^5.5.0, buffer@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -bufferutil@^4.0.1: - version "4.0.7" - resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" - integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== - dependencies: - node-gyp-build "^4.3.0" - -busboy@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" - integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== - dependencies: - streamsearch "^1.1.0" - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -cacheable-lookup@^5.0.3: - version "5.0.4" - resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz#5a6b865b2c44357be3d5ebc2a467b032719a7005" - integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== - -cacheable-lookup@^6.0.4: - version "6.1.0" - resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-6.1.0.tgz#0330a543471c61faa4e9035db583aad753b36385" - integrity sha512-KJ/Dmo1lDDhmW2XDPMo+9oiy/CeqosPguPCrgcVzKyZrL6pM1gU2GmPY/xo6OQPTUaA/c0kwHuywB4E6nmT9ww== - -cacheable-request@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.2.tgz#ea0d0b889364a25854757301ca12b2da77f91d27" - integrity sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew== - dependencies: - clone-response "^1.0.2" - get-stream "^5.1.0" - http-cache-semantics "^4.0.0" - keyv "^4.0.0" - lowercase-keys "^2.0.0" - normalize-url "^6.0.1" - responselike "^2.0.0" - -caching-transform@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/caching-transform/-/caching-transform-4.0.0.tgz#00d297a4206d71e2163c39eaffa8157ac0651f0f" - integrity sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA== - dependencies: - hasha "^5.0.0" - make-dir "^3.0.0" - package-hash "^4.0.0" - write-file-atomic "^3.0.0" - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camel-case@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" - integrity sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w== - dependencies: - no-case "^2.2.0" - upper-case "^1.1.1" - -camelcase-keys@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" - integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg== - dependencies: - camelcase "^5.3.1" - map-obj "^4.0.0" - quick-lru "^4.0.1" - -camelcase@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" - integrity sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg== - -camelcase@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" - integrity sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw== - -camelcase@^5.0.0, camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-lite@^1.0.30001449: - version "1.0.30001480" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001480.tgz#9bbd35ee44c2480a1e3a3b9f4496f5066817164a" - integrity sha512-q7cpoPPvZYgtyC4VaBSN0Bt+PJ4c4EYRf0DrduInOz2SkFpHD5p3LnvEpqBp7UnJn+8x1Ogl1s38saUxe+ihQQ== - -case@^1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/case/-/case-1.6.3.tgz#0a4386e3e9825351ca2e6216c60467ff5f1ea1c9" - integrity sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ== - -caseless@^0.12.0, caseless@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" - integrity sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw== - -catering@^2.1.0, catering@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/catering/-/catering-2.1.1.tgz#66acba06ed5ee28d5286133982a927de9a04b510" - integrity sha512-K7Qy8O9p76sL3/3m7/zLKbRkyOlSZAgzEaLhyj2mXS8PsCud2Eo4hAb8aLtZqHh0QGqLcb9dlJSu6lHRVENm1w== - -cbor@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/cbor/-/cbor-5.2.0.tgz#4cca67783ccd6de7b50ab4ed62636712f287a67c" - integrity sha512-5IMhi9e1QU76ppa5/ajP1BmMWZ2FHkhAhjeVKQ/EFCgYSEaeVaoGtL7cxJskf9oCCk+XjzaIdc3IuU/dbA/o2A== - dependencies: - bignumber.js "^9.0.1" - nofilter "^1.0.4" - -cbor@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/cbor/-/cbor-8.1.0.tgz#cfc56437e770b73417a2ecbfc9caf6b771af60d5" - integrity sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg== - dependencies: - nofilter "^3.1.0" - -chai-as-promised@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/chai-as-promised/-/chai-as-promised-7.1.1.tgz#08645d825deb8696ee61725dbf590c012eb00ca0" - integrity sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA== - dependencies: - check-error "^1.0.2" - -chai@^4.2.0: - version "4.3.7" - resolved "https://registry.yarnpkg.com/chai/-/chai-4.3.7.tgz#ec63f6df01829088e8bf55fca839bcd464a8ec51" - integrity sha512-HLnAzZ2iupm25PlN0xFreAlBA5zaBSv3og0DdeGA4Ar6h6rJ3A0rolRUKJhSF2V10GZKDgWF/VmAEsNWjCRB+A== - dependencies: - assertion-error "^1.1.0" - check-error "^1.0.2" - deep-eql "^4.1.2" - get-func-name "^2.0.0" - loupe "^2.3.1" - pathval "^1.1.1" - type-detect "^4.0.5" - -chalk@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" - integrity sha512-sQfYDlfv2DGVtjdoQqxS0cEZDroyG8h6TamA6rvxwlrU5BaSLDx9xhatBYl2pxZ7gmpNaPFVwBtdGdu5rQ+tYQ== - dependencies: - ansi-styles "~1.0.0" - has-color "~0.1.0" - strip-ansi "~0.1.0" - -chalk@^2.0.0, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.3.2, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -change-case@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/change-case/-/change-case-3.0.2.tgz#fd48746cce02f03f0a672577d1d3a8dc2eceb037" - integrity sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA== - dependencies: - camel-case "^3.0.0" - constant-case "^2.0.0" - dot-case "^2.1.0" - header-case "^1.0.0" - is-lower-case "^1.1.0" - is-upper-case "^1.1.0" - lower-case "^1.1.1" - lower-case-first "^1.0.0" - no-case "^2.3.2" - param-case "^2.1.0" - pascal-case "^2.0.0" - path-case "^2.1.0" - sentence-case "^2.1.0" - snake-case "^2.1.0" - swap-case "^1.1.0" - title-case "^2.1.0" - upper-case "^1.1.1" - upper-case-first "^1.1.0" - -chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - -"charenc@>= 0.0.1": - version "0.0.2" - resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" - integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== - -check-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" - integrity sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA== - -cheerio-select@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" - integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== - dependencies: - boolbase "^1.0.0" - css-select "^5.1.0" - css-what "^6.1.0" - domelementtype "^2.3.0" - domhandler "^5.0.3" - domutils "^3.0.1" - -cheerio@^1.0.0-rc.2: - version "1.0.0-rc.12" - resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683" - integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q== - dependencies: - cheerio-select "^2.1.0" - dom-serializer "^2.0.0" - domhandler "^5.0.3" - domutils "^3.0.1" - htmlparser2 "^8.0.1" - parse5 "^7.0.0" - parse5-htmlparser2-tree-adapter "^7.0.0" - -chokidar@3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.3.0.tgz#12c0714668c55800f659e262d4962a97faf554a6" - integrity sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A== - dependencies: - anymatch "~3.1.1" - braces "~3.0.2" - glob-parent "~5.1.0" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.2.0" - optionalDependencies: - fsevents "~2.1.1" - -chokidar@3.5.3, chokidar@^3.4.0: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chownr@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -ci-info@^3.1.0, ci-info@^3.2.0: - version "3.8.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" - integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== - -cids@^0.7.1: - version "0.7.5" - resolved "https://registry.yarnpkg.com/cids/-/cids-0.7.5.tgz#60a08138a99bfb69b6be4ceb63bfef7a396b28b2" - integrity sha512-zT7mPeghoWAu+ppn8+BS1tQ5qGmbMfB4AregnQjA/qHY3GC1m1ptI9GkWNlgeu38r7CuRdXB47uY2XgAYt6QVA== - dependencies: - buffer "^5.5.0" - class-is "^1.1.0" - multibase "~0.6.0" - multicodec "^1.0.0" - multihashes "~0.4.15" - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -class-is@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" - integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== - -classic-level@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.2.0.tgz#2d52bdec8e7a27f534e67fdeb890abef3e643c27" - integrity sha512-qw5B31ANxSluWz9xBzklRWTUAJ1SXIdaVKTVS7HcTGKOAmExx65Wo5BUICW+YGORe2FOUaDghoI9ZDxj82QcFg== - dependencies: - abstract-level "^1.0.2" - catering "^2.1.0" - module-error "^1.0.1" - napi-macros "~2.0.0" - node-gyp-build "^4.3.0" - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -cli-table3@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.5.1.tgz#0252372d94dfc40dbd8df06005f48f31f656f202" - integrity sha512-7Qg2Jrep1S/+Q3EceiZtQcDPWxhAvBw+ERf1162v4sikJrvojMHFqXt8QIVha8UlH9rgU0BeWPytZ9/TzYqlUw== - dependencies: - object-assign "^4.1.0" - string-width "^2.1.1" - optionalDependencies: - colors "^1.1.2" - -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - integrity sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w== - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - -cliui@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" - integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^6.2.0" - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.1" - wrap-ansi "^7.0.0" - -clone-response@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.3.tgz#af2032aa47816399cf5f0a1d0db902f517abb8c3" - integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== - dependencies: - mimic-response "^1.0.0" - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== - -code-point-at@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" - integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -colors@1.4.0, colors@^1.1.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - -combined-stream@^1.0.6, combined-stream@~1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -command-exists@^1.2.8: - version "1.2.9" - resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" - integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== - -command-line-args@^5.1.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/command-line-args/-/command-line-args-5.2.1.tgz#c44c32e437a57d7c51157696893c5909e9cec42e" - integrity sha512-H4UfQhZyakIjC74I9d34fGYDwk3XpSr17QhEd0Q3I9Xq1CETHo4Hcuo87WyWHpAF1aSLjLRf5lD9ZGX2qStUvg== - dependencies: - array-back "^3.1.0" - find-replace "^3.0.0" - lodash.camelcase "^4.3.0" - typical "^4.0.0" - -command-line-usage@^6.1.0: - version "6.1.3" - resolved "https://registry.yarnpkg.com/command-line-usage/-/command-line-usage-6.1.3.tgz#428fa5acde6a838779dfa30e44686f4b6761d957" - integrity sha512-sH5ZSPr+7UStsloltmDh7Ce5fb8XPlHyoPzTpyyMuYCtervL65+ubVZ6Q61cFtFl62UyJlc8/JwERRbAFPUqgw== - dependencies: - array-back "^4.0.2" - chalk "^2.4.2" - table-layout "^1.0.2" - typical "^5.2.0" - -commander@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" - integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== - -commander@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.0.tgz#71797971162cd3cf65f0b9d24eb28f8d303acdf1" - integrity sha512-zS5PnTI22FIRM6ylNW8G4Ap0IEOyk62fhLSD0+uHRT9McRCLGpkVNvao4bjimpK/GShynyQkFFxHhwMcETmduA== - -commander@^2.19.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -concat-stream@^1.6.0, concat-stream@^1.6.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -constant-case@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/constant-case/-/constant-case-2.0.0.tgz#4175764d389d3fa9c8ecd29186ed6005243b6a46" - integrity sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ== - dependencies: - snake-case "^2.1.0" - upper-case "^1.1.1" - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-hash@^2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/content-hash/-/content-hash-2.5.2.tgz#bbc2655e7c21f14fd3bfc7b7d4bfe6e454c9e211" - integrity sha512-FvIQKy0S1JaWV10sMsA7TRx8bpU+pqPkhbsfvOJAdjRXvYxEckAwQWGwtRjiaJfh+E0DvcWUGqcdjwMGFjsSdw== - dependencies: - cids "^0.7.1" - multicodec "^0.5.5" - multihashes "^0.4.15" - -content-type@~1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== - -convert-source-map@^1.7.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" - integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== - -cookie@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" - integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== - -cookiejar@^2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/cookiejar/-/cookiejar-2.1.4.tgz#ee669c1fea2cf42dc31585469d193fef0d65771b" - integrity sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw== - -core-util-is@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" - integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cors@^2.8.1: - version "2.8.5" - resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" - integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== - dependencies: - object-assign "^4" - vary "^1" - -cosmiconfig@^8.0.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.1.0.tgz#947e174c796483ccf0a48476c24e4fefb7e1aea8" - integrity sha512-0tLZ9URlPGU7JsKq0DQOQ3FoRsYX8xDZ7xMiATQfaiGMz7EHowNkbU9u1coAOmnh9p/1ySpm0RB3JNWRXM5GCg== - dependencies: - import-fresh "^3.2.1" - js-yaml "^4.1.0" - parse-json "^5.0.0" - path-type "^4.0.0" - -crc-32@^1.2.0: - version "1.2.2" - resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" - integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== - -create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.4, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - -cross-fetch@^3.1.4: - version "3.1.5" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" - integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== - dependencies: - node-fetch "2.6.7" - -cross-spawn@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A== - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^6.0.0: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -"crypt@>= 0.0.1": - version "0.0.2" - resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b" - integrity sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow== - -crypto-addr-codec@^0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/crypto-addr-codec/-/crypto-addr-codec-0.1.7.tgz#e16cea892730178fe25a38f6d15b680cab3124ae" - integrity sha512-X4hzfBzNhy4mAc3UpiXEC/L0jo5E8wAa9unsnA8nNXYzXjCcGk83hfC5avJWCSGT8V91xMnAS9AKMHmjw5+XCg== - dependencies: - base-x "^3.0.8" - big-integer "1.6.36" - blakejs "^1.1.0" - bs58 "^4.0.1" - ripemd160-min "0.0.6" - safe-buffer "^5.2.0" - sha3 "^2.1.1" - -crypto-js@^3.1.4, crypto-js@^3.1.9-1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.3.0.tgz#846dd1cce2f68aacfa156c8578f926a609b7976b" - integrity sha512-DIT51nX0dCfKltpRiXV+/TVZq+Qq2NgF4644+K7Ttnla7zEzqc+kjJyiB96BHNyUTBxyjzRcZYpUdZa+QAqi6Q== - -css-select@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" - integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== - dependencies: - boolbase "^1.0.0" - css-what "^6.1.0" - domhandler "^5.0.2" - domutils "^3.0.1" - nth-check "^2.0.1" - -css-what@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" - integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== - -csv-generate@^3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/csv-generate/-/csv-generate-3.4.3.tgz#bc42d943b45aea52afa896874291da4b9108ffff" - integrity sha512-w/T+rqR0vwvHqWs/1ZyMDWtHHSJaN06klRqJXBEpDJaM/+dZkso0OKh1VcuuYvK3XM53KysVNq8Ko/epCK8wOw== - -csv-parse@^4.16.3: - version "4.16.3" - resolved "https://registry.yarnpkg.com/csv-parse/-/csv-parse-4.16.3.tgz#7ca624d517212ebc520a36873c3478fa66efbaf7" - integrity sha512-cO1I/zmz4w2dcKHVvpCr7JVRu8/FymG5OEpmvsZYlccYolPBLoVGKUHgNoc4ZGkFeFlWGEDmMyBM+TTqRdW/wg== - -csv-stringify@^5.6.5: - version "5.6.5" - resolved "https://registry.yarnpkg.com/csv-stringify/-/csv-stringify-5.6.5.tgz#c6d74badda4b49a79bf4e72f91cce1e33b94de00" - integrity sha512-PjiQ659aQ+fUTQqSrd1XEDnOr52jh30RBurfzkscaE2tPaFsDH5wOAHJiw8XAHphRknCwMUE9KRayc4K/NbO8A== - -csv@^5.5.0: - version "5.5.3" - resolved "https://registry.yarnpkg.com/csv/-/csv-5.5.3.tgz#cd26c1e45eae00ce6a9b7b27dcb94955ec95207d" - integrity sha512-QTaY0XjjhTQOdguARF0lGKm5/mEq9PD9/VhZZegHDIBq2tQwgNpHc3dneD4mGo2iJs+fTKv5Bp0fZ+BRuY3Z0g== - dependencies: - csv-generate "^3.4.3" - csv-parse "^4.16.3" - csv-stringify "^5.6.5" - stream-transform "^2.1.3" - -d@1, d@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" - integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== - dependencies: - es5-ext "^0.10.50" - type "^1.0.1" - -dashdash@^1.12.0: - version "1.14.1" - resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" - integrity sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g== - dependencies: - assert-plus "^1.0.0" - -date-time@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/date-time/-/date-time-0.1.1.tgz#ed2f6d93d9790ce2fd66d5b5ff3edd5bbcbf3b07" - integrity sha512-p4psdkgdNA6x0600SKbfWiOomNb33ADBMRHf49GMhYVgJsPefZlMSLXXVWWUpbqSxB3DL5/cxKa6a8i3XPK5Xg== - -death@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" - integrity sha512-vsV6S4KVHvTGxbEcij7hkWRv0It+sGGWVOM67dQde/o5Xjnr+KmLjxWJii2uEObIrt1CcM9w0Yaovx+iOlIL+w== - -debug@2.6.9, debug@^2.2.0, debug@^2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" - integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== - dependencies: - ms "^2.1.1" - -debug@4, debug@4.3.4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.3, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -debug@^3.1.0, debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -decamelize-keys@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" - integrity sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg== - dependencies: - decamelize "^1.1.0" - map-obj "^1.0.0" - -decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== - -decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - -decimal.js-light@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" - integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== - -decode-uri-component@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" - integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== - -decompress-response@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" - integrity sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA== - dependencies: - mimic-response "^1.0.0" - -decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" - integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== - dependencies: - mimic-response "^3.1.0" - -deep-eql@^4.0.1, deep-eql@^4.1.2: - version "4.1.3" - resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-4.1.3.tgz#7c7775513092f7df98d8df9996dd085eb668cc6d" - integrity sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw== - dependencies: - type-detect "^4.0.0" - -deep-extend@~0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - -deep-is@^0.1.3, deep-is@~0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -default-require-extensions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-3.0.1.tgz#bfae00feeaeada68c2ae256c62540f60b80625bd" - integrity sha512-eXTJmRbm2TIt9MgWTsOH1wEuhew6XGZcMeGKCtLedIg/NCsg1iBePXkceTdK4Fii7pzmN9tGsZhKzZ4h7O/fxw== - dependencies: - strip-bom "^4.0.0" - -defaults@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" - integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== - dependencies: - clone "^1.0.2" - -defer-to-connect@^2.0.0, defer-to-connect@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.1.tgz#8016bdb4143e4632b77a3449c6236277de520587" - integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== - -define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" - integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== - dependencies: - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -depd@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -destroy@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - -detect-indent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" - integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== - -detect-indent@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-6.1.0.tgz#592485ebbbf6b3b1ab2be175c8393d04ca0d57e6" - integrity sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA== - -detect-port@^1.3.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" - integrity sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ== - dependencies: - address "^1.0.1" - debug "4" - -diff@3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== - -diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - -diff@^4.0.1, diff@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - -difflib@^0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/difflib/-/difflib-0.2.4.tgz#b5e30361a6db023176d562892db85940a718f47e" - integrity sha512-9YVwmMb0wQHQNr5J9m6BSj6fk4pfGITGQOOs+D9Fl+INODWFOfvhIU1hNv6GgR1RBoC/9NJcwu77zShxV0kT7w== - dependencies: - heap ">= 0.2.0" - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dom-serializer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" - integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.2" - entities "^4.2.0" - -dom-walk@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" - integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== - -domelementtype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" - integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== - -domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" - integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== - dependencies: - domelementtype "^2.3.0" - -domutils@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c" - integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q== - dependencies: - dom-serializer "^2.0.0" - domelementtype "^2.3.0" - domhandler "^5.0.1" - -dot-case@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-2.1.1.tgz#34dcf37f50a8e93c2b3bca8bb7fb9155c7da3bee" - integrity sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug== - dependencies: - no-case "^2.2.0" - -ecc-jsbn@~0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" - integrity sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw== - dependencies: - jsbn "~0.1.0" - safer-buffer "^2.1.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - -electron-to-chromium@^1.4.284: - version "1.4.367" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.367.tgz#d9ddc529ba2315fc852b722c359e4a40e86aa742" - integrity sha512-mNuDxb+HpLhPGUKrg0hSxbTjHWw8EziwkwlJNkFUj3W60ypigLDRVz04vU+VRsJPi8Gub+FDhYUpuTm9xiEwRQ== - -elliptic@6.5.4, elliptic@^6.4.0, elliptic@^6.5.2, elliptic@^6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" - -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - -end-of-stream@^1.1.0: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - -enquirer@^2.3.0, enquirer@^2.3.4, enquirer@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -entities@^4.2.0, entities@^4.3.0, entities@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-4.4.0.tgz#97bdaba170339446495e653cfd2db78962900174" - integrity sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA== - -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - -error-ex@^1.2.0, error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.19.0, es-abstract@^1.20.4: - version "1.21.1" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.1.tgz#e6105a099967c08377830a0c9cb589d570dd86c6" - integrity sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - es-set-tostringtag "^2.0.1" - es-to-primitive "^1.2.1" - function-bind "^1.1.1" - function.prototype.name "^1.1.5" - get-intrinsic "^1.1.3" - get-symbol-description "^1.0.0" - globalthis "^1.0.3" - gopd "^1.0.1" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - internal-slot "^1.0.4" - is-array-buffer "^3.0.1" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-typed-array "^1.1.10" - is-weakref "^1.0.2" - object-inspect "^1.12.2" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" - safe-regex-test "^1.0.0" - string.prototype.trimend "^1.0.6" - string.prototype.trimstart "^1.0.6" - typed-array-length "^1.0.4" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.9" - -es-array-method-boxes-properly@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" - integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== - -es-set-tostringtag@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" - integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== - dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" - has-tostringtag "^1.0.0" - -es-shim-unscopables@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" - integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== - dependencies: - has "^1.0.3" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es5-ext@^0.10.35, es5-ext@^0.10.50: - version "0.10.62" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" - integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== - dependencies: - es6-iterator "^2.0.3" - es6-symbol "^3.1.3" - next-tick "^1.1.0" - -es6-error@^4.0.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/es6-error/-/es6-error-4.1.1.tgz#9e3af407459deed47e9a91f9b885a84eb05c561d" - integrity sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg== - -es6-iterator@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-promise@^4.2.8: - version "4.2.8" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" - integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== - -es6-symbol@^3.1.1, es6-symbol@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" - integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== - dependencies: - d "^1.0.1" - ext "^1.1.2" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - -escape-string-regexp@1.0.5, escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escodegen@1.8.x: - version "1.8.1" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" - integrity sha512-yhi5S+mNTOuRvyW4gWlg5W1byMaQGWWSYHXsuFZ7GBo7tpyOwi2EdzMP/QWxh9hwkD2m+wDVHJsxhRIj+v/b/A== - dependencies: - esprima "^2.7.1" - estraverse "^1.9.1" - esutils "^2.0.2" - optionator "^0.8.1" - optionalDependencies: - source-map "~0.2.0" - -eslint-config-prettier@8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" - integrity sha512-BgZuLUSeKzvlL/VUjx/Yb787VQ26RU3gGjA3iiFvdsp/2bMfVIWUVP7tjxtjS0e+HP409cPlPvNkQloz8C91ew== - -eslint-import-resolver-node@^0.3.6: - version "0.3.7" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" - integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA== - dependencies: - debug "^3.2.7" - is-core-module "^2.11.0" - resolve "^1.22.1" - -eslint-module-utils@^2.6.2: - version "2.7.4" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" - integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== - dependencies: - debug "^3.2.7" - -eslint-plugin-import@2.24.1: - version "2.24.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.24.1.tgz#64aba8b567a1ba9921d5465586e86c491b8e2135" - integrity sha512-KSFWhNxPH8OGJwpRJJs+Z7I0a13E2iFQZJIvSnCu6KUs4qmgAm3xN9GYBCSoiGWmwA7gERZPXqYQjcoCROnYhQ== - dependencies: - array-includes "^3.1.3" - array.prototype.flat "^1.2.4" - debug "^2.6.9" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.6" - eslint-module-utils "^2.6.2" - find-up "^2.0.0" - has "^1.0.3" - is-core-module "^2.6.0" - minimatch "^3.0.4" - object.values "^1.1.4" - pkg-up "^2.0.0" - read-pkg-up "^3.0.0" - resolve "^1.20.0" - tsconfig-paths "^3.10.1" - -eslint-plugin-no-only-tests@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-no-only-tests/-/eslint-plugin-no-only-tests-3.0.0.tgz#026cbc8cb069c8da6b7e19d03654be7ad49893f6" - integrity sha512-I0PeXMs1vu21ap45hey4HQCJRqpcoIvGcNTPJe+UhUm8TwjQ6//mCrDqF8q0WS6LgmRDwQ4ovQej0AQsAHb5yg== - -eslint-plugin-prettier@3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.0.tgz#cdbad3bf1dbd2b177e9825737fe63b476a08f0c7" - integrity sha512-UDK6rJT6INSfcOo545jiaOwB701uAIt2/dR7WnFQoGCVl1/EMqdANBmwUaqqQ45aXprsTGzSa39LI1PyuRBxxw== - dependencies: - prettier-linter-helpers "^1.0.0" - -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - -eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - -eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - -eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - -eslint-visitor-keys@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" - integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== - -eslint@^7.29.0: - version "7.32.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" - integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== - dependencies: - "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.3" - "@humanwhocodes/config-array" "^0.5.0" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.0.1" - doctrine "^3.0.0" - enquirer "^2.3.5" - escape-string-regexp "^4.0.0" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" - esquery "^1.4.0" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.1.2" - globals "^13.6.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.0.4" - natural-compare "^1.4.0" - optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" - strip-json-comments "^3.1.0" - table "^6.0.9" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - -espree@^7.3.0, espree@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== - dependencies: - acorn "^7.4.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" - -esprima@2.7.x, esprima@^2.7.1: - version "2.7.3" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" - integrity sha512-OarPfz0lFCiW4/AV2Oy1Rp9qu0iusTKqykwTspGCZtPxmF81JR4MmIebvF1F9+UOKth2ZubLQ4XGGaU+hSn99A== - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^1.9.1: - version "1.9.3" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" - integrity sha512-25w1fMXQrGdoquWnScXZGckOv+Wes+JDnuN/+7ex3SauFRS72r2lFDec0EKPt2YD1wUJ/IrfEex+9yp4hfSOJA== - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - -eth-ens-namehash@2.0.8, eth-ens-namehash@^2.0.0, eth-ens-namehash@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/eth-ens-namehash/-/eth-ens-namehash-2.0.8.tgz#229ac46eca86d52e0c991e7cb2aef83ff0f68bcf" - integrity sha512-VWEI1+KJfz4Km//dadyvBBoBeSQ0MHTXPvr8UIXiLW6IanxvAV+DmlZAijZwAyggqGUfwQBeHf7tc9wzc1piSw== - dependencies: - idna-uts46-hx "^2.3.1" - js-sha3 "^0.5.7" - -eth-gas-reporter@^0.2.25: - version "0.2.25" - resolved "https://registry.yarnpkg.com/eth-gas-reporter/-/eth-gas-reporter-0.2.25.tgz#546dfa946c1acee93cb1a94c2a1162292d6ff566" - integrity sha512-1fRgyE4xUB8SoqLgN3eDfpDfwEfRxh2Sz1b7wzFbyQA+9TekMmvSjjoRu9SKcSVyK+vLkLIsVbJDsTWjw195OQ== - dependencies: - "@ethersproject/abi" "^5.0.0-beta.146" - "@solidity-parser/parser" "^0.14.0" - cli-table3 "^0.5.0" - colors "1.4.0" - ethereum-cryptography "^1.0.3" - ethers "^4.0.40" - fs-readdir-recursive "^1.1.0" - lodash "^4.17.14" - markdown-table "^1.1.3" - mocha "^7.1.1" - req-cwd "^2.0.0" - request "^2.88.0" - request-promise-native "^1.0.5" - sha1 "^1.1.1" - sync-request "^6.0.0" - -eth-lib@0.2.8: - version "0.2.8" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.2.8.tgz#b194058bef4b220ad12ea497431d6cb6aa0623c8" - integrity sha512-ArJ7x1WcWOlSpzdoTBX8vkwlkSQ85CjjifSZtV4co64vWxSV8geWfPI9x4SVYu3DSxnX4yWFVTtGL+j9DUFLNw== - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - xhr-request-promise "^0.1.2" - -eth-lib@^0.1.26: - version "0.1.29" - resolved "https://registry.yarnpkg.com/eth-lib/-/eth-lib-0.1.29.tgz#0c11f5060d42da9f931eab6199084734f4dbd1d9" - integrity sha512-bfttrr3/7gG4E02HoWTDUcDDslN003OlOoBxk9virpAZQ1ja/jDgwkWB8QfJF7ojuEowrqy+lzp9VcJG7/k5bQ== - dependencies: - bn.js "^4.11.6" - elliptic "^6.4.0" - nano-json-stream-parser "^0.1.2" - servify "^0.1.12" - ws "^3.0.0" - xhr-request-promise "^0.1.2" - -ethereum-bloom-filters@^1.0.6: - version "1.0.10" - resolved "https://registry.yarnpkg.com/ethereum-bloom-filters/-/ethereum-bloom-filters-1.0.10.tgz#3ca07f4aed698e75bd134584850260246a5fed8a" - integrity sha512-rxJ5OFN3RwjQxDcFP2Z5+Q9ho4eIdEmSc2ht0fCu8Se9nbXjZ7/031uXoUYJ87KHCOdVeiUuwSnoS7hmYAGVHA== - dependencies: - js-sha3 "^0.8.0" - -ethereum-cryptography@0.1.3, ethereum-cryptography@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-0.1.3.tgz#8d6143cfc3d74bf79bbd8edecdf29e4ae20dd191" - integrity sha512-w8/4x1SGGzc+tO97TASLja6SLd3fRIK2tLVcV2Gx4IB21hE19atll5Cq9o3d0ZmAYC/8aw0ipieTSiekAea4SQ== - dependencies: - "@types/pbkdf2" "^3.0.0" - "@types/secp256k1" "^4.0.1" - blakejs "^1.1.0" - browserify-aes "^1.2.0" - bs58check "^2.1.2" - create-hash "^1.2.0" - create-hmac "^1.1.7" - hash.js "^1.1.7" - keccak "^3.0.0" - pbkdf2 "^3.0.17" - randombytes "^2.1.0" - safe-buffer "^5.1.2" - scrypt-js "^3.0.0" - secp256k1 "^4.0.1" - setimmediate "^1.0.5" - -ethereum-cryptography@^1.0.3: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-1.2.0.tgz#5ccfa183e85fdaf9f9b299a79430c044268c9b3a" - integrity sha512-6yFQC9b5ug6/17CQpCyE3k9eKBMdhyVjzUy1WkiuY/E4vj/SXDBbCw8QEIaXqf0Mf2SnY6RmpDcwlUmBSS0EJw== - dependencies: - "@noble/hashes" "1.2.0" - "@noble/secp256k1" "1.7.1" - "@scure/bip32" "1.1.5" - "@scure/bip39" "1.1.1" - -ethereum-ens@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/ethereum-ens/-/ethereum-ens-0.8.0.tgz#6d0f79acaa61fdbc87d2821779c4e550243d4c57" - integrity sha512-a8cBTF4AWw1Q1Y37V1LSCS9pRY4Mh3f8vCg5cbXCCEJ3eno1hbI/+Ccv9SZLISYpqQhaglP3Bxb/34lS4Qf7Bg== - dependencies: - bluebird "^3.4.7" - eth-ens-namehash "^2.0.0" - js-sha3 "^0.5.7" - pako "^1.0.4" - underscore "^1.8.3" - web3 "^1.0.0-beta.34" - -ethereumjs-abi@^0.6.8: - version "0.6.8" - resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" - integrity sha512-Tx0r/iXI6r+lRsdvkFDlut0N08jWMnKRZ6Gkq+Nmw75lZe4e6o3EkSnkaBP5NF6+m5PTGAr9JP43N3LyeoglsA== - dependencies: - bn.js "^4.11.8" - ethereumjs-util "^6.0.0" - -ethereumjs-util@6.2.1, ethereumjs-util@^6.0.0, ethereumjs-util@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-6.2.1.tgz#fcb4e4dd5ceacb9d2305426ab1a5cd93e3163b69" - integrity sha512-W2Ktez4L01Vexijrm5EB6w7dg4n/TgpoYU4avuT5T3Vmnw/eCRtiBrJfQYS/DCSvDIOLn2k57GcHdeBcgVxAqw== - dependencies: - "@types/bn.js" "^4.11.3" - bn.js "^4.11.0" - create-hash "^1.1.2" - elliptic "^6.5.2" - ethereum-cryptography "^0.1.3" - ethjs-util "0.1.6" - rlp "^2.2.3" - -ethereumjs-util@^7.1.0, ethereumjs-util@^7.1.1, ethereumjs-util@^7.1.2, ethereumjs-util@^7.1.4, ethereumjs-util@^7.1.5: - version "7.1.5" - resolved "https://registry.yarnpkg.com/ethereumjs-util/-/ethereumjs-util-7.1.5.tgz#9ecf04861e4fbbeed7465ece5f23317ad1129181" - integrity sha512-SDl5kKrQAudFBUe5OJM9Ac6WmMyYmXX/6sTmLZ3ffG2eY6ZIGBes3pEDxNN6V72WyOw4CPD5RomKdsa8DAAwLg== - dependencies: - "@types/bn.js" "^5.1.0" - bn.js "^5.1.2" - create-hash "^1.1.2" - ethereum-cryptography "^0.1.3" - rlp "^2.2.4" - -ethers@^4.0.0-beta.1, ethers@^4.0.32, ethers@^4.0.40: - version "4.0.49" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.49.tgz#0eb0e9161a0c8b4761be547396bbe2fb121a8894" - integrity sha512-kPltTvWiyu+OktYy1IStSO16i2e7cS9D9OxZ81q2UUaiNPVrm/RTcbxamCXF9VUSKzJIdJV68EAIhTEVBalRWg== - dependencies: - aes-js "3.0.0" - bn.js "^4.11.9" - elliptic "6.5.4" - hash.js "1.1.3" - js-sha3 "0.5.7" - scrypt-js "2.0.4" - setimmediate "1.0.4" - uuid "2.0.1" - xmlhttprequest "1.8.0" - -ethers@^5.0.0, ethers@^5.0.13, ethers@^5.4.7, ethers@^5.7.1: - version "5.7.2" - resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.7.2.tgz#3a7deeabbb8c030d4126b24f84e525466145872e" - integrity sha512-wswUsmWo1aOK8rR7DIKiWSw9DbLWe6x98Jrn8wcTflTVvaXhAMaB5zGAXy0GYQEQp9iO1iSHWVyARQm11zUtyg== - dependencies: - "@ethersproject/abi" "5.7.0" - "@ethersproject/abstract-provider" "5.7.0" - "@ethersproject/abstract-signer" "5.7.0" - "@ethersproject/address" "5.7.0" - "@ethersproject/base64" "5.7.0" - "@ethersproject/basex" "5.7.0" - "@ethersproject/bignumber" "5.7.0" - "@ethersproject/bytes" "5.7.0" - "@ethersproject/constants" "5.7.0" - "@ethersproject/contracts" "5.7.0" - "@ethersproject/hash" "5.7.0" - "@ethersproject/hdnode" "5.7.0" - "@ethersproject/json-wallets" "5.7.0" - "@ethersproject/keccak256" "5.7.0" - "@ethersproject/logger" "5.7.0" - "@ethersproject/networks" "5.7.1" - "@ethersproject/pbkdf2" "5.7.0" - "@ethersproject/properties" "5.7.0" - "@ethersproject/providers" "5.7.2" - "@ethersproject/random" "5.7.0" - "@ethersproject/rlp" "5.7.0" - "@ethersproject/sha2" "5.7.0" - "@ethersproject/signing-key" "5.7.0" - "@ethersproject/solidity" "5.7.0" - "@ethersproject/strings" "5.7.0" - "@ethersproject/transactions" "5.7.0" - "@ethersproject/units" "5.7.0" - "@ethersproject/wallet" "5.7.0" - "@ethersproject/web" "5.7.1" - "@ethersproject/wordlists" "5.7.0" - -ethjs-abi@0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/ethjs-abi/-/ethjs-abi-0.1.8.tgz#cd288583ed628cdfadaf8adefa3ba1dbcbca6c18" - integrity sha512-3SIJpF+LCVJrNht9OjSJ7+3B9ABZf6dEATMj1PaslL0BW547Cz6/kGyuDvvrcEBlSsbGpCWYrJX5B8OjhcAMFQ== - dependencies: - bn.js "4.11.6" - js-sha3 "0.5.5" - number-to-bn "1.7.0" - -ethjs-unit@0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-unit/-/ethjs-unit-0.1.6.tgz#c665921e476e87bce2a9d588a6fe0405b2c41699" - integrity sha512-/Sn9Y0oKl0uqQuvgFk/zQgR7aw1g36qX/jzSQ5lSwlO0GigPymk4eGQfeNTD03w1dPOqfz8V77Cy43jH56pagw== - dependencies: - bn.js "4.11.6" - number-to-bn "1.7.0" - -ethjs-util@0.1.6, ethjs-util@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/ethjs-util/-/ethjs-util-0.1.6.tgz#f308b62f185f9fe6237132fb2a9818866a5cd536" - integrity sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w== - dependencies: - is-hex-prefixed "1.0.0" - strip-hex-prefix "1.0.0" - -event-target-shim@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" - integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== - -eventemitter3@4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" - integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== - -evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -express@^4.14.0: - version "4.18.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" - integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.1" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.5.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.2.0" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "2.4.1" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.7" - qs "6.11.0" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" - setprototypeof "1.2.0" - statuses "2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -ext@^1.1.2: - version "1.7.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" - integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== - dependencies: - type "^2.7.2" - -extend@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -extendable-error@^0.1.5: - version "0.1.7" - resolved "https://registry.yarnpkg.com/extendable-error/-/extendable-error-0.1.7.tgz#60b9adf206264ac920058a7395685ae4670c2b96" - integrity sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg== - -external-editor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - -extsprintf@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" - integrity sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g== - -extsprintf@^1.2.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.1.tgz#8d172c064867f235c0c84a596806d279bf4bcc07" - integrity sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA== - -fast-check@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-check/-/fast-check-3.1.1.tgz#72c5ae7022a4e86504762e773adfb8a5b0b01252" - integrity sha512-3vtXinVyuUKCKFKYcwXhGE6NtGWkqF8Yh3rvMZNzmwz8EPrgoc/v4pDdLHyLnCyCI5MZpZZkDEwFyXyEONOxpA== - dependencies: - pure-rand "^5.0.1" - -fast-deep-equal@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" - integrity sha512-fueX787WZKCV0Is4/T2cyAdM4+x1S3MXXOAhavE1ys/W42SHAPacLTQhucja22QBYrfGw50M2sRiXPtTGv9Ymw== - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-diff@^1.1.2, fast-diff@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" - integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== - -fast-glob@^3.0.3, fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" - -find-cache-dir@^3.2.0: - version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" - integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - -find-replace@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-replace/-/find-replace-3.0.0.tgz#3e7e23d3b05167a76f770c9fbd5258b0def68c38" - integrity sha512-6Tb2myMioCAgv5kfvP5/PkZZ/ntTpVK39fHY7WkWBgvbeE+VHd/tZuZ4mrC+bxh4cfOZeYKVPaJIZtZXV7GNCQ== - dependencies: - array-back "^3.0.1" - -find-up@3.0.0, find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -find-up@5.0.0, find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.0.0, find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== - dependencies: - locate-path "^2.0.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -find-yarn-workspace-root2@1.2.16: - version "1.2.16" - resolved "https://registry.yarnpkg.com/find-yarn-workspace-root2/-/find-yarn-workspace-root2-1.2.16.tgz#60287009dd2f324f59646bdb4b7610a6b301c2a9" - integrity sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA== - dependencies: - micromatch "^4.0.2" - pkg-dir "^4.2.0" - -flat-cache@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" - integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== - dependencies: - flatted "^3.1.0" - rimraf "^3.0.2" - -flat@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/flat/-/flat-4.1.1.tgz#a392059cc382881ff98642f5da4dde0a959f309b" - integrity sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA== - dependencies: - is-buffer "~2.0.3" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^3.1.0: - version "3.2.7" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" - integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== - -follow-redirects@^1.12.1, follow-redirects@^1.14.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== - -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -foreground-child@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-2.0.0.tgz#71b32800c9f15aa8f2f83f4a6bd9bff35d861a53" - integrity sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^3.0.2" - -forever-agent@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" - integrity sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw== - -form-data-encoder@1.7.1: - version "1.7.1" - resolved "https://registry.yarnpkg.com/form-data-encoder/-/form-data-encoder-1.7.1.tgz#ac80660e4f87ee0d3d3c3638b7da8278ddb8ec96" - integrity sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg== - -form-data@^2.2.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" - integrity sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -form-data@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" - integrity sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.6" - mime-types "^2.1.12" - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fp-ts@1.19.3: - version "1.19.3" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.3.tgz#261a60d1088fbff01f91256f91d21d0caaaaa96f" - integrity sha512-H5KQDspykdHuztLTg+ajGN0Z2qUjcEf3Ybxc6hLt0k7/zPkn29XnKnxlBPyW2XIddWrGaJBzBl4VLYOtk39yZg== - -fp-ts@^1.0.0: - version "1.19.5" - resolved "https://registry.yarnpkg.com/fp-ts/-/fp-ts-1.19.5.tgz#3da865e585dfa1fdfd51785417357ac50afc520a" - integrity sha512-wDNqTimnzs8QqpldiId9OavWK2NptormjXnRJTQecNjzwfyp6P/8s/zG8e4h3ja3oqkKaY72UlTjQYt/1yXf9A== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - -fromentries@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/fromentries/-/fromentries-1.3.2.tgz#e4bca6808816bf8f93b52750f1127f5a6fd86e3a" - integrity sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg== - -fs-extra@^0.30.0: - version "0.30.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.30.0.tgz#f233ffcc08d4da7d432daa449776989db1df93f0" - integrity sha512-UvSPKyhMn6LEd/WpUaV9C9t3zATuqoqfWc3QdPhPLb58prN9tqYPlPWi8Krxi44loBoUzlobqZ3+8tGpxxSzwA== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^2.1.0" - klaw "^1.0.0" - path-is-absolute "^1.0.0" - rimraf "^2.2.8" - -fs-extra@^4.0.2: - version "4.0.3" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" - integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^7.0.0, fs-extra@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-7.0.1.tgz#4f189c44aa123b895f722804f55ea23eadc348e9" - integrity sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw== - dependencies: - graceful-fs "^4.1.2" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" - integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^4.0.0" - universalify "^0.1.0" - -fs-extra@^9.1.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-minipass@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.7.tgz#ccff8570841e7fe4265693da88936c55aed7f7c7" - integrity sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA== - dependencies: - minipass "^2.6.0" - -fs-readdir-recursive@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" - integrity sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@~2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" - integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -function.prototype.name@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" - integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - es-abstract "^1.19.0" - functions-have-names "^1.2.2" - -functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== - -functions-have-names@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -ganache-cli@^6.12.2: - version "6.12.2" - resolved "https://registry.yarnpkg.com/ganache-cli/-/ganache-cli-6.12.2.tgz#c0920f7db0d4ac062ffe2375cb004089806f627a" - integrity sha512-bnmwnJDBDsOWBUP8E/BExWf85TsdDEFelQSzihSJm9VChVO1SHp94YXLP5BlA4j/OTxp0wR4R1Tje9OHOuAJVw== - dependencies: - ethereumjs-util "6.2.1" - source-map-support "0.5.12" - yargs "13.2.4" - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-caller-file@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" - integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== - -get-caller-file@^2.0.1, get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-func-name@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" - integrity sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" - integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== - -get-port@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" - integrity sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg== - -get-port@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" - integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== - -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-stream@^5.1.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" - integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== - dependencies: - pump "^3.0.0" - -get-stream@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -getpass@^0.1.1: - version "0.1.7" - resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" - integrity sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng== - dependencies: - assert-plus "^1.0.0" - -ghost-testrpc@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/ghost-testrpc/-/ghost-testrpc-0.0.2.tgz#c4de9557b1d1ae7b2d20bbe474a91378ca90ce92" - integrity sha512-i08dAEgJ2g8z5buJIrCTduwPIhih3DP+hOCTyyryikfV8T0bNvHnGXO67i0DD1H4GBDETTclPy9njZbfluQYrQ== - dependencies: - chalk "^2.4.2" - node-emoji "^1.10.0" - -glob-parent@^5.1.2, glob-parent@~5.1.0, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob@7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^5.0.15: - version "5.0.15" - resolved "https://registry.yarnpkg.com/glob/-/glob-5.0.15.tgz#1bc936b9e02f4a603fcc222ecf7633d30b8b93b1" - integrity sha512-c9IPMazfRITpmAAKi22dK1VKxGDX9ehhqfABDriL/lzO92xcUKEJPQHrVA/2YHSNFB4iFlykVmWvwo48nr3OxA== - dependencies: - inflight "^1.0.4" - inherits "2" - minimatch "2 || 3" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^7.0.0, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^8.0.3: - version "8.1.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" - integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -global-modules@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" - integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== - dependencies: - global-prefix "^3.0.0" - -global-prefix@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-3.0.0.tgz#fc85f73064df69f50421f47f883fe5b913ba9b97" - integrity sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg== - dependencies: - ini "^1.3.5" - kind-of "^6.0.2" - which "^1.3.1" - -global@~4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" - integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== - dependencies: - min-document "^2.19.0" - process "^0.11.10" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^13.6.0, globals@^13.9.0: - version "13.20.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" - integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== - dependencies: - type-fest "^0.20.2" - -globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== - dependencies: - define-properties "^1.1.3" - -globby@^10.0.1: - version "10.0.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" - integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.0.3" - glob "^7.1.3" - ignore "^5.1.1" - merge2 "^1.2.3" - slash "^3.0.0" - -globby@^11.0.0, globby@^11.0.3, globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - -got@12.1.0: - version "12.1.0" - resolved "https://registry.yarnpkg.com/got/-/got-12.1.0.tgz#099f3815305c682be4fd6b0ee0726d8e4c6b0af4" - integrity sha512-hBv2ty9QN2RdbJJMK3hesmSkFTjVIHyIDDbssCKnSmq62edGgImJWD10Eb1k77TiV1bxloxqcFAVK8+9pkhOig== - dependencies: - "@sindresorhus/is" "^4.6.0" - "@szmarczak/http-timer" "^5.0.1" - "@types/cacheable-request" "^6.0.2" - "@types/responselike" "^1.0.0" - cacheable-lookup "^6.0.4" - cacheable-request "^7.0.2" - decompress-response "^6.0.0" - form-data-encoder "1.7.1" - get-stream "^6.0.1" - http2-wrapper "^2.1.10" - lowercase-keys "^3.0.0" - p-cancelable "^3.0.0" - responselike "^2.0.0" - -got@^11.8.5: - version "11.8.6" - resolved "https://registry.yarnpkg.com/got/-/got-11.8.6.tgz#276e827ead8772eddbcfc97170590b841823233a" - integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== - dependencies: - "@sindresorhus/is" "^4.0.0" - "@szmarczak/http-timer" "^4.0.5" - "@types/cacheable-request" "^6.0.1" - "@types/responselike" "^1.0.0" - cacheable-lookup "^5.0.3" - cacheable-request "^7.0.2" - decompress-response "^6.0.0" - http2-wrapper "^1.0.0-beta.5.2" - lowercase-keys "^2.0.0" - p-cancelable "^2.0.0" - responselike "^2.0.0" - -graceful-fs@^4.1.15: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - -graceful-fs@^4.1.2, graceful-fs@^4.1.5, graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0: - version "4.2.10" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" - integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== - -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - -growl@1.10.5: - version "1.10.5" - resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.5.tgz#f2735dc2283674fa67478b10181059355c369e5e" - integrity sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA== - -handlebars@^4.0.1: - version "4.7.7" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" - integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.0" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - -har-schema@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" - integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== - -har-validator@~5.1.3: - version "5.1.5" - resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.5.tgz#1f0803b9f8cb20c0fa13822df1ecddb36bde1efd" - integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== - dependencies: - ajv "^6.12.3" - har-schema "^2.0.0" - -hard-rejection@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" - integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== - -hardhat-gas-reporter@^1.0.8: - version "1.0.9" - resolved "https://registry.yarnpkg.com/hardhat-gas-reporter/-/hardhat-gas-reporter-1.0.9.tgz#9a2afb354bc3b6346aab55b1c02ca556d0e16450" - integrity sha512-INN26G3EW43adGKBNzYWOlI3+rlLnasXTwW79YNnUhXPDa+yHESgt639dJEs37gCjhkbNKcRRJnomXEuMFBXJg== - dependencies: - array-uniq "1.0.3" - eth-gas-reporter "^0.2.25" - sha1 "^1.1.1" - -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-color@~0.1.0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" - integrity sha512-kaNz5OTAYYmt646Hkqw50/qyxP2vFnTVu5AQ1Zmk22Kk5+4Qx6BpO8+u7IKsML5fOsFk0ZT0AcCJNYwcvaLBvw== - -has-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" - integrity sha512-DyYHfIYwAJmjAjSSPKANxI8bFY9YtFrgkAfinBojQ8YJTOuOuav64tMUJv584SES4xl74PmuaevIyaLESHdTAA== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - -has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== - -has-symbols@^1.0.0, has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - -hash.js@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.3.tgz#340dedbe6290187151c1ea1d777a3448935df846" - integrity sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.0" - -hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3, hash.js@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -hasha@^5.0.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/hasha/-/hasha-5.2.2.tgz#a48477989b3b327aea3c04f53096d816d97522a1" - integrity sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ== - dependencies: - is-stream "^2.0.0" - type-fest "^0.8.0" - -he@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -header-case@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/header-case/-/header-case-1.0.1.tgz#9535973197c144b09613cd65d317ef19963bd02d" - integrity sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ== - dependencies: - no-case "^2.2.0" - upper-case "^1.1.3" - -"heap@>= 0.2.0": - version "0.2.7" - resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc" - integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== - -highlight.js@^10.4.1: - version "10.7.3" - resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" - integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== - -highlightjs-solidity@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/highlightjs-solidity/-/highlightjs-solidity-2.0.6.tgz#e7a702a2b05e0a97f185e6ba39fd4846ad23a990" - integrity sha512-DySXWfQghjm2l6a/flF+cteroJqD4gI8GSdL4PtvxZSsAHie8m3yVe2JFoRg03ROKT6hp2Lc/BxXkqerNmtQYg== - -hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - -htmlparser2@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.1.tgz#abaa985474fcefe269bc761a779b544d7196d010" - integrity sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.2" - domutils "^3.0.1" - entities "^4.3.0" - -http-basic@^8.1.1: - version "8.1.3" - resolved "https://registry.yarnpkg.com/http-basic/-/http-basic-8.1.3.tgz#a7cabee7526869b9b710136970805b1004261bbf" - integrity sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw== - dependencies: - caseless "^0.12.0" - concat-stream "^1.6.2" - http-response-object "^3.0.1" - parse-cache-control "^1.0.1" - -http-cache-semantics@^4.0.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" - integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -http-https@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/http-https/-/http-https-1.0.0.tgz#2f908dd5f1db4068c058cd6e6d4ce392c913389b" - integrity sha512-o0PWwVCSp3O0wS6FvNr6xfBCHgt0m1tvPLFOCc2iFDKTRAXhB7m8klDf7ErowFH8POa6dVdGatKU5I1YYwzUyg== - -http-response-object@^3.0.1: - version "3.0.2" - resolved "https://registry.yarnpkg.com/http-response-object/-/http-response-object-3.0.2.tgz#7f435bb210454e4360d074ef1f989d5ea8aa9810" - integrity sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA== - dependencies: - "@types/node" "^10.0.3" - -http-signature@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" - integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== - dependencies: - assert-plus "^1.0.0" - jsprim "^1.2.2" - sshpk "^1.7.0" - -http2-wrapper@^1.0.0-beta.5.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-1.0.3.tgz#b8f55e0c1f25d4ebd08b3b0c2c079f9590800b3d" - integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== - dependencies: - quick-lru "^5.1.1" - resolve-alpn "^1.0.0" - -http2-wrapper@^2.1.10: - version "2.2.0" - resolved "https://registry.yarnpkg.com/http2-wrapper/-/http2-wrapper-2.2.0.tgz#b80ad199d216b7d3680195077bd7b9060fa9d7f3" - integrity sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ== - dependencies: - quick-lru "^5.1.1" - resolve-alpn "^1.2.0" - -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -human-id@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/human-id/-/human-id-1.0.2.tgz#e654d4b2b0d8b07e45da9f6020d8af17ec0a5df3" - integrity sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw== - -iconv-lite@0.4.24, iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -idna-uts46-hx@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/idna-uts46-hx/-/idna-uts46-hx-2.3.1.tgz#a1dc5c4df37eee522bf66d969cc980e00e8711f9" - integrity sha512-PWoF9Keq6laYdIRwwCdhTPl60xRqAloYNMQLiyUnG42VjT53oW07BXIRM+NK7eQjzXjAk2gUvX9caRxlnF9TAA== - dependencies: - punycode "2.1.0" - -ieee754@^1.1.13, ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.1.1, ignore@^5.2.0, ignore@^5.2.4: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - -immutable@^4.0.0-rc.12: - version "4.2.4" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.2.4.tgz#83260d50889526b4b531a5e293709a77f7c55a2a" - integrity sha512-WDxL3Hheb1JkRN3sQkyujNlL/xRjAo3rJtaU5xeufUauG66JdMr32bLj4gF+vWl84DIA3Zxw7tiAjneYzRRw+w== - -import-fresh@^3.0.0, import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ini@^1.3.5: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -internal-slot@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" - integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== - dependencies: - get-intrinsic "^1.2.0" - has "^1.0.3" - side-channel "^1.0.4" - -interpret@^1.0.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" - integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== - -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - integrity sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ== - -invert-kv@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" - integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== - -io-ts@1.10.4: - version "1.10.4" - resolved "https://registry.yarnpkg.com/io-ts/-/io-ts-1.10.4.tgz#cd5401b138de88e4f920adbcb7026e2d1967e6e2" - integrity sha512-b23PteSnYXSONJ6JQXRAlvJhuw8KOtkqa87W4wDtvMrud/DTJd5X+NpOOI+O/zZwVq6v0VLAaJ+1EDViKEuN9g== - dependencies: - fp-ts "^1.0.0" - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -is-arguments@^1.0.4: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-array-buffer@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.1.tgz#deb1db4fcae48308d54ef2442706c0393997052a" - integrity sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-typed-array "^1.1.10" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-buffer@^2.0.5, is-buffer@~2.0.3: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-ci@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" - integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== - dependencies: - ci-info "^3.2.0" - -is-core-module@^2.11.0, is-core-module@^2.6.0, is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" - integrity sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw== - dependencies: - number-is-nan "^1.0.0" - -is-fullwidth-code-point@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" - integrity sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w== - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-function@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" - integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== - -is-generator-function@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" - integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== - dependencies: - has-tostringtag "^1.0.0" - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-hex-prefixed@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz#7d8d37e6ad77e5d127148913c573e082d777f554" - integrity sha512-WvtOiug1VFrE9v1Cydwm+FnXd3+w9GaeVUss5W4v/SLy3UW00vP+6iNF2SdnfiBoLy4bTqVdkftNGTUeOFVsbA== - -is-lower-case@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-lower-case/-/is-lower-case-1.1.3.tgz#7e147be4768dc466db3bfb21cc60b31e6ad69393" - integrity sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA== - dependencies: - lower-case "^1.1.0" - -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== - -is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-subdir@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-subdir/-/is-subdir-1.2.0.tgz#b791cd28fab5202e91a08280d51d9d7254fd20d4" - integrity sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw== - dependencies: - better-path-resolve "1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typed-array@^1.1.10, is-typed-array@^1.1.3, is-typed-array@^1.1.9: - version "1.1.10" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" - integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - -is-typedarray@^1.0.0, is-typedarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-upper-case@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-upper-case/-/is-upper-case-1.1.2.tgz#8d0b1fa7e7933a1e58483600ec7d9661cbaf756f" - integrity sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw== - dependencies: - upper-case "^1.1.0" - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== - -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -is-windows@^1.0.0, is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -isarray@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" - integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -isstream@~0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== - -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== - -istanbul-lib-hook@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz#8f84c9434888cc6b1d0a9d7092a76d239ebf0cc6" - integrity sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ== - dependencies: - append-transform "^2.0.0" - -istanbul-lib-instrument@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" - integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== - dependencies: - "@babel/core" "^7.7.5" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.0.0" - semver "^6.3.0" - -istanbul-lib-processinfo@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz#366d454cd0dcb7eb6e0e419378e60072c8626169" - integrity sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg== - dependencies: - archy "^1.0.0" - cross-spawn "^7.0.3" - istanbul-lib-coverage "^3.2.0" - p-map "^3.0.0" - rimraf "^3.0.0" - uuid "^8.3.2" - -istanbul-lib-report@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#7518fe52ea44de372f460a76b5ecda9ffb73d8a6" - integrity sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw== - dependencies: - istanbul-lib-coverage "^3.0.0" - make-dir "^3.0.0" - supports-color "^7.1.0" - -istanbul-lib-source-maps@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" - integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" - -istanbul-reports@^3.0.2: - version "3.1.5" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.5.tgz#cc9a6ab25cb25659810e4785ed9d9fb742578bae" - integrity sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w== - dependencies: - html-escaper "^2.0.0" - istanbul-lib-report "^3.0.0" - -jest-changed-files@^24.9.0: - version "24.9.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-24.9.0.tgz#08d8c15eb79a7fa3fc98269bc14b451ee82f8039" - integrity sha512-6aTWpe2mHF0DhL28WjdkO8LyGjs3zItPET4bMSeXU6T3ub4FPMw+mcOcbdGXQOAfmLcxofD23/5Bl9Z4AkFwqg== - dependencies: - "@jest/types" "^24.9.0" - execa "^1.0.0" - throat "^4.0.0" - -js-sdsl@^4.1.4: - version "4.3.0" - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.3.0.tgz#aeefe32a451f7af88425b11fdb5f58c90ae1d711" - integrity sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ== - -js-sha3@0.5.5: - version "0.5.5" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.5.tgz#baf0c0e8c54ad5903447df96ade7a4a1bca79a4a" - integrity sha512-yLLwn44IVeunwjpDVTDZmQeVbB0h+dZpY2eO68B/Zik8hu6dH+rKeLxwua79GGIvW6xr8NBAcrtiUbYrTjEFTA== - -js-sha3@0.5.7, js-sha3@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.5.7.tgz#0d4ffd8002d5333aabaf4a23eed2f6374c9f28e7" - integrity sha512-GII20kjaPX0zJ8wzkTbNDYMY7msuZcTWk8S5UOh6806Jq/wz1J8/bnr8uGU0DAUmYDjj2Mr4X1cW8v/GLYnR+g== - -js-sha3@0.8.0, js-sha3@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@3.13.1: - version "3.13.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" - integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@3.x, js-yaml@^3.13.0, js-yaml@^3.13.1, js-yaml@^3.6.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@4.1.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" - integrity sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg== - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" - integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== - -json-parse-better-errors@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" - integrity sha512-4JD/Ivzg7PoW8NzdrBSr3UFwC9mHgvI7Z6z3QGBsSHgKaRTUDmyZAAKJo2UbG1kUVfS9WS8bi36N49U1xw43DA== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json-schema@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.4.0.tgz#f7de4cf6efab838ebaeb3236474cbba5a1930ab5" - integrity sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json-stringify-safe@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - -json5@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== - dependencies: - minimist "^1.2.0" - -json5@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -jsonfile@^2.1.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-2.4.0.tgz#3736a2b428b87bbda0cc83b53fa3d633a35c2ae8" - integrity sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw== - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" - integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== - optionalDependencies: - graceful-fs "^4.1.6" - -jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonschema@^1.2.4: - version "1.4.1" - resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" - integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== - -jsprim@^1.2.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" - integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== - dependencies: - assert-plus "1.0.0" - extsprintf "1.3.0" - json-schema "0.4.0" - verror "1.10.0" - -just-extend@^4.0.2: - version "4.2.1" - resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.2.1.tgz#ef5e589afb61e5d66b24eca749409a8939a8c744" - integrity sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg== - -keccak@^3.0.0, keccak@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.3.tgz#4bc35ad917be1ef54ff246f904c2bbbf9ac61276" - integrity sha512-JZrLIAJWuZxKbCilMpNz5Vj7Vtb4scDG3dMXLOsbzBmQGyjwE61BbW7bJkfKKCShXiQZt3T6sBgALRtmd+nZaQ== - dependencies: - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - readable-stream "^3.6.0" - -keyv@^4.0.0: - version "4.5.2" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.2.tgz#0e310ce73bf7851ec702f2eaf46ec4e3805cce56" - integrity sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g== - dependencies: - json-buffer "3.0.1" - -kind-of@^6.0.2, kind-of@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -klaw@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/klaw/-/klaw-1.3.1.tgz#4088433b46b3b1ba259d78785d8e96f73ba02439" - integrity sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw== - optionalDependencies: - graceful-fs "^4.1.9" - -kleur@^4.1.4: - version "4.1.5" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" - integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== - -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw== - dependencies: - invert-kv "^1.0.0" - -lcid@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" - integrity sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA== - dependencies: - invert-kv "^2.0.0" - -level-supports@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/level-supports/-/level-supports-4.0.1.tgz#431546f9d81f10ff0fea0e74533a0e875c08c66a" - integrity sha512-PbXpve8rKeNcZ9C1mUicC9auIYFyGpkV9/i6g76tLgANwWhtG2v7I4xNBUlkn3lE2/dZF3Pi0ygYGtLc4RXXdA== - -level-transcoder@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/level-transcoder/-/level-transcoder-1.0.1.tgz#f8cef5990c4f1283d4c86d949e73631b0bc8ba9c" - integrity sha512-t7bFwFtsQeD8cl8NIoQ2iwxA0CL/9IFw7/9gAjOonH0PWTTiRfY7Hq+Ejbsxh86tXobDQ6IOiddjNYIfOBs06w== - dependencies: - buffer "^6.0.3" - module-error "^1.0.1" - -level@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/level/-/level-8.0.0.tgz#41b4c515dabe28212a3e881b61c161ffead14394" - integrity sha512-ypf0jjAk2BWI33yzEaaotpq7fkOPALKAgDBxggO6Q9HGX2MRXn0wbP1Jn/tJv1gtL867+YOjOB49WaUF3UoJNQ== - dependencies: - browser-level "^1.0.1" - classic-level "^1.2.0" - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw== - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -load-yaml-file@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/load-yaml-file/-/load-yaml-file-0.2.0.tgz#af854edaf2bea89346c07549122753c07372f64d" - integrity sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw== - dependencies: - graceful-fs "^4.1.5" - js-yaml "^3.13.0" - pify "^4.0.1" - strip-bom "^3.0.0" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.assign@^4.0.3, lodash.assign@^4.0.6: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-4.2.0.tgz#0d99f3ccd7a6d261d19bdaeb9245005d285808e7" - integrity sha512-hFuH8TY+Yji7Eja3mGiuAxBqLagejScbG8GbG0j6o9vzn0YL14My+ktnqtZgFTosKymC9/44wP6s7xyuLfnClw== - -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA== - -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== - -lodash.flattendeep@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" - integrity sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ== - -lodash.get@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" - integrity sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ== - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.startcase@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz#9436e34ed26093ed7ffae1936144350915d9add8" - integrity sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg== - -lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== - -lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.16, lodash@^4.17.19, lodash@^4.17.21, lodash@^4.17.4: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - -log-symbols@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-3.0.0.tgz#f3a08516a5dea893336a7dee14d18a1cfdab77c4" - integrity sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ== - dependencies: - chalk "^2.4.2" - -log-symbols@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -loupe@^2.3.1: - version "2.3.6" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.6.tgz#76e4af498103c532d1ecc9be102036a21f787b53" - integrity sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA== - dependencies: - get-func-name "^2.0.0" - -lower-case-first@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/lower-case-first/-/lower-case-first-1.0.2.tgz#e5da7c26f29a7073be02d52bac9980e5922adfa1" - integrity sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA== - dependencies: - lower-case "^1.1.2" - -lower-case@^1.1.0, lower-case@^1.1.1, lower-case@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" - integrity sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA== - -lowercase-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479" - integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== - -lowercase-keys@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-3.0.0.tgz#c5e7d442e37ead247ae9db117a9d0a467c89d4f2" - integrity sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ== - -lru-cache@^4.0.1: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -lru_map@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" - integrity sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ== - -make-dir@^3.0.0, make-dir@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -map-age-cleaner@^0.1.1: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - -map-obj@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg== - -map-obj@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" - integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== - -markdown-table@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.3.tgz#9fcb69bcfdb8717bfd0398c6ec2d93036ef8de60" - integrity sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q== - -mcl-wasm@^0.7.1: - version "0.7.9" - resolved "https://registry.yarnpkg.com/mcl-wasm/-/mcl-wasm-0.7.9.tgz#c1588ce90042a8700c3b60e40efb339fc07ab87f" - integrity sha512-iJIUcQWA88IJB/5L15GnJVnSQJmf/YaxxV6zRavv83HILHaJQb6y0iFyDMdDO0gN8X37tdxmAOrH/P8B6RB8sQ== - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - -mem@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" - integrity sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w== - dependencies: - map-age-cleaner "^0.1.1" - mimic-fn "^2.0.0" - p-is-promise "^2.0.0" - -memory-level@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/memory-level/-/memory-level-1.0.0.tgz#7323c3fd368f9af2f71c3cd76ba403a17ac41692" - integrity sha512-UXzwewuWeHBz5krr7EvehKcmLFNoXxGcvuYhC41tRnkrTbJohtS7kVn9akmgirtRygg+f7Yjsfi8Uu5SGSQ4Og== - dependencies: - abstract-level "^1.0.0" - functional-red-black-tree "^1.0.1" - module-error "^1.0.1" - -memorystream@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== - -meow@^6.0.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/meow/-/meow-6.1.1.tgz#1ad64c4b76b2a24dfb2f635fddcadf320d251467" - integrity sha512-3YffViIt2QWgTy6Pale5QpopX/IvU3LPL03jOTqp6pGj3VjesdO/U8CuHMKpnQr4shCNCM5fd5XFFvIIl6JBHg== - dependencies: - "@types/minimist" "^1.2.0" - camelcase-keys "^6.2.2" - decamelize-keys "^1.1.0" - hard-rejection "^2.1.0" - minimist-options "^4.0.2" - normalize-package-data "^2.5.0" - read-pkg-up "^7.0.1" - redent "^3.0.0" - trim-newlines "^3.0.0" - type-fest "^0.13.1" - yargs-parser "^18.1.3" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== - -merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - -micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.12, mime-types@^2.1.16, mime-types@~2.1.19, mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mimic-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mimic-response@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" - integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== - -mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" - integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== - -min-document@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" - integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ== - dependencies: - dom-walk "^0.1.0" - -min-indent@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" - integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== - -"minimatch@2 || 3", minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== - dependencies: - brace-expansion "^1.1.7" - -minimatch@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^5.0.1: - version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== - dependencies: - brace-expansion "^2.0.1" - -minimist-options@^4.0.2: - version "4.1.0" - resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" - integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== - dependencies: - arrify "^1.0.1" - is-plain-obj "^1.1.0" - kind-of "^6.0.3" - -minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -minipass@^2.6.0, minipass@^2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.9.0.tgz#e713762e7d3e32fed803115cf93e04bca9fcc9a6" - integrity sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg== - dependencies: - safe-buffer "^5.1.2" - yallist "^3.0.0" - -minizlib@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" - integrity sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q== - dependencies: - minipass "^2.9.0" - -mixme@^0.5.1: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mixme/-/mixme-0.5.5.tgz#bf8f67d8caf10fdb49fd23198fd1fa6d8e406627" - integrity sha512-/6IupbRx32s7jjEwHcycXikJwFD5UujbVNuJFkeKLYje+92OvtuPniF6JhnFm5JCTDUhS+kYK3W/4BWYQYXz7w== - -mkdirp-promise@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz#e9b8f68e552c68a9c1713b84883f7a1dd039b8a1" - integrity sha512-Hepn5kb1lJPtVW84RFT40YG1OddBNTOVUZR2bzQUHc+Z03en8/3uX0+060JDhcEzyO08HmipsN9DcnFMxhIL9w== - dependencies: - mkdirp "*" - -mkdirp@*: - version "2.1.3" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.3.tgz#b083ff37be046fd3d6552468c1f0ff44c1545d1f" - integrity sha512-sjAkg21peAG9HS+Dkx7hlG9Ztx7HLeKnvB3NQRcu/mltCVmvkF0pisbiTSfDVYTT86XEfZrTUosLdZLStquZUw== - -mkdirp@0.5.5: - version "0.5.5" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" - integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== - dependencies: - minimist "^1.2.5" - -mkdirp@0.5.x, mkdirp@^0.5.5: - version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== - dependencies: - minimist "^1.2.6" - -mkdirp@^1.0.3, mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -mnemonist@^0.38.0: - version "0.38.5" - resolved "https://registry.yarnpkg.com/mnemonist/-/mnemonist-0.38.5.tgz#4adc7f4200491237fe0fa689ac0b86539685cade" - integrity sha512-bZTFT5rrPKtPJxj8KSV0WkPyNxl72vQepqqVUAW2ARUpUSF2qXMB6jZj7hW5/k7C1rtpzqbD/IIbJwLXUjCHeg== - dependencies: - obliterator "^2.0.0" - -mocha@7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.1.2.tgz#8e40d198acf91a52ace122cd7599c9ab857b29e6" - integrity sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA== - dependencies: - ansi-colors "3.2.3" - browser-stdout "1.3.1" - chokidar "3.3.0" - debug "3.2.6" - diff "3.5.0" - escape-string-regexp "1.0.5" - find-up "3.0.0" - glob "7.1.3" - growl "1.10.5" - he "1.2.0" - js-yaml "3.13.1" - log-symbols "3.0.0" - minimatch "3.0.4" - mkdirp "0.5.5" - ms "2.1.1" - node-environment-flags "1.0.6" - object.assign "4.1.0" - strip-json-comments "2.0.1" - supports-color "6.0.0" - which "1.3.1" - wide-align "1.1.3" - yargs "13.3.2" - yargs-parser "13.1.2" - yargs-unparser "1.6.0" - -mocha@^10.0.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" - integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== - dependencies: - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - nanoid "3.3.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - -mocha@^7.1.1: - version "7.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.2.0.tgz#01cc227b00d875ab1eed03a75106689cfed5a604" - integrity sha512-O9CIypScywTVpNaRrCAgoUnJgozpIofjKUYmJhiCIJMiuYnLI6otcb1/kpW9/n/tJODHGZ7i8aLQoDVsMtOKQQ== - dependencies: - ansi-colors "3.2.3" - browser-stdout "1.3.1" - chokidar "3.3.0" - debug "3.2.6" - diff "3.5.0" - escape-string-regexp "1.0.5" - find-up "3.0.0" - glob "7.1.3" - growl "1.10.5" - he "1.2.0" - js-yaml "3.13.1" - log-symbols "3.0.0" - minimatch "3.0.4" - mkdirp "0.5.5" - ms "2.1.1" - node-environment-flags "1.0.6" - object.assign "4.1.0" - strip-json-comments "2.0.1" - supports-color "6.0.0" - which "1.3.1" - wide-align "1.1.3" - yargs "13.3.2" - yargs-parser "13.1.2" - yargs-unparser "1.6.0" - -mock-fs@^4.1.0: - version "4.14.0" - resolved "https://registry.yarnpkg.com/mock-fs/-/mock-fs-4.14.0.tgz#ce5124d2c601421255985e6e94da80a7357b1b18" - integrity sha512-qYvlv/exQ4+svI3UOvPUpLDF0OMX5euvUH0Ny4N5QyRyhNdgAgUrVH3iUINSzEPLvx0kbo/Bp28GJKIqvE7URw== - -module-error@^1.0.1, module-error@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/module-error/-/module-error-1.0.2.tgz#8d1a48897ca883f47a45816d4fb3e3c6ba404d86" - integrity sha512-0yuvsqSCv8LbaOKhnsQ/T5JhyFlCYLPXK3U2sgV10zoKQwzs/MyfuQUOZQ1V/6OCOJsK/TRgNVrPuPDqtdMFtA== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -multibase@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.7.0.tgz#1adfc1c50abe05eefeb5091ac0c2728d6b84581b" - integrity sha512-TW8q03O0f6PNFTQDvh3xxH03c8CjGaaYrjkl9UQPG6rz53TQzzxJVCIWVjzcbN/Q5Y53Zd0IBQBMVktVgNx4Fg== - dependencies: - base-x "^3.0.8" - buffer "^5.5.0" - -multibase@~0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/multibase/-/multibase-0.6.1.tgz#b76df6298536cc17b9f6a6db53ec88f85f8cc12b" - integrity sha512-pFfAwyTjbbQgNc3G7D48JkJxWtoJoBMaR4xQUOuB8RnCgRqaYmWNFeJTTvrJ2w51bjLq2zTby6Rqj9TQ9elSUw== - dependencies: - base-x "^3.0.8" - buffer "^5.5.0" - -multicodec@^0.5.5: - version "0.5.7" - resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-0.5.7.tgz#1fb3f9dd866a10a55d226e194abba2dcc1ee9ffd" - integrity sha512-PscoRxm3f+88fAtELwUnZxGDkduE2HD9Q6GHUOywQLjOGT/HAdhjLDYNZ1e7VR0s0TP0EwZ16LNUTFpoBGivOA== - dependencies: - varint "^5.0.0" - -multicodec@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/multicodec/-/multicodec-1.0.4.tgz#46ac064657c40380c28367c90304d8ed175a714f" - integrity sha512-NDd7FeS3QamVtbgfvu5h7fd1IlbaC4EQ0/pgU4zqE2vdHCmBGsUa0TiM8/TdSeG6BMPC92OOCf8F1ocE/Wkrrg== - dependencies: - buffer "^5.6.0" - varint "^5.0.0" - -multihashes@^0.4.15, multihashes@~0.4.15: - version "0.4.21" - resolved "https://registry.yarnpkg.com/multihashes/-/multihashes-0.4.21.tgz#dc02d525579f334a7909ade8a122dabb58ccfcb5" - integrity sha512-uVSvmeCWf36pU2nB4/1kzYZjsXD9vofZKpgudqkceYY5g2aZZXJ5r9lxuzoRLl1OAp28XljXsEJ/X/85ZsKmKw== - dependencies: - buffer "^5.5.0" - multibase "^0.7.0" - varint "^5.0.0" - -mz@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" - integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== - dependencies: - any-promise "^1.0.0" - object-assign "^4.0.1" - thenify-all "^1.0.0" - -nano-base32@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/nano-base32/-/nano-base32-1.0.1.tgz#ba548c879efcfb90da1c4d9e097db4a46c9255ef" - integrity sha512-sxEtoTqAPdjWVGv71Q17koMFGsOMSiHsIFEvzOM7cNp8BXB4AnEwmDabm5dorusJf/v1z7QxaZYxUorU9RKaAw== - -nano-json-stream-parser@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/nano-json-stream-parser/-/nano-json-stream-parser-0.1.2.tgz#0cc8f6d0e2b622b479c40d499c46d64b755c6f5f" - integrity sha512-9MqxMH/BSJC7dnLsEMPyfN5Dvoo49IsPFYMcHw3Bcfc2kN0lpHRBSzlMSVx4HGyJ7s9B31CyBTVehWJoQ8Ctew== - -nanoid@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" - integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== - -napi-macros@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/napi-macros/-/napi-macros-2.0.0.tgz#2b6bae421e7b96eb687aa6c77a7858640670001b" - integrity sha512-A0xLykHtARfueITVDernsAWdtIMbOJgKgcluwENp3AlsKN/PloyO10HtmoqnFAQAcxPkgZN7wdfPfEd0zNGxbg== - -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -neo-async@^2.6.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -next-tick@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" - integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -nise@^4.0.4: - version "4.1.0" - resolved "https://registry.yarnpkg.com/nise/-/nise-4.1.0.tgz#8fb75a26e90b99202fa1e63f448f58efbcdedaf6" - integrity sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA== - dependencies: - "@sinonjs/commons" "^1.7.0" - "@sinonjs/fake-timers" "^6.0.0" - "@sinonjs/text-encoding" "^0.7.1" - just-extend "^4.0.2" - path-to-regexp "^1.7.0" - -no-case@^2.2.0, no-case@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" - integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== - dependencies: - lower-case "^1.1.1" - -node-addon-api@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" - integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== - -node-emoji@^1.10.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" - integrity sha512-wo2DpQkQp7Sjm2A0cq+sN7EHKO6Sl0ctXeBdFZrL9T9+UywORbufTcTZxom8YqpLQt/FqNMUkOpkZrJVYSKD3A== - dependencies: - lodash "^4.17.21" - -node-environment-flags@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/node-environment-flags/-/node-environment-flags-1.0.6.tgz#a30ac13621f6f7d674260a54dede048c3982c088" - integrity sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw== - dependencies: - object.getownpropertydescriptors "^2.0.3" - semver "^5.7.0" - -node-fetch@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -node-gyp-build@^4.2.0, node-gyp-build@^4.3.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" - integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== - -node-preload@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/node-preload/-/node-preload-0.2.1.tgz#c03043bb327f417a18fee7ab7ee57b408a144301" - integrity sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ== - dependencies: - process-on-spawn "^1.0.0" - -node-releases@^2.0.8: - version "2.0.10" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" - integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== - -nofilter@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-1.0.4.tgz#78d6f4b6a613e7ced8b015cec534625f7667006e" - integrity sha512-N8lidFp+fCz+TD51+haYdbDGrcBWwuHX40F5+z0qkUjMJ5Tp+rdSuAkMJ9N9eoolDlEVTf6u5icM+cNKkKW2mA== - -nofilter@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/nofilter/-/nofilter-3.1.0.tgz#c757ba68801d41ff930ba2ec55bab52ca184aa66" - integrity sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g== - -nopt@3.x: - version "3.0.6" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" - integrity sha512-4GUt3kSEYmk4ITxzB/b9vaIDfUVWN/Ml1Fwl11IlnIG2iaJ9O6WXZ9SrYM9NLI8OCBieN2Y8SWC2oJV0RQ7qYg== - dependencies: - abbrev "1" - -normalize-package-data@^2.3.2, normalize-package-data@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== - dependencies: - path-key "^2.0.0" - -nth-check@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" - integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== - dependencies: - boolbase "^1.0.0" - -number-is-nan@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" - integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== - -number-to-bn@1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/number-to-bn/-/number-to-bn-1.7.0.tgz#bb3623592f7e5f9e0030b1977bd41a0c53fe1ea0" - integrity sha512-wsJ9gfSz1/s4ZsJN01lyonwuxA1tml6X1yBDnfpMglypcBRFZZkus26EdPSlqS5GJfYddVZa22p3VNb3z5m5Ig== - dependencies: - bn.js "4.11.6" - strip-hex-prefix "1.0.0" - -nyc@^15.1.0: - version "15.1.0" - resolved "https://registry.yarnpkg.com/nyc/-/nyc-15.1.0.tgz#1335dae12ddc87b6e249d5a1994ca4bdaea75f02" - integrity sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A== - dependencies: - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.2" - caching-transform "^4.0.0" - convert-source-map "^1.7.0" - decamelize "^1.2.0" - find-cache-dir "^3.2.0" - find-up "^4.1.0" - foreground-child "^2.0.0" - get-package-type "^0.1.0" - glob "^7.1.6" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-hook "^3.0.0" - istanbul-lib-instrument "^4.0.0" - istanbul-lib-processinfo "^2.0.2" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.0.2" - make-dir "^3.0.0" - node-preload "^0.2.1" - p-map "^3.0.0" - process-on-spawn "^1.0.0" - resolve-from "^5.0.0" - rimraf "^3.0.0" - signal-exit "^3.0.2" - spawn-wrap "^2.0.0" - test-exclude "^6.0.0" - yargs "^15.0.2" - -oauth-sign@~0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" - integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== - -object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-inspect@^1.12.2, object-inspect@^1.9.0: - version "1.12.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== - -object-keys@^1.0.11, object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.0.tgz#968bf1100d7956bb3ca086f006f846b3bc4008da" - integrity sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w== - dependencies: - define-properties "^1.1.2" - function-bind "^1.1.1" - has-symbols "^1.0.0" - object-keys "^1.0.11" - -object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -object.getownpropertydescriptors@^2.0.3: - version "2.1.5" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.5.tgz#db5a9002489b64eef903df81d6623c07e5b4b4d3" - integrity sha512-yDNzckpM6ntyQiGTik1fKV1DcVDRS+w8bvpWNCBanvH5LfRX9O8WTHqQzG4RZwRAM4I0oU7TV11Lj5v0g20ibw== - dependencies: - array.prototype.reduce "^1.0.5" - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -object.values@^1.1.4: - version "1.1.6" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" - integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -obliterator@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.4.tgz#fa650e019b2d075d745e44f1effeb13a2adbe816" - integrity sha512-lgHwxlxV1qIg1Eap7LgIeoBWIMFibOjbrYPIPJZcI1mmGAI2m3lNYpK12Y+GBdPQ0U1hRwSord7GIaawz962qQ== - -oboe@2.1.5: - version "2.1.5" - resolved "https://registry.yarnpkg.com/oboe/-/oboe-2.1.5.tgz#5554284c543a2266d7a38f17e073821fbde393cd" - integrity sha512-zRFWiF+FoicxEs3jNI/WYUrVEgA7DeET/InK0XQuudGHRg8iIob3cNPrJTKaz4004uaA9Pbe+Dwa8iluhjLZWA== - dependencies: - http-https "^1.0.0" - -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - -once@1.x, once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.3" - -ordinal@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/ordinal/-/ordinal-1.0.3.tgz#1a3c7726a61728112f50944ad7c35c06ae3a0d4d" - integrity sha512-cMddMgb2QElm8G7vdaa02jhUNbTSrhsgAGUz1OokD83uJTwSUn+nKoNoKVVaRa08yF6sgfO7Maou1+bgLd9rdQ== - -os-locale@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" - integrity sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g== - dependencies: - lcid "^1.0.0" - -os-locale@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" - integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== - dependencies: - execa "^1.0.0" - lcid "^2.0.0" - mem "^4.0.0" - -os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== - -outdent@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/outdent/-/outdent-0.5.0.tgz#9e10982fdc41492bb473ad13840d22f9655be2ff" - integrity sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q== - -p-cancelable@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf" - integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== - -p-cancelable@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-3.0.0.tgz#63826694b54d61ca1c20ebcb6d3ecf5e14cd8050" - integrity sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw== - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw== - -p-filter@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-2.1.0.tgz#1b1472562ae7a0f742f0f3d3d3718ea66ff9c09c" - integrity sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw== - dependencies: - p-map "^2.0.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== - -p-is-promise@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-2.1.0.tgz#918cebaea248a62cf7ffab8e3bca8c5f882fc42e" - integrity sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg== - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0, p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-map@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" - integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== - -p-map@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" - integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== - dependencies: - aggregate-error "^3.0.0" - -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -package-hash@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/package-hash/-/package-hash-4.0.0.tgz#3537f654665ec3cc38827387fc904c163c54f506" - integrity sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ== - dependencies: - graceful-fs "^4.1.15" - hasha "^5.0.0" - lodash.flattendeep "^4.4.0" - release-zalgo "^1.0.0" - -pako@^1.0.4: - version "1.0.11" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" - integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== - -param-case@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-2.1.1.tgz#df94fd8cf6531ecf75e6bef9a0858fbc72be2247" - integrity sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w== - dependencies: - no-case "^2.2.0" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-cache-control@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parse-cache-control/-/parse-cache-control-1.0.1.tgz#8eeab3e54fa56920fe16ba38f77fa21aacc2d74e" - integrity sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg== - -parse-headers@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9" - integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA== - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== - dependencies: - error-ex "^1.2.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-json@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -parse-ms@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/parse-ms/-/parse-ms-0.1.2.tgz#dd3fa25ed6c2efc7bdde12ad9b46c163aa29224e" - integrity sha512-VwMglE9412ifMHcRFEVJePEpreQh90wjIiOdP0UQQGKV4l+QprdKI+p5noXTkmGjznBMb40s+VymcclATAVvYA== - -parse5-htmlparser2-tree-adapter@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1" - integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g== - dependencies: - domhandler "^5.0.2" - parse5 "^7.0.0" - -parse5@^7.0.0: - version "7.1.2" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" - integrity sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw== - dependencies: - entities "^4.4.0" - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -pascal-case@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-2.0.1.tgz#2d578d3455f660da65eca18ef95b4e0de912761e" - integrity sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ== - dependencies: - camel-case "^3.0.0" - upper-case-first "^1.1.0" - -path-case@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/path-case/-/path-case-2.1.1.tgz#94b8037c372d3fe2906e465bb45e25d226e8eea5" - integrity sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q== - dependencies: - no-case "^2.2.0" - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== - -path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.6, path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== - -path-to-regexp@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== - dependencies: - isarray "0.0.1" - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -pathval@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" - integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== - -pbkdf2@^3.0.17: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" - integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -performance-now@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" - integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pify@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== - -pkg-dir@^4.1.0, pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha512-fjAPuiws93rm7mPUu21RdBnkeZNrbfCFCwfAhPWY+rR3zG0ubpe5cEReHOw5fIbfmsxEV/g2kSxGTATY3Bpnwg== - dependencies: - find-up "^2.1.0" - -pluralize@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-8.0.0.tgz#1a6fa16a38d12a1901e0320fa017051c539ce3b1" - integrity sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA== - -preferred-pm@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/preferred-pm/-/preferred-pm-3.0.3.tgz#1b6338000371e3edbce52ef2e4f65eb2e73586d6" - integrity sha512-+wZgbxNES/KlJs9q40F/1sfOd/j7f1O9JaHcW5Dsn3aUUOZg3L2bjpVUcKV2jvtElYfoTuQiNeMfQJ4kwUAhCQ== - dependencies: - find-up "^5.0.0" - find-yarn-workspace-root2 "1.2.16" - path-exists "^4.0.0" - which-pm "2.0.0" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== - -prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== - dependencies: - fast-diff "^1.1.2" - -prettier@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.1.tgz#671e11c89c14a4cfc876ce564106c4a6726c9f5c" - integrity sha512-9fbDAXSBcc6Bs1mZrDYb3XKzDLm4EXXL9sC1LqKP5rZkT6KRr/rf9amVUcODVXgguK/isJz0d0hP72WeaKWsvA== - -prettier@^2.3.1, prettier@^2.7.1, prettier@^2.8.3: - version "2.8.4" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.4.tgz#34dd2595629bfbb79d344ac4a91ff948694463c3" - integrity sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw== - -pretty-ms@^0.2.1: - version "0.2.2" - resolved "https://registry.yarnpkg.com/pretty-ms/-/pretty-ms-0.2.2.tgz#da879a682ff33a37011046f13d627f67c73b84f6" - integrity sha512-ah/vWDJAT0arxQwVcSGp6etaLTZr4IsrXTy/khfjimzdYgSxYWzTMByrtpJUWinAnVY8szDg+qQhsE5MUMz3lQ== - dependencies: - parse-ms "^0.1.0" - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -process-on-spawn@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/process-on-spawn/-/process-on-spawn-1.0.0.tgz#95b05a23073d30a17acfdc92a440efd2baefdc93" - integrity sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg== - dependencies: - fromentries "^1.2.0" - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== - -progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - -promise@^8.0.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/promise/-/promise-8.3.0.tgz#8cb333d1edeb61ef23869fbb8a4ea0279ab60e0a" - integrity sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg== - dependencies: - asap "~2.0.6" - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== - -psl@^1.1.28: - version "1.9.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" - integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== - -pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -punycode@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.0.tgz#5f863edc89b96db09074bad7947bf09056ca4e7d" - integrity sha512-Yxz2kRwT90aPiWEMHVYnEf4+rhwF1tBmmZ4KepCP+Wkium9JxtWnUm1nqGwpiAHr/tnTSeHqr3wb++jgSkXjhA== - -punycode@^2.1.0, punycode@^2.1.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -pure-rand@^5.0.1: - version "5.0.5" - resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-5.0.5.tgz#bda2a7f6a1fc0f284d78d78ca5902f26f2ad35cf" - integrity sha512-BwQpbqxSCBJVpamI6ydzcKqyFmnd5msMWUGvzXLm1aXvusbbgkbOto/EUPM00hjveJEaJtdbhUjKSzWRhQVkaw== - -qs@6.11.0, qs@^6.4.0, qs@^6.7.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== - dependencies: - side-channel "^1.0.4" - -qs@~6.5.2: - version "6.5.3" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.3.tgz#3aeeffc91967ef6e35c0e488ef46fb296ab76aad" - integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== - -query-string@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" - integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== - dependencies: - decode-uri-component "^0.2.0" - object-assign "^4.1.0" - strict-uri-encode "^1.0.0" - -queue-microtask@^1.2.2, queue-microtask@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -quick-lru@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" - integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== - -quick-lru@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932" - integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.5.1, raw-body@^2.4.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw== - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg-up@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" - integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== - dependencies: - find-up "^4.1.0" - read-pkg "^5.2.0" - type-fest "^0.8.1" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA== - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - -read-pkg@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" - integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== - dependencies: - "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^2.5.0" - parse-json "^5.0.0" - type-fest "^0.6.0" - -read-yaml-file@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-yaml-file/-/read-yaml-file-1.1.0.tgz#9362bbcbdc77007cc8ea4519fe1c0b821a7ce0d8" - integrity sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA== - dependencies: - graceful-fs "^4.1.5" - js-yaml "^3.6.1" - pify "^4.0.1" - strip-bom "^3.0.0" - -readable-stream@^2.2.2: - version "2.3.7" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" - integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" - integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.2.0.tgz#c30c33352b12c96dfb4b895421a49fd5a9593839" - integrity sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ== - dependencies: - picomatch "^2.0.4" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -rechoir@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" - integrity sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw== - dependencies: - resolve "^1.1.6" - -recursive-readdir@^2.2.2: - version "2.2.3" - resolved "https://registry.yarnpkg.com/recursive-readdir/-/recursive-readdir-2.2.3.tgz#e726f328c0d69153bcabd5c322d3195252379372" - integrity sha512-8HrF5ZsXk5FAH9dgsx3BlUer73nIhuj+9OrQwEbLTPOBzGkL1lsFCR01am+v+0m2Cmbs1nP12hLDl5FA7EszKA== - dependencies: - minimatch "^3.0.5" - -redent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" - integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== - dependencies: - indent-string "^4.0.0" - strip-indent "^3.0.0" - -reduce-flatten@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/reduce-flatten/-/reduce-flatten-2.0.0.tgz#734fd84e65f375d7ca4465c69798c25c9d10ae27" - integrity sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w== - -regenerator-runtime@^0.13.11: - version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - -regexp.prototype.flags@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" - integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - functions-have-names "^1.2.2" - -regexpp@^3.1.0, regexpp@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - -release-zalgo@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/release-zalgo/-/release-zalgo-1.0.0.tgz#09700b7e5074329739330e535c5a90fb67851730" - integrity sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA== - dependencies: - es6-error "^4.0.1" - -req-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/req-cwd/-/req-cwd-2.0.0.tgz#d4082b4d44598036640fb73ddea01ed53db49ebc" - integrity sha512-ueoIoLo1OfB6b05COxAA9UpeoscNpYyM+BqYlA7H6LVF4hKGPXQQSSaD2YmvDVJMkk4UDpAHIeU1zG53IqjvlQ== - dependencies: - req-from "^2.0.0" - -req-from@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/req-from/-/req-from-2.0.0.tgz#d74188e47f93796f4aa71df6ee35ae689f3e0e70" - integrity sha512-LzTfEVDVQHBRfjOUMgNBA+V6DWsSnoeKzf42J7l0xa/B4jyPOuuF5MlNSmomLNGemWTnV2TIdjSSLnEn95fOQA== - dependencies: - resolve-from "^3.0.0" - -request-promise-core@1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.4.tgz#3eedd4223208d419867b78ce815167d10593a22f" - integrity sha512-TTbAfBBRdWD7aNNOoVOBH4pN/KigV6LyapYNNlAPA8JwbovRti1E88m3sYAwsLi5ryhPKsE9APwnjFTgdUjTpw== - dependencies: - lodash "^4.17.19" - -request-promise-native@^1.0.5: - version "1.0.9" - resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.9.tgz#e407120526a5efdc9a39b28a5679bf47b9d9dc28" - integrity sha512-wcW+sIUiWnKgNY0dqCpOZkUbF/I+YPi+f09JZIDa39Ec+q82CpSYniDp+ISgTTbKmnpJWASeJBPZmoxH84wt3g== - dependencies: - request-promise-core "1.1.4" - stealthy-require "^1.1.1" - tough-cookie "^2.3.3" - -request@^2.79.0, request@^2.88.0: - version "2.88.2" - resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" - integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== - dependencies: - aws-sign2 "~0.7.0" - aws4 "^1.8.0" - caseless "~0.12.0" - combined-stream "~1.0.6" - extend "~3.0.2" - forever-agent "~0.6.1" - form-data "~2.3.2" - har-validator "~5.1.3" - http-signature "~1.2.0" - is-typedarray "~1.0.0" - isstream "~0.1.2" - json-stringify-safe "~5.0.1" - mime-types "~2.1.19" - oauth-sign "~0.9.0" - performance-now "^2.1.0" - qs "~6.5.2" - safe-buffer "^5.1.2" - tough-cookie "~2.5.0" - tunnel-agent "^0.6.0" - uuid "^3.3.2" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -require-from-string@^1.1.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-1.2.1.tgz#529c9ccef27380adfec9a2f965b649bbee636418" - integrity sha512-H7AkJWMobeskkttHyhTVtS0fxpFLjxhbfMa6Bk3wimP7sdPRGL3EyCg3sAQenFfAe+xQ+oAc85Nmtvq0ROM83Q== - -require-from-string@^2.0.0, require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -require-main-filename@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" - integrity sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug== - -require-main-filename@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" - integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== - -resolve-alpn@^1.0.0, resolve-alpn@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/resolve-alpn/-/resolve-alpn-1.2.1.tgz#b7adbdac3546aaaec20b45e7d8265927072726f9" - integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve@1.1.x: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg== - -resolve@1.17.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" - integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== - dependencies: - path-parse "^1.0.6" - -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.20.0, resolve@^1.22.1: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -responselike@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.1.tgz#9a0bc8fdc252f3fb1cca68b016591059ba1422bc" - integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== - dependencies: - lowercase-keys "^2.0.0" - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^2.2.8: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -rimraf@^3.0.0, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -ripemd160-min@0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/ripemd160-min/-/ripemd160-min-0.0.6.tgz#a904b77658114474d02503e819dcc55853b67e62" - integrity sha512-+GcJgQivhs6S9qvLogusiTcS9kQUfgR75whKuy5jIhuiOfQuJ8fjqxV6EGD5duH1Y/FawFUMtMhyeq3Fbnib8A== - -ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - -rlp@^2.2.3, rlp@^2.2.4: - version "2.2.7" - resolved "https://registry.yarnpkg.com/rlp/-/rlp-2.2.7.tgz#33f31c4afac81124ac4b283e2bd4d9720b30beaf" - integrity sha512-d5gdPmgQ0Z+AklL2NVXr/IoSjNZFfTVvQWzL/AM2AOcSzYP2xjlb0AC8YyCLc41MSNf6P6QVtjgPdmVtzb+4lQ== - dependencies: - bn.js "^5.2.0" - -run-parallel-limit@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz#be80e936f5768623a38a963262d6bef8ff11e7ba" - integrity sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw== - dependencies: - queue-microtask "^1.2.2" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -rustbn.js@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/rustbn.js/-/rustbn.js-0.2.0.tgz#8082cb886e707155fd1cb6f23bd591ab8d55d0ca" - integrity sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA== - -safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-regex "^1.1.4" - -"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2, safer-buffer@^2.1.0, safer-buffer@~2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sc-istanbul@^0.4.5: - version "0.4.6" - resolved "https://registry.yarnpkg.com/sc-istanbul/-/sc-istanbul-0.4.6.tgz#cf6784355ff2076f92d70d59047d71c13703e839" - integrity sha512-qJFF/8tW/zJsbyfh/iT/ZM5QNHE3CXxtLJbZsL+CzdJLBsPD7SedJZoUA4d8iAcN2IoMp/Dx80shOOd2x96X/g== - dependencies: - abbrev "1.0.x" - async "1.x" - escodegen "1.8.x" - esprima "2.7.x" - glob "^5.0.15" - handlebars "^4.0.1" - js-yaml "3.x" - mkdirp "0.5.x" - nopt "3.x" - once "1.x" - resolve "1.1.x" - supports-color "^3.1.0" - which "^1.1.1" - wordwrap "^1.0.0" - -scrypt-js@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-2.0.4.tgz#32f8c5149f0797672e551c07e230f834b6af5f16" - integrity sha512-4KsaGcPnuhtCZQCxFxN3GVYIhKFPTdLd8PLC552XwbMndtD0cjRFAhDuuydXQ0h08ZfPgzqe6EKHozpuH74iDw== - -scrypt-js@3.0.1, scrypt-js@^3.0.0, scrypt-js@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/scrypt-js/-/scrypt-js-3.0.1.tgz#d314a57c2aef69d1ad98a138a21fe9eafa9ee312" - integrity sha512-cdwTTnqPu0Hyvf5in5asVdZocVDTNRmR7XEcJuIzMjJeSHybHl7vpB66AzwTaIg6CLSbtjcxc8fqcySfnTkccA== - -secp256k1@^4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/secp256k1/-/secp256k1-4.0.3.tgz#c4559ecd1b8d3c1827ed2d1b94190d69ce267303" - integrity sha512-NLZVf+ROMxwtEj3Xa562qgv2BK5e2WNmXPiOdVIPLgs6lyTzMvBq0aWTYMI5XCP9jZMVKOcqZLw/Wc4vDkuxhA== - dependencies: - elliptic "^6.5.4" - node-addon-api "^2.0.0" - node-gyp-build "^4.2.0" - -"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - -semver@7.3.7: - version "7.3.7" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" - integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== - dependencies: - lru-cache "^6.0.0" - -semver@^6.0.0, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^7.2.1, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7: - version "7.3.8" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" - integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== - dependencies: - lru-cache "^6.0.0" - -send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" - -sentence-case@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/sentence-case/-/sentence-case-2.1.1.tgz#1f6e2dda39c168bf92d13f86d4a918933f667ed4" - integrity sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ== - dependencies: - no-case "^2.2.0" - upper-case-first "^1.1.2" - -serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.18.0" - -servify@^0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/servify/-/servify-0.1.12.tgz#142ab7bee1f1d033b66d0707086085b17c06db95" - integrity sha512-/xE6GvsKKqyo1BAY+KxOWXcLpPsUUyji7Qg3bVD7hh1eRze5bR1uYiuDA/k3Gof1s9BTzQZEJK8sNcNGFIzeWw== - dependencies: - body-parser "^1.16.0" - cors "^2.8.1" - express "^4.14.0" - request "^2.79.0" - xhr "^2.3.3" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - -setimmediate@1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.4.tgz#20e81de622d4a02588ce0c8da8973cbcf1d3138f" - integrity sha512-/TjEmXQVEzdod/FFskf3o7oOAsGhHf2j1dZqRFbDzq4F3mvvxflIIi4Hd3bLQE9y/CpwqfSQam5JakI/mi3Pog== - -setimmediate@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -sha.js@^2.4.0, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - -sha1@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/sha1/-/sha1-1.1.1.tgz#addaa7a93168f393f19eb2b15091618e2700f848" - integrity sha512-dZBS6OrMjtgVkopB1Gmo4RQCDKiZsqcpAQpkV/aaj+FCrCg8r4I4qMkDPQjBgLIxlmu9k4nUbWq6ohXahOneYA== - dependencies: - charenc ">= 0.0.1" - crypt ">= 0.0.1" - -sha3@^2.1.1: - version "2.1.4" - resolved "https://registry.yarnpkg.com/sha3/-/sha3-2.1.4.tgz#000fac0fe7c2feac1f48a25e7a31b52a6492cc8f" - integrity sha512-S8cNxbyb0UGUM2VhRD4Poe5N58gJnJsLJ5vC7FYWGUmGhcsj4++WaIOBFVDxlG0W3To6xBuiRh+i0Qp2oNCOtg== - dependencies: - buffer "6.0.3" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== - dependencies: - shebang-regex "^1.0.0" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shelljs@^0.8.3, shelljs@^0.8.5: - version "0.8.5" - resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.5.tgz#de055408d8361bed66c669d2f000538ced8ee20c" - integrity sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow== - dependencies: - glob "^7.0.0" - interpret "^1.0.0" - rechoir "^0.6.2" - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^2.7.0: - version "2.8.2" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-2.8.2.tgz#5708fb0919d440657326cd5fe7d2599d07705019" - integrity sha512-Ijd/rV5o+mSBBs4F/x9oDPtTx9Zb6X9brmnXvMW4J7IR15ngi9q5xxqWBKU744jTZiaXtxaPL7uHG6vtN8kUkw== - dependencies: - decompress-response "^3.3.0" - once "^1.3.1" - simple-concat "^1.0.0" - -sinon-chai@^3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-3.7.0.tgz#cfb7dec1c50990ed18c153f1840721cf13139783" - integrity sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g== - -sinon@^9.0.0: - version "9.2.4" - resolved "https://registry.yarnpkg.com/sinon/-/sinon-9.2.4.tgz#e55af4d3b174a4443a8762fa8421c2976683752b" - integrity sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg== - dependencies: - "@sinonjs/commons" "^1.8.1" - "@sinonjs/fake-timers" "^6.0.1" - "@sinonjs/samsam" "^5.3.1" - diff "^4.0.2" - nise "^4.0.4" - supports-color "^7.1.0" - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - -smartwrap@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/smartwrap/-/smartwrap-2.0.2.tgz#7e25d3dd58b51c6ca4aba3a9e391650ea62698a4" - integrity sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA== - dependencies: - array.prototype.flat "^1.2.3" - breakword "^1.0.5" - grapheme-splitter "^1.0.4" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" - yargs "^15.1.0" - -snake-case@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/snake-case/-/snake-case-2.1.0.tgz#41bdb1b73f30ec66a04d4e2cad1b76387d4d6d9f" - integrity sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q== - dependencies: - no-case "^2.2.0" - -solc@0.7.3: - version "0.7.3" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.7.3.tgz#04646961bd867a744f63d2b4e3c0701ffdc7d78a" - integrity sha512-GAsWNAjGzIDg7VxzP6mPjdurby3IkGCjQcM8GFYZT6RyaoUZKmMU6Y7YwG+tFGhv7dwZ8rmR4iwFDrrD99JwqA== - dependencies: - command-exists "^1.2.8" - commander "3.0.2" - follow-redirects "^1.12.1" - fs-extra "^0.30.0" - js-sha3 "0.8.0" - memorystream "^0.3.1" - require-from-string "^2.0.0" - semver "^5.5.0" - tmp "0.0.33" - -solc@^0.4.20: - version "0.4.26" - resolved "https://registry.yarnpkg.com/solc/-/solc-0.4.26.tgz#5390a62a99f40806b86258c737c1cf653cc35cb5" - integrity sha512-o+c6FpkiHd+HPjmjEVpQgH7fqZ14tJpXhho+/bQXlXbliLIS/xjXb42Vxh+qQY1WCSTMQ0+a5vR9vi0MfhU6mA== - dependencies: - fs-extra "^0.30.0" - memorystream "^0.3.1" - require-from-string "^1.1.0" - semver "^5.3.0" - yargs "^4.7.1" - -solhint@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/solhint/-/solhint-3.4.0.tgz#a7e4f2d73e679cb197a1ca5279aa7534bd323e4d" - integrity sha512-FYEs/LoTxMsWFP/OGsEqR1CBDn3Bn7hrTWsgtjai17MzxITgearIdlo374KKZjjIycu8E2xBcJ+RSWeoBvQmkw== - dependencies: - "@solidity-parser/parser" "^0.15.0" - ajv "^6.12.6" - antlr4 "^4.11.0" - ast-parents "^0.0.1" - chalk "^4.1.2" - commander "^10.0.0" - cosmiconfig "^8.0.0" - fast-diff "^1.2.0" - glob "^8.0.3" - ignore "^5.2.4" - js-yaml "^4.1.0" - lodash "^4.17.21" - pluralize "^8.0.0" - semver "^6.3.0" - strip-ansi "^6.0.1" - table "^6.8.1" - text-table "^0.2.0" - optionalDependencies: - prettier "^2.8.3" - -solidity-coverage@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/solidity-coverage/-/solidity-coverage-0.8.2.tgz#bc39604ab7ce0a3fa7767b126b44191830c07813" - integrity sha512-cv2bWb7lOXPE9/SSleDO6czkFiMHgP4NXPj+iW9W7iEKLBk7Cj0AGBiNmGX3V1totl9wjPrT0gHmABZKZt65rQ== - dependencies: - "@ethersproject/abi" "^5.0.9" - "@solidity-parser/parser" "^0.14.1" - chalk "^2.4.2" - death "^1.1.0" - detect-port "^1.3.0" - difflib "^0.2.4" - fs-extra "^8.1.0" - ghost-testrpc "^0.0.2" - global-modules "^2.0.0" - globby "^10.0.1" - jsonschema "^1.2.4" - lodash "^4.17.15" - mocha "7.1.2" - node-emoji "^1.10.0" - pify "^4.0.1" - recursive-readdir "^2.2.2" - sc-istanbul "^0.4.5" - semver "^7.3.4" - shelljs "^0.8.3" - web3-utils "^1.3.6" - -solpp@^0.11.5: - version "0.11.5" - resolved "https://registry.yarnpkg.com/solpp/-/solpp-0.11.5.tgz#e5f38b5acc952e1cc2e3871d490fdbed910938dd" - integrity sha512-LjzCGMrTDXtera2C4mbQGZSpBznP+o3/82L2CneAAMNbm+t4xPsvfrgJkIaY+IZ5YLrB8IXn7cYthwHMKvAWnQ== - dependencies: - antlr4 "~4.8.0" - axios "^0.21.1" - bn-str-256 "^1.9.1" - commander "^2.19.0" - ethereumjs-util "^6.0.0" - lodash "^4.17.11" - mz "^2.7.0" - resolve "^1.10.0" - semver "^5.6.0" - -source-map-support@0.5.12: - version "0.5.12" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.12.tgz#b4f3b10d51857a5af0138d3ce8003b201613d599" - integrity sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-support@^0.5.13, source-map-support@^0.5.19: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0, source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -source-map@~0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" - integrity sha512-CBdZ2oa/BHhS4xj5DlhjWNHcan57/5YuvfdLf17iVmIpd9KRm+DFLmC6nBNj+6Ua7Kt3TmOjDpQT1aTYOQtoUA== - dependencies: - amdefine ">=0.0.4" - -spawn-wrap@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/spawn-wrap/-/spawn-wrap-2.0.0.tgz#103685b8b8f9b79771318827aa78650a610d457e" - integrity sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg== - dependencies: - foreground-child "^2.0.0" - is-windows "^1.0.2" - make-dir "^3.0.0" - rimraf "^3.0.0" - signal-exit "^3.0.2" - which "^2.0.1" - -spawndamnit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/spawndamnit/-/spawndamnit-2.0.0.tgz#9f762ac5c3476abb994b42ad592b5ad22bb4b0ad" - integrity sha512-j4JKEcncSjFlqIwU5L/rp2N5SIPsdxaRsIv678+TZxZ0SRDJTm8JrxJMjE/XuiEZNEir3S8l0Fa3Ke339WI4qA== - dependencies: - cross-spawn "^5.1.0" - signal-exit "^3.0.2" - -spdx-correct@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" - integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.12" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz#69077835abe2710b65f03969898b6637b505a779" - integrity sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA== - -split@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" - integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== - dependencies: - through "2" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== - -sshpk@^1.7.0: - version "1.17.0" - resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.17.0.tgz#578082d92d4fe612b13007496e543fa0fbcbe4c5" - integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== - dependencies: - asn1 "~0.2.3" - assert-plus "^1.0.0" - bcrypt-pbkdf "^1.0.0" - dashdash "^1.12.0" - ecc-jsbn "~0.1.1" - getpass "^0.1.1" - jsbn "~0.1.0" - safer-buffer "^2.0.2" - tweetnacl "~0.14.0" - -stacktrace-parser@^0.1.10: - version "0.1.10" - resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a" - integrity sha512-KJP1OCML99+8fhOHxwwzyWrlUuVX5GQ0ZpJTd1DFXhdkrvg1szxfHhawXUZ3g9TkXORQd4/WG68jMlQZ2p8wlg== - dependencies: - type-fest "^0.7.1" - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -stealthy-require@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" - integrity sha512-ZnWpYnYugiOVEY5GkcuJK1io5V8QmNYChG62gSit9pQVGErXtrKuPC55ITaVSukmMta5qpMU7vqLt2Lnni4f/g== - -stream-transform@^2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/stream-transform/-/stream-transform-2.1.3.tgz#a1c3ecd72ddbf500aa8d342b0b9df38f5aa598e3" - integrity sha512-9GHUiM5hMiCi6Y03jD2ARC1ettBXkQBoQAe7nJsPknnI0ow10aXjTnew8QtYQmLjzn974BnmWEAJgCY6ZP1DeQ== - dependencies: - mixme "^0.5.1" - -streamsearch@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" - integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== - -strict-uri-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" - integrity sha512-R3f198pcvnB+5IpnBlRkphuE9n46WyVl8I39W/ZUTZLz4nqSP/oLYUrcnJrw462Ds8he4YKMov2efsTIw1BDGQ== - -string-format@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-format/-/string-format-2.0.0.tgz#f2df2e7097440d3b65de31b6d40d54c96eaffb9b" - integrity sha512-bbEs3scLeYNXLecRRuk6uJxdXUSj6le/8rNPHChIJTn2V79aXVTR1EH2OH5zLKKoz0V02fOUKZZcw01pLUShZA== - -string-width@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" - integrity sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw== - dependencies: - code-point-at "^1.0.0" - is-fullwidth-code-point "^1.0.0" - strip-ansi "^3.0.0" - -"string-width@^1.0.2 || 2", string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string.prototype.trimend@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz#c4a27fa026d979d79c04f17397f250a462944533" - integrity sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -string.prototype.trimstart@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz#e90ab66aa8e4007d92ef591bbf3cd422c56bdcf4" - integrity sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - es-abstract "^1.20.4" - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-ansi@^3.0.0, strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" - integrity sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow== - dependencies: - ansi-regex "^3.0.0" - -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" - integrity sha512-behete+3uqxecWlDAm5lmskaSaISA+ThQ4oNNBDTBJt0x2ppR6IPqfZNuj6BLaLJ/Sji4TPZlcRyOis8wXQTLg== - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== - dependencies: - is-utf8 "^0.2.0" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== - -strip-hex-prefix@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz#0c5f155fef1151373377de9dbb588da05500e36f" - integrity sha512-q8d4ue7JGEiVcypji1bALTos+0pWtyGlivAWyPuTkHzuTCJqrK9sWxYQZUq6Nq3cuyv3bm734IhHvHtGGURU6A== - dependencies: - is-hex-prefixed "1.0.0" - -strip-indent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-2.0.0.tgz#5ef8db295d01e6ed6cbf7aab96998d7822527b68" - integrity sha512-RsSNPLpq6YUL7QYy44RnPVTn/lcVZtb48Uof3X5JLbF4zD/Gs7ZFDv2HWol+leoQN2mT86LAzSshGfkTlSOpsA== - -strip-indent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" - integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== - dependencies: - min-indent "^1.0.0" - -strip-json-comments@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== - -strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supports-color@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.0.0.tgz#76cfe742cf1f41bb9b1c29ad03068c05b4c0e40a" - integrity sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg== - dependencies: - has-flag "^3.0.0" - -supports-color@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-color@^3.1.0: - version "3.2.3" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" - integrity sha512-Jds2VIYDrlp5ui7t8abHN2bjAu4LV/q4N2KivFPpGH0lrka0BMq/33AmECUXlKPcHigkNaqfXRENFju+rlcy+A== - dependencies: - has-flag "^1.0.0" - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -swap-case@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/swap-case/-/swap-case-1.1.2.tgz#c39203a4587385fad3c850a0bd1bcafa081974e3" - integrity sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ== - dependencies: - lower-case "^1.1.1" - upper-case "^1.1.1" - -swarm-js@^0.1.40: - version "0.1.42" - resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.42.tgz#497995c62df6696f6e22372f457120e43e727979" - integrity sha512-BV7c/dVlA3R6ya1lMlSSNPLYrntt0LUq4YMgy3iwpCIc6rZnS5W2wUoctarZ5pXlpKtxDDf9hNziEkcfrxdhqQ== - dependencies: - bluebird "^3.5.0" - buffer "^5.0.5" - eth-lib "^0.1.26" - fs-extra "^4.0.2" - got "^11.8.5" - mime-types "^2.1.16" - mkdirp-promise "^5.0.1" - mock-fs "^4.1.0" - setimmediate "^1.0.5" - tar "^4.0.2" - xhr-request "^1.0.1" - -sync-request@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/sync-request/-/sync-request-6.1.0.tgz#e96217565b5e50bbffe179868ba75532fb597e68" - integrity sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw== - dependencies: - http-response-object "^3.0.1" - sync-rpc "^1.2.1" - then-request "^6.0.0" - -sync-rpc@^1.2.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/sync-rpc/-/sync-rpc-1.3.6.tgz#b2e8b2550a12ccbc71df8644810529deb68665a7" - integrity sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw== - dependencies: - get-port "^3.1.0" - -table-layout@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/table-layout/-/table-layout-1.0.2.tgz#c4038a1853b0136d63365a734b6931cf4fad4a04" - integrity sha512-qd/R7n5rQTRFi+Zf2sk5XVVd9UQl6ZkduPFC3S7WEGJAmetDTjY3qPN50eSKzwuzEyQKy5TN2TiZdkIjos2L6A== - dependencies: - array-back "^4.0.1" - deep-extend "~0.6.0" - typical "^5.2.0" - wordwrapjs "^4.0.0" - -table@^6.0.9, table@^6.8.0, table@^6.8.1: - version "6.8.1" - resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" - integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== - dependencies: - ajv "^8.0.1" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - -tar@^4.0.2: - version "4.4.19" - resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.19.tgz#2e4d7263df26f2b914dee10c825ab132123742f3" - integrity sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA== - dependencies: - chownr "^1.1.4" - fs-minipass "^1.2.7" - minipass "^2.9.0" - minizlib "^1.3.3" - mkdirp "^0.5.5" - safe-buffer "^5.2.1" - yallist "^3.1.1" - -term-size@^2.1.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54" - integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg== - -test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" - integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== - dependencies: - "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^3.0.4" - -testrpc@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/testrpc/-/testrpc-0.0.1.tgz#83e2195b1f5873aec7be1af8cbe6dcf39edb7aed" - integrity sha512-afH1hO+SQ/VPlmaLUFj2636QMeDvPCeQMc/9RBMW0IfjNe9gFD9Ra3ShqYkB7py0do1ZcCna/9acHyzTJ+GcNA== - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -then-request@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/then-request/-/then-request-6.0.2.tgz#ec18dd8b5ca43aaee5cb92f7e4c1630e950d4f0c" - integrity sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA== - dependencies: - "@types/concat-stream" "^1.6.0" - "@types/form-data" "0.0.33" - "@types/node" "^8.0.0" - "@types/qs" "^6.2.31" - caseless "~0.12.0" - concat-stream "^1.6.0" - form-data "^2.2.0" - http-basic "^8.1.1" - http-response-object "^3.0.1" - promise "^8.0.0" - qs "^6.4.0" - -thenify-all@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" - integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== - dependencies: - thenify ">= 3.1.0 < 4" - -"thenify@>= 3.1.0 < 4": - version "3.3.1" - resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" - integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== - dependencies: - any-promise "^1.0.0" - -throat@^4.0.0, throat@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" - integrity sha512-wCVxLDcFxw7ujDxaeJC6nfl2XfHJNYs8yUYJnvMgtPEFlttP9tHSfRUv2vBe6C4hkVFPWoP1P6ZccbYjmSEkKA== - -through@2: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - -time-require@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/time-require/-/time-require-0.1.2.tgz#f9e12cb370fc2605e11404582ba54ef5ca2b2d98" - integrity sha512-IqcSpa1sVNleRbC9eHnN7p7vwEHNmsjsXUDqjlnvo4+2VLJ7/gIY2XACTBuRhMB4weYbDYKsR3av2ySykRhDIA== - dependencies: - chalk "^0.4.0" - date-time "^0.1.1" - pretty-ms "^0.2.1" - text-table "^0.2.0" - -timed-out@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" - integrity sha512-G7r3AhovYtr5YKOWQkta8RKAPb+J9IsO4uVmzjl8AZwfhs8UcUwTiD6gcJYSgOtzyjvQKrKYn41syHbUWMkafA== - -title-case@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/title-case/-/title-case-2.1.1.tgz#3e127216da58d2bc5becf137ab91dae3a7cd8faa" - integrity sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q== - dependencies: - no-case "^2.2.0" - upper-case "^1.0.3" - -tmp@0.0.33, tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -tough-cookie@^2.3.3, tough-cookie@~2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" - integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g== - dependencies: - psl "^1.1.28" - punycode "^2.1.1" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -trim-newlines@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" - integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== - -truffle-blockchain-utils@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/truffle-blockchain-utils/-/truffle-blockchain-utils-0.0.5.tgz#a4e5c064dadd69f782a137f3d276d21095da7a47" - integrity sha512-eCCV8FbYOuKagRY5NiqJCZrrh9GjWX2573ahqZPvUrzxYGIvCpSsHpGCub2e00YefpMfBqwscbsDTK7WNVfwoA== - -truffle-contract-schema@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/truffle-contract-schema/-/truffle-contract-schema-2.0.3.tgz#0af8e19a39c630730bc19dd41b48f5b4137a6977" - integrity sha512-eI5cFifbB3zpcO4RsXSnjN9JMSlJ4M50GQPdrfbrIXRTXHsyQ433SkgFjIATUwfq++TXWkCRfKMjN8eA7YQ3+Q== - dependencies: - ajv "^5.1.1" - crypto-js "^3.1.9-1" - debug "^3.1.0" - -truffle-contract@^3.0.7: - version "3.0.8" - resolved "https://registry.yarnpkg.com/truffle-contract/-/truffle-contract-3.0.8.tgz#6588b1b816060f6ac6876d77948934b929574067" - integrity sha512-uhXb/G4dORU4RjFlwZZbFT0n5BS8akify+MaRsnWWs4SA/bo6x4/bQs1xtdO3b5Cl9nXiOX88wdQzRj3xtPVUg== - dependencies: - ethjs-abi "0.1.8" - truffle-blockchain-utils "^0.0.5" - truffle-contract-schema "^2.0.3" - truffle-error "^0.0.3" - web3 "0.20.6" - -truffle-error@^0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/truffle-error/-/truffle-error-0.0.3.tgz#4bf55242e14deee1c7194932709182deff2c97ca" - integrity sha512-9gxs1z6BUn7MqrE4NPm/jcYe8rLok3Z57aweGIh1+CoRJSttzYqwcXCqaPRSNrTFnsTeZMBukkYr/PUcADoihw== - -ts-command-line-args@^2.2.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/ts-command-line-args/-/ts-command-line-args-2.4.2.tgz#b4815b23c35f8a0159d4e69e01012d95690bc448" - integrity sha512-mJLQQBOdyD4XI/ZWQY44PIdYde47JhV2xl380O7twPkTQ+Y5vFDHsk8LOeXKuz7dVY5aDCfAzRarNfSqtKOkQQ== - dependencies: - "@morgan-stanley/ts-mocking-bird" "^0.6.2" - chalk "^4.1.0" - command-line-args "^5.1.1" - command-line-usage "^6.1.0" - string-format "^2.0.0" - -ts-essentials@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/ts-essentials/-/ts-essentials-7.0.3.tgz#686fd155a02133eedcc5362dc8b5056cde3e5a38" - integrity sha512-8+gr5+lqO3G84KdiTSMRLtuyJ+nTBVRKuCrK4lidMPdVeEp0uqC875uE5NMcaA7YYMN7XsNiFQuMvasF8HT/xQ== - -ts-node@^10.8.0: - version "10.9.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== - dependencies: - "@cspotcode/source-map-support" "^0.8.0" - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.2" - acorn "^8.4.1" - acorn-walk "^8.1.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - v8-compile-cache-lib "^3.0.1" - yn "3.1.1" - -tsconfig-paths@^3.10.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" - integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.1" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@^1.8.1, tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tsort@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/tsort/-/tsort-0.0.1.tgz#e2280f5e817f8bf4275657fd0f9aebd44f5a2786" - integrity sha512-Tyrf5mxF8Ofs1tNoxA13lFeZ2Zrbd6cKbuH3V+MQ5sb6DtBj5FjrXVsRWT8YvNAQTqNoz66dz1WsbigI22aEnw== - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -tty-table@^4.1.5: - version "4.1.6" - resolved "https://registry.yarnpkg.com/tty-table/-/tty-table-4.1.6.tgz#6bd58338f36c94cce478c3337934d8a65ab40a73" - integrity sha512-kRj5CBzOrakV4VRRY5kUWbNYvo/FpOsz65DzI5op9P+cHov3+IqPbo1JE1ZnQGkHdZgNFDsrEjrfqqy/Ply9fw== - dependencies: - chalk "^4.1.2" - csv "^5.5.0" - kleur "^4.1.4" - smartwrap "^2.0.2" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" - yargs "^17.1.1" - -tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== - dependencies: - safe-buffer "^5.0.1" - -tweetnacl-util@^0.15.1: - version "0.15.1" - resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" - integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== - -tweetnacl@^0.14.3, tweetnacl@~0.14.0: - version "0.14.5" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" - integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== - -tweetnacl@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== - dependencies: - prelude-ls "~1.1.2" - -type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5, type-detect@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.13.1.tgz#0172cb5bce80b0bd542ea348db50c7e21834d934" - integrity sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" - integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== - -type-fest@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" - integrity sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg== - -type-fest@^0.8.0, type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -type@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" - integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== - -type@^2.7.2: - version "2.7.2" - resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" - integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== - -typechain@^8.1.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/typechain/-/typechain-8.1.1.tgz#9c2e8012c2c4c586536fc18402dcd7034c4ff0bd" - integrity sha512-uF/sUvnXTOVF2FHKhQYnxHk4su4JjZR8vr4mA2mBaRwHTbwh0jIlqARz9XJr1tA0l7afJGvEa1dTSi4zt039LQ== - dependencies: - "@types/prettier" "^2.1.1" - debug "^4.3.1" - fs-extra "^7.0.0" - glob "7.1.7" - js-sha3 "^0.8.0" - lodash "^4.17.15" - mkdirp "^1.0.4" - prettier "^2.3.1" - ts-command-line-args "^2.2.0" - ts-essentials "^7.0.1" - -typed-array-length@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" - integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - is-typed-array "^1.1.9" - -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== - -typescript@~4.7.4: - version "4.7.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" - integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== - -typical@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-4.0.0.tgz#cbeaff3b9d7ae1e2bbfaf5a4e6f11eccfde94fc4" - integrity sha512-VAH4IvQ7BDFYglMd7BPRDfLgxZZX4O4TFcRDA6EN5X7erNJJq+McIEp8np9aVtxrCJ6qx4GTYVfOWNjcqwZgRw== - -typical@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/typical/-/typical-5.2.0.tgz#4daaac4f2b5315460804f0acf6cb69c52bb93066" - integrity sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg== - -uglify-js@^3.1.4: - version "3.17.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" - integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== - -ultron@~1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" - integrity sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og== - -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" - -underscore@^1.8.3: - version "1.13.6" - resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.13.6.tgz#04786a1f589dc6c09f761fc5f45b89e935136441" - integrity sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A== - -undici@^5.14.0: - version "5.18.0" - resolved "https://registry.yarnpkg.com/undici/-/undici-5.18.0.tgz#e88a77a74d991a30701e9a6751e4193a26fabda9" - integrity sha512-1iVwbhonhFytNdg0P4PqyIAXbdlVZVebtPDvuM36m66mRw4OGrCm2MYynJv/UENFLdP13J1nPVQzVE2zTs1OeA== - dependencies: - busboy "^1.6.0" - -universalify@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" - integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== - -universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -untildify@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" - integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== - -update-browserslist-db@^1.0.10: - version "1.0.11" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" - integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - -upper-case-first@^1.1.0, upper-case-first@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/upper-case-first/-/upper-case-first-1.1.2.tgz#5d79bedcff14419518fd2edb0a0507c9b6859115" - integrity sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ== - dependencies: - upper-case "^1.1.1" - -upper-case@^1.0.3, upper-case@^1.1.0, upper-case@^1.1.1, upper-case@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" - integrity sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA== - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -url-set-query@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/url-set-query/-/url-set-query-1.0.0.tgz#016e8cfd7c20ee05cafe7795e892bd0702faa339" - integrity sha512-3AChu4NiXquPfeckE5R5cGdiHCMWJx1dwCWOmWIL4KHAziJNOFIYJlpGFeKDvwLPHovZRCxK3cYlwzqI9Vp+Gg== - -utf-8-validate@^5.0.2: - version "5.0.10" - resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" - integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== - dependencies: - node-gyp-build "^4.3.0" - -utf8@3.0.0, utf8@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" - integrity sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ== - -utf8@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/utf8/-/utf8-2.1.2.tgz#1fa0d9270e9be850d9b05027f63519bf46457d96" - integrity sha512-QXo+O/QkLP/x1nyi54uQiG0XrODxdysuQvE5dtVqv7F5K2Qb6FsN+qbr6KhF5wQ20tfcV3VQp0/2x1e1MRSPWg== - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -util@^0.12.5: - version "0.12.5" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" - integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== - dependencies: - inherits "^2.0.3" - is-arguments "^1.0.4" - is-generator-function "^1.0.7" - is-typed-array "^1.1.3" - which-typed-array "^1.1.2" - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - -uuid@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.1.tgz#c2a30dedb3e535d72ccf82e343941a50ba8533ac" - integrity sha512-nWg9+Oa3qD2CQzHIP4qKUqwNfzKn8P0LtFhotaCTFchsV7ZfDhAybeip/HZVeMIpZi9JgY1E3nUlwaCmZT1sEg== - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -uuid@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" - integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -uuid@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" - integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== - -v8-compile-cache-lib@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" - integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== - -v8-compile-cache@^2.0.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -validate-npm-package-license@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -varint@^5.0.0: - version "5.0.2" - resolved "https://registry.yarnpkg.com/varint/-/varint-5.0.2.tgz#5b47f8a947eb668b848e034dcfa87d0ff8a7f7a4" - integrity sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow== - -vary@^1, vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - -verror@1.10.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" - integrity sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw== - dependencies: - assert-plus "^1.0.0" - core-util-is "1.0.2" - extsprintf "^1.2.0" - -wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== - dependencies: - defaults "^1.0.3" - -web3-bzz@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-bzz/-/web3-bzz-1.8.2.tgz#67ea1c775874056250eece551ded22905ed08784" - integrity sha512-1EEnxjPnFnvNWw3XeeKuTR8PBxYd0+XWzvaLK7OJC/Go9O8llLGxrxICbKV+8cgIE0sDRBxiYx02X+6OhoAQ9w== - dependencies: - "@types/node" "^12.12.6" - got "12.1.0" - swarm-js "^0.1.40" - -web3-core-helpers@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-core-helpers/-/web3-core-helpers-1.8.2.tgz#82066560f8085e6c7b93bcc8e88b441289ea9f9f" - integrity sha512-6B1eLlq9JFrfealZBomd1fmlq1o4A09vrCVQSa51ANoib/jllT3atZrRDr0zt1rfI7TSZTZBXdN/aTdeN99DWw== - dependencies: - web3-eth-iban "1.8.2" - web3-utils "1.8.2" - -web3-core-method@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-core-method/-/web3-core-method-1.8.2.tgz#ba5ec68084e903f0516415010477618be017eac2" - integrity sha512-1qnr5mw5wVyULzLOrk4B+ryO3gfGjGd/fx8NR+J2xCGLf1e6OSjxT9vbfuQ3fErk/NjSTWWreieYWLMhaogcRA== - dependencies: - "@ethersproject/transactions" "^5.6.2" - web3-core-helpers "1.8.2" - web3-core-promievent "1.8.2" - web3-core-subscriptions "1.8.2" - web3-utils "1.8.2" - -web3-core-promievent@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-core-promievent/-/web3-core-promievent-1.8.2.tgz#e670d6b4453632e6ecfd9ad82da44f77ac1585c9" - integrity sha512-nvkJWDVgoOSsolJldN33tKW6bKKRJX3MCPDYMwP5SUFOA/mCzDEoI88N0JFofDTXkh1k7gOqp1pvwi9heuaxGg== - dependencies: - eventemitter3 "4.0.4" - -web3-core-requestmanager@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-core-requestmanager/-/web3-core-requestmanager-1.8.2.tgz#dda95e83ca4808949612a41e54ecea557f78ef26" - integrity sha512-p1d090RYs5Mu7DK1yyc3GCBVZB/03rBtFhYFoS2EruGzOWs/5Q0grgtpwS/DScdRAm8wB8mYEBhY/RKJWF6B2g== - dependencies: - util "^0.12.5" - web3-core-helpers "1.8.2" - web3-providers-http "1.8.2" - web3-providers-ipc "1.8.2" - web3-providers-ws "1.8.2" - -web3-core-subscriptions@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-core-subscriptions/-/web3-core-subscriptions-1.8.2.tgz#0c8bd49439d83c6f0a03c70f00b24a915a70a5ed" - integrity sha512-vXQogHDmAIQcKpXvGiMddBUeP9lnKgYF64+yQJhPNE5PnWr1sAibXuIPV7mIPihpFr/n/DORRj6Wh1pUv9zaTw== - dependencies: - eventemitter3 "4.0.4" - web3-core-helpers "1.8.2" - -web3-core@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-1.8.2.tgz#333e93d7872b1a36efe758ed8b89a7acbdd962c2" - integrity sha512-DJTVEAYcNqxkqruJE+Rxp3CIv0y5AZMwPHQmOkz/cz+MM75SIzMTc0AUdXzGyTS8xMF8h3YWMQGgGEy8SBf1PQ== - dependencies: - "@types/bn.js" "^5.1.0" - "@types/node" "^12.12.6" - bignumber.js "^9.0.0" - web3-core-helpers "1.8.2" - web3-core-method "1.8.2" - web3-core-requestmanager "1.8.2" - web3-utils "1.8.2" - -web3-eth-abi@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-1.8.2.tgz#16e1e9be40e2527404f041a4745111211488f31a" - integrity sha512-Om9g3kaRNjqiNPAgKwGT16y+ZwtBzRe4ZJFGjLiSs6v5I7TPNF+rRMWuKnR6jq0azQZDj6rblvKFMA49/k48Og== - dependencies: - "@ethersproject/abi" "^5.6.3" - web3-utils "1.8.2" - -web3-eth-accounts@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-1.8.2.tgz#b894f5d5158fcae429da42de75d96520d0712971" - integrity sha512-c367Ij63VCz9YdyjiHHWLFtN85l6QghgwMQH2B1eM/p9Y5lTlTX7t/Eg/8+f1yoIStXbk2w/PYM2lk+IkbqdLA== - dependencies: - "@ethereumjs/common" "2.5.0" - "@ethereumjs/tx" "3.3.2" - eth-lib "0.2.8" - ethereumjs-util "^7.1.5" - scrypt-js "^3.0.1" - uuid "^9.0.0" - web3-core "1.8.2" - web3-core-helpers "1.8.2" - web3-core-method "1.8.2" - web3-utils "1.8.2" - -web3-eth-contract@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-1.8.2.tgz#5388b7130923d2b790c09a420391a81312a867fb" - integrity sha512-ID5A25tHTSBNwOPjiXSVzxruz006ULRIDbzWTYIFTp7NJ7vXu/kynKK2ag/ObuTqBpMbobP8nXcA9b5EDkIdQA== - dependencies: - "@types/bn.js" "^5.1.0" - web3-core "1.8.2" - web3-core-helpers "1.8.2" - web3-core-method "1.8.2" - web3-core-promievent "1.8.2" - web3-core-subscriptions "1.8.2" - web3-eth-abi "1.8.2" - web3-utils "1.8.2" - -web3-eth-ens@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-1.8.2.tgz#0a086ad4d919102e28b9fd3036df246add9df22a" - integrity sha512-PWph7C/CnqdWuu1+SH4U4zdrK4t2HNt0I4XzPYFdv9ugE8EuojselioPQXsVGvjql+Nt3jDLvQvggPqlMbvwRw== - dependencies: - content-hash "^2.5.2" - eth-ens-namehash "2.0.8" - web3-core "1.8.2" - web3-core-helpers "1.8.2" - web3-core-promievent "1.8.2" - web3-eth-abi "1.8.2" - web3-eth-contract "1.8.2" - web3-utils "1.8.2" - -web3-eth-iban@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-1.8.2.tgz#5cb3022234b13986f086353b53f0379a881feeaf" - integrity sha512-h3vNblDWkWMuYx93Q27TAJz6lhzpP93EiC3+45D6xoz983p6si773vntoQ+H+5aZhwglBtoiBzdh7PSSOnP/xQ== - dependencies: - bn.js "^5.2.1" - web3-utils "1.8.2" - -web3-eth-personal@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-1.8.2.tgz#3526c1ebaa4e7bf3a0a8ec77e34f067cc9a750b2" - integrity sha512-Vg4HfwCr7doiUF/RC+Jz0wT4+cYaXcOWMAW2AHIjHX6Z7Xwa8nrURIeQgeEE62qcEHAzajyAdB1u6bJyTfuCXw== - dependencies: - "@types/node" "^12.12.6" - web3-core "1.8.2" - web3-core-helpers "1.8.2" - web3-core-method "1.8.2" - web3-net "1.8.2" - web3-utils "1.8.2" - -web3-eth@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-1.8.2.tgz#8562287ae1803c30eb54dc7d832092e5739ce06a" - integrity sha512-JoTiWWc4F4TInpbvDUGb0WgDYJsFhuIjJlinc5ByjWD88Gvh+GKLsRjjFdbqe5YtwIGT4NymwoC5LQd1K6u/QQ== - dependencies: - web3-core "1.8.2" - web3-core-helpers "1.8.2" - web3-core-method "1.8.2" - web3-core-subscriptions "1.8.2" - web3-eth-abi "1.8.2" - web3-eth-accounts "1.8.2" - web3-eth-contract "1.8.2" - web3-eth-ens "1.8.2" - web3-eth-iban "1.8.2" - web3-eth-personal "1.8.2" - web3-net "1.8.2" - web3-utils "1.8.2" - -web3-net@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-1.8.2.tgz#97e1e0015fabc4cda31017813e98d0b5468dd04f" - integrity sha512-1itkDMGmbgb83Dg9nporFes9/fxsU7smJ3oRXlFkg4ZHn8YJyP1MSQFPJWWwSc+GrcCFt4O5IrUTvEkHqE3xag== - dependencies: - web3-core "1.8.2" - web3-core-method "1.8.2" - web3-utils "1.8.2" - -web3-providers-http@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-1.8.2.tgz#fbda3a3bbc8db004af36e91bec35f80273b37885" - integrity sha512-2xY94IIEQd16+b+vIBF4IC1p7GVaz9q4EUFscvMUjtEq4ru4Atdzjs9GP+jmcoo49p70II0UV3bqQcz0TQfVyQ== - dependencies: - abortcontroller-polyfill "^1.7.3" - cross-fetch "^3.1.4" - es6-promise "^4.2.8" - web3-core-helpers "1.8.2" - -web3-providers-ipc@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-1.8.2.tgz#e52a7250f40c83b99a2482ec5b4cf2728377ae5c" - integrity sha512-p6fqKVGFg+WiXGHWnB1hu43PbvPkDHTz4RgoEzbXugv5rtv5zfYLqm8Ba6lrJOS5ks9kGKR21a0y3NzE3u7V4w== - dependencies: - oboe "2.1.5" - web3-core-helpers "1.8.2" - -web3-providers-ws@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-1.8.2.tgz#56a2b701387011aca9154ca4bc06ea4b5f27e4ef" - integrity sha512-3s/4K+wHgbiN+Zrp9YjMq2eqAF6QGABw7wFftPdx+m5hWImV27/MoIx57c6HffNRqZXmCHnfWWFCNHHsi7wXnA== - dependencies: - eventemitter3 "4.0.4" - web3-core-helpers "1.8.2" - websocket "^1.0.32" - -web3-shh@1.8.2: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-shh/-/web3-shh-1.8.2.tgz#217a417f0d6e243dd4d441848ffc2bd164cea8a0" - integrity sha512-uZ+3MAoNcaJsXXNCDnizKJ5viBNeHOFYsCbFhV755Uu52FswzTOw6DtE7yK9nYXMtIhiSgi7nwl1RYzP8pystw== - dependencies: - web3-core "1.8.2" - web3-core-method "1.8.2" - web3-core-subscriptions "1.8.2" - web3-net "1.8.2" - -web3-utils@1.8.2, web3-utils@^1.0.0-beta.31, web3-utils@^1.3.6: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-1.8.2.tgz#c32dec5e9b955acbab220eefd7715bc540b75cc9" - integrity sha512-v7j6xhfLQfY7xQDrUP0BKbaNrmZ2/+egbqP9q3KYmOiPpnvAfol+32slgL0WX/5n8VPvKCK5EZ1HGrAVICSToA== - dependencies: - bn.js "^5.2.1" - ethereum-bloom-filters "^1.0.6" - ethereumjs-util "^7.1.0" - ethjs-unit "0.1.6" - number-to-bn "1.7.0" - randombytes "^2.1.0" - utf8 "3.0.0" - -web3@0.20.6: - version "0.20.6" - resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.6.tgz#3e97306ae024fb24e10a3d75c884302562215120" - integrity sha512-diON1+Y8sPQ33htuTMZfyo+qlsmCBSYwi+MVTRneS8anqZUaTrGaBkTpPkPUvfX1X+NK+Y2spLaaei3HfXeSuw== - dependencies: - bignumber.js "git+https://github.com/frozeman/bignumber.js-nolookahead.git" - crypto-js "^3.1.4" - utf8 "^2.1.1" - xhr2 "*" - xmlhttprequest "*" - -web3@1.8.2, web3@^1.0.0-beta.34, web3@^1.0.0-beta.36: - version "1.8.2" - resolved "https://registry.yarnpkg.com/web3/-/web3-1.8.2.tgz#95a4e5398fd0f01325264bf8e5e8cdc69a7afe86" - integrity sha512-92h0GdEHW9wqDICQQKyG4foZBYi0OQkyg4CRml2F7XBl/NG+fu9o6J19kzfFXzSBoA4DnJXbyRgj/RHZv5LRiw== - dependencies: - web3-bzz "1.8.2" - web3-core "1.8.2" - web3-eth "1.8.2" - web3-eth-personal "1.8.2" - web3-net "1.8.2" - web3-shh "1.8.2" - web3-utils "1.8.2" - -web3@^0.20.0: - version "0.20.7" - resolved "https://registry.yarnpkg.com/web3/-/web3-0.20.7.tgz#1605e6d81399ed6f85a471a4f3da0c8be57df2f7" - integrity sha512-VU6/DSUX93d1fCzBz7WP/SGCQizO1rKZi4Px9j/3yRyfssHyFcZamMw2/sj4E8TlfMXONvZLoforR8B4bRoyTQ== - dependencies: - bignumber.js "git+https://github.com/frozeman/bignumber.js-nolookahead.git" - crypto-js "^3.1.4" - utf8 "^2.1.1" - xhr2-cookies "^1.1.0" - xmlhttprequest "*" - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -websocket@^1.0.32: - version "1.0.34" - resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" - integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== - dependencies: - bufferutil "^4.0.1" - debug "^2.2.0" - es5-ext "^0.10.50" - typedarray-to-buffer "^3.1.5" - utf-8-validate "^5.0.2" - yaeti "^0.0.6" - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" - integrity sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ== - -which-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" - integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== - -which-pm@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/which-pm/-/which-pm-2.0.0.tgz#8245609ecfe64bf751d0eef2f376d83bf1ddb7ae" - integrity sha512-Lhs9Pmyph0p5n5Z3mVnN0yWcbQYUAD7rbQUiMsQxOJ3T57k7RFe35SUwWMf7dsbDZks1uOmw4AecB/JMDj3v/w== - dependencies: - load-yaml-file "^0.2.0" - path-exists "^4.0.0" - -which-typed-array@^1.1.2, which-typed-array@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" - integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - is-typed-array "^1.1.10" - -which@1.3.1, which@^1.1.1, which@^1.2.9, which@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wide-align@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -window-size@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" - integrity sha512-UD7d8HFA2+PZsbKyaOCEy8gMh1oDtHgJh1LfgjQ4zVXmYjAT/kvz3PueITKuqDiIXQe7yzpPnxX3lNc+AhQMyw== - -word-wrap@^1.2.3, word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== - -wordwrapjs@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/wordwrapjs/-/wordwrapjs-4.0.1.tgz#d9790bccfb110a0fc7836b5ebce0937b37a8b98f" - integrity sha512-kKlNACbvHrkpIw6oPeYDSmdCTu2hdMHoyXLTcUKala++lx5Y+wjJ/e474Jqv5abnVmwxw08DiTuHmw69lJGksA== - dependencies: - reduce-flatten "^2.0.0" - typical "^5.2.0" - -workerpool@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" - integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== - -wrap-ansi@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" - integrity sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw== - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - -wrap-ansi@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -write-file-atomic@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== - dependencies: - imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" - -ws@7.4.6: - version "7.4.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c" - integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A== - -ws@^3.0.0: - version "3.3.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" - integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== - dependencies: - async-limiter "~1.0.0" - safe-buffer "~5.1.0" - ultron "~1.1.0" - -ws@^7.4.6: - version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== - -wsrun@^5.2.2: - version "5.2.4" - resolved "https://registry.yarnpkg.com/wsrun/-/wsrun-5.2.4.tgz#6eb6c3ccd3327721a8df073a5e3578fb0dea494e" - integrity sha512-akv3WtKBohdHsD/5uqhYRHw6GXeCXe87FsSg28Szq+2cpoqRW2SY4yPfm1D0za1cS6MgNy5hPgzS5SqYJaGUxg== - dependencies: - bluebird "^3.5.1" - chalk "^2.3.0" - glob "^7.1.2" - jest-changed-files "^24.9.0" - lodash "^4.17.4" - minimatch "^3.0.4" - split "^1.0.1" - throat "^4.1.0" - yargs "^13.0.0" - -xhr-request-promise@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/xhr-request-promise/-/xhr-request-promise-0.1.3.tgz#2d5f4b16d8c6c893be97f1a62b0ed4cf3ca5f96c" - integrity sha512-YUBytBsuwgitWtdRzXDDkWAXzhdGB8bYm0sSzMPZT7Z2MBjMSTHFsyCT1yCRATY+XC69DUrQraRAEgcoCRaIPg== - dependencies: - xhr-request "^1.1.0" - -xhr-request@^1.0.1, xhr-request@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/xhr-request/-/xhr-request-1.1.0.tgz#f4a7c1868b9f198723444d82dcae317643f2e2ed" - integrity sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA== - dependencies: - buffer-to-arraybuffer "^0.0.5" - object-assign "^4.1.1" - query-string "^5.0.1" - simple-get "^2.7.0" - timed-out "^4.0.1" - url-set-query "^1.0.0" - xhr "^2.0.4" - -xhr2-cookies@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz#7d77449d0999197f155cb73b23df72505ed89d48" - integrity sha512-hjXUA6q+jl/bd8ADHcVfFsSPIf+tyLIjuO9TwJC9WI6JP2zKcS7C+p56I9kCLLsaCiNT035iYvEUUzdEFj/8+g== - dependencies: - cookiejar "^2.1.1" - -xhr2@*: - version "0.2.1" - resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.2.1.tgz#4e73adc4f9cfec9cbd2157f73efdce3a5f108a93" - integrity sha512-sID0rrVCqkVNUn8t6xuv9+6FViXjUVXq8H5rWOH2rz9fDNQEd4g0EA2XlcEdJXRz5BMEn4O1pJFdT+z4YHhoWw== - -xhr@^2.0.4, xhr@^2.3.3: - version "2.6.0" - resolved "https://registry.yarnpkg.com/xhr/-/xhr-2.6.0.tgz#b69d4395e792b4173d6b7df077f0fc5e4e2b249d" - integrity sha512-/eCGLb5rxjx5e3mF1A7s+pLlR6CGyqWN91fv1JgER5mVWg1MZmlhBvy9kjcsOdRk8RrIujotWyJamfyrp+WIcA== - dependencies: - global "~4.4.0" - is-function "^1.0.1" - parse-headers "^2.0.0" - xtend "^4.0.0" - -xmlhttprequest@*, xmlhttprequest@1.8.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" - integrity sha512-58Im/U0mlVBLM38NdZjHyhuMtCqa61469k2YP/AaPbvCoV9aQGUpbJBj1QRm2ytRiVQBD/fsw7L2bJGDVQswBA== - -xtend@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -y18n@^3.2.1: - version "3.2.2" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.2.tgz#85c901bd6470ce71fc4bb723ad209b70f7f28696" - integrity sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ== - -y18n@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" - integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yaeti@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" - integrity sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug== - -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== - -yallist@^3.0.0, yallist@^3.0.2, yallist@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@13.1.2, yargs-parser@^13.1.0, yargs-parser@^13.1.2: - version "13.1.2" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" - integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@^18.1.2, yargs-parser@^18.1.3: - version "18.1.3" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" - integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" - -yargs-parser@^2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-2.4.1.tgz#85568de3cf150ff49fa51825f03a8c880ddcc5c4" - integrity sha512-9pIKIJhnI5tonzG6OnCFlz/yln8xHYcGl+pn3xR0Vzff0vzN1PbNRaelgfgRUwZ3s4i3jvxT9WhmUGL4whnasA== - dependencies: - camelcase "^3.0.0" - lodash.assign "^4.0.6" - -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== - -yargs-unparser@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" - integrity sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw== - dependencies: - flat "^4.1.0" - lodash "^4.17.15" - yargs "^13.3.0" - -yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - -yargs@13.2.4: - version "13.2.4" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" - integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - os-locale "^3.1.0" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.0" - -yargs@13.3.2, yargs@^13.0.0, yargs@^13.3.0: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.2" - -yargs@16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^15.0.2, yargs@^15.1.0: - version "15.4.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" - integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== - dependencies: - cliui "^6.0.0" - decamelize "^1.2.0" - find-up "^4.1.0" - get-caller-file "^2.0.1" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^4.2.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^18.1.2" - -yargs@^17.1.1: - version "17.6.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541" - integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.1.1" - -yargs@^4.7.1: - version "4.8.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.8.1.tgz#c0c42924ca4aaa6b0e6da1739dfb216439f9ddc0" - integrity sha512-LqodLrnIDM3IFT+Hf/5sxBnEGECrfdC1uIbgZeJmESCSo4HoCAaKEus8MylXHAkdacGc0ye+Qa+dpkuom8uVYA== - dependencies: - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - lodash.assign "^4.0.3" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.1" - which-module "^1.0.0" - window-size "^0.2.0" - y18n "^3.2.1" - yargs-parser "^2.4.1" - -yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==