From fb167e23f6113ca82b438f825f086c72ddb91609 Mon Sep 17 00:00:00 2001 From: "moxey.eth" Date: Wed, 8 Feb 2023 08:55:51 +1100 Subject: [PATCH 1/7] feat: multicall + contract error cleanup --- src/errors/contract.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/errors/contract.ts b/src/errors/contract.ts index 62f823de78..cf6542d6af 100644 --- a/src/errors/contract.ts +++ b/src/errors/contract.ts @@ -94,7 +94,7 @@ export class ContractFunctionRevertedError extends BaseError { super( [ - `The contract function "${functionName}" reverted with the following reason:`, + `The contract function "${functionName}" reverted for the following reason:`, reason, ].join('\n'), ) From b4a4d87b893e1c9238b9e9a2958cfbd6b58ccd62 Mon Sep 17 00:00:00 2001 From: "moxey.eth" Date: Wed, 8 Feb 2023 14:52:14 +1100 Subject: [PATCH 2/7] tests: fix --- src/errors/contract.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/errors/contract.ts b/src/errors/contract.ts index cf6542d6af..62f823de78 100644 --- a/src/errors/contract.ts +++ b/src/errors/contract.ts @@ -94,7 +94,7 @@ export class ContractFunctionRevertedError extends BaseError { super( [ - `The contract function "${functionName}" reverted for the following reason:`, + `The contract function "${functionName}" reverted with the following reason:`, reason, ].join('\n'), ) From 320c67a17f0c0a3f357a35e9b62f0b2a12d2d1d5 Mon Sep 17 00:00:00 2001 From: "moxey.eth" Date: Wed, 8 Feb 2023 16:29:31 +1100 Subject: [PATCH 3/7] feat: support Panic & custom contract errors --- .github/workflows/bench.yml | 16 + .github/workflows/main.yml | 31 + .github/workflows/release.yml | 2 + .github/workflows/size.yml | 7 +- .github/workflows/snapshot.yml | 2 + .gitignore | 3 + .gitmodules | 3 + contracts/.gitignore | 2 + contracts/foundry.toml | 2 + contracts/lib/forge-std | 1 + contracts/src/ErrorsExample.sol | 88 +++ package.json | 4 +- pnpm-lock.yaml | 634 +++++++++++++++++++- src/_test/index.ts | 2 + src/_test/utils.ts | 40 +- src/actions/public/multicall.test.ts | 2 - src/actions/public/multicall.ts | 14 +- src/actions/public/readContract.test.ts | 176 +++++- src/actions/public/simulateContract.test.ts | 187 +++++- src/constants/abis.test.ts | 2 +- src/constants/abis.ts | 512 ---------------- src/constants/index.test.ts | 33 + src/constants/index.ts | 2 + src/constants/solidity.test.ts | 43 ++ src/constants/solidity.ts | 37 ++ src/errors/contract.test.ts | 233 +++++++ src/errors/contract.ts | 81 ++- src/errors/index.ts | 2 + src/index.test.ts | 3 + src/index.ts | 3 + src/utils/abi/decodeErrorResult.test.ts | 74 ++- src/utils/abi/decodeErrorResult.ts | 40 +- src/utils/contract/getContractError.ts | 18 +- wagmi.config.ts | 12 + 34 files changed, 1684 insertions(+), 627 deletions(-) create mode 100644 .gitmodules create mode 100644 contracts/.gitignore create mode 100644 contracts/foundry.toml create mode 160000 contracts/lib/forge-std create mode 100644 contracts/src/ErrorsExample.sol create mode 100644 src/constants/solidity.test.ts create mode 100644 src/constants/solidity.ts create mode 100644 src/errors/contract.test.ts create mode 100644 wagmi.config.ts diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index 6996a292d0..be34edc822 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -40,9 +40,23 @@ jobs: playgrounds/**/node_modules site/node_modules key: modules-${{ hashFiles('pnpm-lock.yaml') }} + - name: Install rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: wasm32-unknown-unknown + profile: minimal + override: true + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly - name: Install Dependencies if: steps.cache-node-modules.outputs.cache-hit != 'true' run: pnpm i + - name: Build Contracts + if: steps.cache-node-modules.outputs.cache-hit == 'true' + run: pnpm contracts:build - name: Link Dependencies if: steps.cache-node-modules.outputs.cache-hit == 'true' run: pnpm dev @@ -91,6 +105,8 @@ jobs: VITE_ANVIL_BLOCK_NUMBER: ${{ secrets.VITE_ANVIL_BLOCK_NUMBER }} VITE_ANVIL_BLOCK_TIME: ${{ secrets.VITE_ANVIL_BLOCK_TIME }} VITE_ANVIL_FORK_URL: ${{ secrets.VITE_ANVIL_FORK_URL }} + - name: Build Contracts + run: pnpm contracts:build - name: Bench run: pnpm bench:ci env: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dc6ddb86cd..e6b99e1920 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -43,9 +43,23 @@ jobs: playgrounds/**/node_modules site/node_modules key: modules-${{ hashFiles('pnpm-lock.yaml') }} + - name: Install rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: wasm32-unknown-unknown + profile: minimal + override: true + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly - name: Install Dependencies if: steps.cache-node-modules.outputs.cache-hit != 'true' run: pnpm i + - name: Build Contracts + if: steps.cache-node-modules.outputs.cache-hit == 'true' + run: pnpm contracts:build - name: Link Dependencies if: steps.cache-node-modules.outputs.cache-hit == 'true' run: pnpm dev @@ -77,6 +91,19 @@ jobs: playgrounds/**/node_modules site/node_modules key: modules-${{ hashFiles('pnpm-lock.yaml') }} + - name: Install rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: wasm32-unknown-unknown + profile: minimal + override: true + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + - name: Build Contracts + run: pnpm contracts:build - name: Link run: pnpm dev - name: Check types @@ -174,6 +201,8 @@ jobs: VITE_ANVIL_BLOCK_NUMBER: ${{ secrets.VITE_ANVIL_BLOCK_NUMBER }} VITE_ANVIL_BLOCK_TIME: ${{ secrets.VITE_ANVIL_BLOCK_TIME }} VITE_ANVIL_FORK_URL: ${{ secrets.VITE_ANVIL_FORK_URL }} + - name: Build Contracts + run: pnpm contracts:build - name: Test uses: nick-fields/retry@v2 with: @@ -235,6 +264,8 @@ jobs: VITE_ANVIL_BLOCK_NUMBER: ${{ secrets.VITE_ANVIL_BLOCK_NUMBER }} VITE_ANVIL_BLOCK_TIME: ${{ secrets.VITE_ANVIL_BLOCK_TIME }} VITE_ANVIL_FORK_URL: ${{ secrets.VITE_ANVIL_FORK_URL }} + - name: Build Contracts + run: pnpm contracts:build - name: Bench run: pnpm bench:ci --changed env: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5427bb4a85..b559e62653 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -29,6 +29,8 @@ jobs: node-version: ${{ matrix.node-version }} - name: Install Dependencies run: pnpm i + env: + SKIP_WAGMI_CLI: true - name: Create Release Pull Request or Publish to npm id: changesets diff --git a/.github/workflows/size.yml b/.github/workflows/size.yml index 30730e88e8..3c0d5e72ec 100644 --- a/.github/workflows/size.yml +++ b/.github/workflows/size.yml @@ -38,7 +38,10 @@ jobs: key: modules-${{ hashFiles('pnpm-lock.yaml') }} - name: Install Dependencies if: steps.cache-node-modules.outputs.cache-hit != 'true' - run: pnpm i + env: + SKIP_WAGMI_CLI: true - uses: preactjs/compressed-size-action@v2 with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" \ No newline at end of file + repo-token: "${{ secrets.GITHUB_TOKEN }}" + env: + SKIP_WAGMI_CLI: true \ No newline at end of file diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index be676370a6..38f0ff75dc 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -28,6 +28,8 @@ jobs: - name: Install Dependencies run: pnpm i + env: + SKIP_WAGMI_CLI: true - name: Publish to npm uses: seek-oss/changesets-snapshot@v0 diff --git a/.gitignore b/.gitignore index 95062c78f5..0b0adfc275 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,9 @@ bench .env.production.local .envrc +# @wagmi/cli +generated.ts + actions/** chains/** clients/** diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..c65a596591 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "contracts/lib/forge-std"] + path = contracts/lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/contracts/.gitignore b/contracts/.gitignore new file mode 100644 index 0000000000..1f85ede7bf --- /dev/null +++ b/contracts/.gitignore @@ -0,0 +1,2 @@ +cache/ +out/ \ No newline at end of file diff --git a/contracts/foundry.toml b/contracts/foundry.toml new file mode 100644 index 0000000000..93d2364a88 --- /dev/null +++ b/contracts/foundry.toml @@ -0,0 +1,2 @@ +[profile.ci.fuzz] +runs = 10_000 diff --git a/contracts/lib/forge-std b/contracts/lib/forge-std new file mode 160000 index 0000000000..662ae0d693 --- /dev/null +++ b/contracts/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 662ae0d6936654c5d1fb79fc15f521de28edb60e diff --git a/contracts/src/ErrorsExample.sol b/contracts/src/ErrorsExample.sol new file mode 100644 index 0000000000..1094718218 --- /dev/null +++ b/contracts/src/ErrorsExample.sol @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.13; + +contract ErrorsExample { + struct Foo { + address sender; + uint256 bar; + } + + error SimpleError(string message); + error ComplexError(Foo foo, string message, uint256 number); + + function revertRead() public pure { + revert("This is a revert message"); + } + + function assertRead() public pure { + assert(false); + } + + function overflowRead() public pure returns (uint256) { + uint256 a = 2**256 - 1; + uint256 b = 1; + uint256 c = a + b; + return c; + } + + function divideByZeroRead() public pure returns (uint256) { + uint256 a = 69; + uint256 b = 0; + uint256 c = a / b; + return c; + } + + function requireRead() public pure { + require(false); + } + + function simpleCustomRead() public pure { + revert SimpleError("bugger"); + } + + function complexCustomRead() public pure { + revert ComplexError( + Foo({sender: 0x0000000000000000000000000000000000000000, bar: 69}), + "bugger", + 69 + ); + } + + function revertWrite() public { + revert("This is a revert message"); + } + + function assertWrite() public { + assert(false); + } + + function overflowWrite() public returns (uint256) { + uint256 a = 2**256 - 1; + uint256 b = 1; + uint256 c = a + b; + return c; + } + + function divideByZeroWrite() public returns (uint256) { + uint256 a = 69; + uint256 b = 0; + uint256 c = a / b; + return c; + } + + function requireWrite() public { + require(false); + } + + function simpleCustomWrite() public { + revert SimpleError("bugger"); + } + + function complexCustomWrite() public { + revert ComplexError( + Foo({sender: 0x0000000000000000000000000000000000000000, bar: 69}), + "bugger", + 69 + ); + } +} diff --git a/package.json b/package.json index fd2ec79d2f..04786b91a9 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "changeset": "changeset", "changeset:release": "pnpm build && changeset publish", "changeset:version": "changeset version && pnpm install --lockfile-only", + "contracts:build": "wagmi generate", "dev": "DEV=true tsup", "dev:docs": "pnpm -r --filter site dev", "format": "rome format src/ test/ --write", @@ -17,7 +18,7 @@ "lint:fix": "pnpm lint --apply-suggested", "playground": "pnpm --filter playground-dev dev", "playground:benchmark": "pnpm --filter playground-benchmark dev", - "postinstall": "pnpm dev", + "postinstall": "pnpm dev && if [ -z $SKIP_WAGMI_CLI ]; then pnpm contracts:build; fi", "preinstall": "npx only-allow pnpm", "prepublishOnly": "pnpm ts-node scripts/generate-package-json.ts", "prepare": "npx simple-git-hooks", @@ -107,6 +108,7 @@ "@types/node": "^17.0.45", "@vitest/coverage-c8": "^0.24.3", "@vitest/ui": "^0.19.1", + "@wagmi/cli": "^0.1.5", "bundlewatch": "^0.3.3", "dedent": "^0.7.0", "esbuild": "^0.16.12", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 991a8cc5db..c5b5151d9f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -22,6 +22,7 @@ importers: '@vitest/coverage-c8': ^0.24.3 '@vitest/ui': ^0.19.1 '@wagmi/chains': ~0.2.6 + '@wagmi/cli': ^0.1.5 abitype: ~0.3.0 bundlewatch: ^0.3.3 dedent: ^0.7.0 @@ -57,6 +58,7 @@ importers: '@types/node': 17.0.45 '@vitest/coverage-c8': 0.24.3_vnmq2nkosb62o4dsp6xedf6gbi '@vitest/ui': 0.19.1 + '@wagmi/cli': 0.1.5_typescript@4.9.5 bundlewatch: 0.3.3 dedent: 0.7.0 esbuild: 0.16.12 @@ -600,6 +602,15 @@ packages: dev: true optional: true + /@esbuild/android-arm/0.15.13: + resolution: {integrity: sha512-RY2fVI8O0iFUNvZirXaQ1vMvK0xhCcl0gqRj74Z6yEiO1zAUa7hbsdwZM1kzqbxHK7LFyMizipfXT3JME+12Hw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + /@esbuild/android-arm/0.16.12: resolution: {integrity: sha512-CTWgMJtpCyCltrvipZrrcjjRu+rzm6pf9V8muCsJqtKujR3kPmU4ffbckvugNNaRmhxAF1ZI3J+0FUIFLFg8KA==} engines: {node: '>=12'} @@ -699,6 +710,15 @@ packages: dev: true optional: true + /@esbuild/linux-loong64/0.15.13: + resolution: {integrity: sha512-+BoyIm4I8uJmH/QDIH0fu7MG0AEx9OXEDXnqptXCwKOlOqZiS4iraH1Nr7/ObLMokW3sOCeBNyD68ATcV9b9Ag==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /@esbuild/linux-loong64/0.16.12: resolution: {integrity: sha512-xTGzVPqm6WKfCC0iuj1fryIWr1NWEM8DMhAIo+4rFgUtwy/lfHl+Obvus4oddzRDbBetLLmojfVZGmt/g/g+Rw==} engines: {node: '>=12'} @@ -1959,7 +1979,48 @@ packages: optional: true dependencies: typescript: 4.9.5 - dev: false + + /@wagmi/cli/0.1.5_typescript@4.9.5: + resolution: {integrity: sha512-HPkpPMBcRQUH23P9WpfXrQtBs+biaVuHSqnc5gq+8owNV/V0nMsMHtOQOLRpbjVbwim2q8ZEB7a9ep9sEzzlQg==} + engines: {node: '>=14'} + hasBin: true + peerDependencies: + '@wagmi/core': '>=0.9' + typescript: '>=4.9.4' + wagmi: '>=0.11' + peerDependenciesMeta: + '@wagmi/core': + optional: true + typescript: + optional: true + wagmi: + optional: true + dependencies: + '@ethersproject/address': 5.7.0 + '@wagmi/chains': 0.2.6_typescript@4.9.5 + abitype: 0.3.0_p5jgycp7euppyerdfacwyih2x4 + abort-controller: 3.0.0 + bundle-require: 3.1.2_esbuild@0.15.13 + cac: 6.7.14 + change-case: 4.1.2 + chokidar: 3.5.3 + dedent: 0.7.0 + detect-package-manager: 2.0.1 + dotenv: 16.0.3 + dotenv-expand: 10.0.0 + esbuild: 0.15.13 + execa: 6.1.0 + find-up: 6.3.0 + fs-extra: 10.1.0 + globby: 13.1.3 + node-fetch: 3.3.0 + ora: 6.1.2 + pathe: 1.1.0 + picocolors: 1.0.0 + prettier: 2.8.3 + typescript: 4.9.5 + zod: 3.20.2 + dev: true /@walletconnect/browser-utils/1.8.0: resolution: {integrity: sha512-Wcqqx+wjxIo9fv6eBUFHPsW1y/bGWWRboni5dfD8PtOmrihrEpOCmvRJe4rfl7xgJW8Ea9UqKEaq0bIRLHlK4A==} @@ -2154,6 +2215,20 @@ packages: resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} dev: true + /abitype/0.3.0_p5jgycp7euppyerdfacwyih2x4: + resolution: {integrity: sha512-0YokyAV4hKMcy97Pl+6QgZBlBdZJN2llslOs7kiFY+cu7kMlVXDBpxMExfv0krzBCQt2t7hNovpQ3y/zvEm18A==} + engines: {pnpm: '>=7'} + peerDependencies: + typescript: '>=4.9.4' + zod: '>=3.19.1' + peerDependenciesMeta: + zod: + optional: true + dependencies: + typescript: 4.9.5 + zod: 3.20.2 + dev: true + /abitype/0.3.0_typescript@4.9.5: resolution: {integrity: sha512-0YokyAV4hKMcy97Pl+6QgZBlBdZJN2llslOs7kiFY+cu7kMlVXDBpxMExfv0krzBCQt2t7hNovpQ3y/zvEm18A==} engines: {pnpm: '>=7'} @@ -2167,6 +2242,13 @@ packages: typescript: 4.9.5 dev: false + /abort-controller/3.0.0: + resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} + engines: {node: '>=6.5'} + dependencies: + event-target-shim: 5.0.1 + dev: true + /abortcontroller-polyfill/1.7.5: resolution: {integrity: sha512-JMJ5soJWP18htbbxJjG7bG6yuI6pRhgJ0scHHTfkUjf6wjP912xZWvM+A4sJK3gqd9E8fcPbDnOefbA9Th/FIQ==} dev: true @@ -2283,6 +2365,11 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} + /ansi-regex/6.0.1: + resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==} + engines: {node: '>=12'} + dev: true + /ansi-styles/3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -2507,6 +2594,14 @@ packages: engines: {node: '>=8'} dev: true + /bl/5.1.0: + resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} + dependencies: + buffer: 6.0.3 + inherits: 2.0.4 + readable-stream: 3.6.0 + dev: true + /blakejs/1.2.1: resolution: {integrity: sha512-QXUSXI3QVc/gJME0dBpXrag1kbzOqCjCX8/b54ntNyW6sjtoqxqRk3LTmXzaJoh71zMsDCjM+47jS7XiwN/+fQ==} dev: true @@ -2685,6 +2780,13 @@ packages: base64-js: 1.5.1 ieee754: 1.2.1 + /buffer/6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + /bufferutil/4.0.7: resolution: {integrity: sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw==} engines: {node: '>=6.14.2'} @@ -2703,6 +2805,16 @@ packages: load-tsconfig: 0.2.3 dev: true + /bundle-require/3.1.2_esbuild@0.15.13: + resolution: {integrity: sha512-Of6l6JBAxiyQ5axFxUM6dYeP/W7X2Sozeo/4EYB9sJhL+dqL7TKjg+shwxp6jlu/6ZSERfsYtIpSJ1/x3XkAEA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + peerDependencies: + esbuild: '>=0.13' + dependencies: + esbuild: 0.15.13 + load-tsconfig: 0.2.3 + dev: true + /bundlewatch/0.3.3: resolution: {integrity: sha512-qzSVWrZyyWXa546JpAPRPTFmnXms9YNVnfzB05DRJKmN6wRRa7SkxE4OgKQmbAY74Z6CM2mKAc6vwvd2R+1lUQ==} engines: {node: '>=10'} @@ -2784,6 +2896,13 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + /camel-case/4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + dependencies: + pascal-case: 3.1.2 + tslib: 2.4.0 + dev: true + /camelcase-css/2.0.1: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} @@ -2810,6 +2929,14 @@ packages: resolution: {integrity: sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA==} dev: true + /capital-case/1.0.4: + resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} + dependencies: + no-case: 3.0.4 + tslib: 2.4.0 + upper-case-first: 2.0.2 + dev: true + /caseless/0.12.0: resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} dev: true @@ -2851,6 +2978,28 @@ packages: ansi-styles: 4.3.0 supports-color: 7.2.0 + /chalk/5.2.0: + resolution: {integrity: sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + dev: true + + /change-case/4.1.2: + resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==} + dependencies: + camel-case: 4.1.2 + capital-case: 1.0.4 + constant-case: 3.0.4 + dot-case: 3.0.4 + header-case: 2.0.4 + no-case: 3.0.4 + param-case: 3.0.4 + pascal-case: 3.1.2 + path-case: 3.0.4 + sentence-case: 3.0.4 + snake-case: 3.0.4 + tslib: 2.4.0 + dev: true + /chardet/0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} dev: true @@ -2909,6 +3058,18 @@ packages: resolution: {integrity: sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw==} dev: true + /cli-cursor/4.0.0: + resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + restore-cursor: 4.0.0 + dev: true + + /cli-spinners/2.7.0: + resolution: {integrity: sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==} + engines: {node: '>=6'} + dev: true + /cliui/5.0.0: resolution: {integrity: sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==} dependencies: @@ -2986,6 +3147,14 @@ packages: /concat-map/0.0.1: resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + /constant-case/3.0.4: + resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} + dependencies: + no-case: 3.0.4 + tslib: 2.4.0 + upper-case: 2.0.2 + dev: true + /content-disposition/0.5.4: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} @@ -3187,6 +3356,11 @@ packages: assert-plus: 1.0.0 dev: true + /data-uri-to-buffer/4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + dev: true + /data-urls/3.0.2: resolution: {integrity: sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==} engines: {node: '>=12'} @@ -3356,6 +3530,13 @@ packages: engines: {node: '>=8'} dev: true + /detect-package-manager/2.0.1: + resolution: {integrity: sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A==} + engines: {node: '>=12'} + dependencies: + execa: 5.1.1 + dev: true + /detective/5.2.1: resolution: {integrity: sha512-v9XE1zRnz1wRtgurGu0Bs8uHKFSTdteYZNbIPFVhUZ39L/S79ppMpdmVOZAnoz1jfEFodc48n6MX483Xo3t1yw==} engines: {node: '>=0.8.0'} @@ -3424,6 +3605,23 @@ packages: webidl-conversions: 7.0.0 dev: true + /dot-case/3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dependencies: + no-case: 3.0.4 + tslib: 2.4.0 + dev: true + + /dotenv-expand/10.0.0: + resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} + engines: {node: '>=12'} + dev: true + + /dotenv/16.0.3: + resolution: {integrity: sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==} + engines: {node: '>=12'} + dev: true + /dotenv/8.6.0: resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} engines: {node: '>=10'} @@ -3610,6 +3808,15 @@ packages: dev: true optional: true + /esbuild-android-64/0.15.13: + resolution: {integrity: sha512-yRorukXBlokwTip+Sy4MYskLhJsO0Kn0/Fj43s1krVblfwP+hMD37a4Wmg139GEsMLl+vh8WXp2mq/cTA9J97g==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + requiresBuild: true + dev: true + optional: true + /esbuild-android-arm64/0.14.49: resolution: {integrity: sha512-g2HGr/hjOXCgSsvQZ1nK4nW/ei8JUx04Li74qub9qWrStlysaVmadRyTVuW32FGIpLQyc5sUjjZopj49eGGM2g==} engines: {node: '>=12'} @@ -3628,6 +3835,15 @@ packages: dev: true optional: true + /esbuild-android-arm64/0.15.13: + resolution: {integrity: sha512-TKzyymLD6PiVeyYa4c5wdPw87BeAiTXNtK6amWUcXZxkV51gOk5u5qzmDaYSwiWeecSNHamFsaFjLoi32QR5/w==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + /esbuild-darwin-64/0.14.49: resolution: {integrity: sha512-3rvqnBCtX9ywso5fCHixt2GBCUsogNp9DjGmvbBohh31Ces34BVzFltMSxJpacNki96+WIcX5s/vum+ckXiLYg==} engines: {node: '>=12'} @@ -3646,6 +3862,15 @@ packages: dev: true optional: true + /esbuild-darwin-64/0.15.13: + resolution: {integrity: sha512-WAx7c2DaOS6CrRcoYCgXgkXDliLnFv3pQLV6GeW1YcGEZq2Gnl8s9Pg7ahValZkpOa0iE/ojRVQ87sbUhF1Cbg==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /esbuild-darwin-arm64/0.14.49: resolution: {integrity: sha512-XMaqDxO846srnGlUSJnwbijV29MTKUATmOLyQSfswbK/2X5Uv28M9tTLUJcKKxzoo9lnkYPsx2o8EJcTYwCs/A==} engines: {node: '>=12'} @@ -3664,6 +3889,15 @@ packages: dev: true optional: true + /esbuild-darwin-arm64/0.15.13: + resolution: {integrity: sha512-U6jFsPfSSxC3V1CLiQqwvDuj3GGrtQNB3P3nNC3+q99EKf94UGpsG9l4CQ83zBs1NHrk1rtCSYT0+KfK5LsD8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + /esbuild-freebsd-64/0.14.49: resolution: {integrity: sha512-NJ5Q6AjV879mOHFri+5lZLTp5XsO2hQ+KSJYLbfY9DgCu8s6/Zl2prWXVANYTeCDLlrIlNNYw8y34xqyLDKOmQ==} engines: {node: '>=12'} @@ -3682,6 +3916,15 @@ packages: dev: true optional: true + /esbuild-freebsd-64/0.15.13: + resolution: {integrity: sha512-whItJgDiOXaDG/idy75qqevIpZjnReZkMGCgQaBWZuKHoElDJC1rh7MpoUgupMcdfOd+PgdEwNQW9DAE6i8wyA==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /esbuild-freebsd-arm64/0.14.49: resolution: {integrity: sha512-lFLtgXnAc3eXYqj5koPlBZvEbBSOSUbWO3gyY/0+4lBdRqELyz4bAuamHvmvHW5swJYL7kngzIZw6kdu25KGOA==} engines: {node: '>=12'} @@ -3700,6 +3943,15 @@ packages: dev: true optional: true + /esbuild-freebsd-arm64/0.15.13: + resolution: {integrity: sha512-6pCSWt8mLUbPtygv7cufV0sZLeylaMwS5Fznj6Rsx9G2AJJsAjQ9ifA+0rQEIg7DwJmi9it+WjzNTEAzzdoM3Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-32/0.14.49: resolution: {integrity: sha512-zTTH4gr2Kb8u4QcOpTDVn7Z8q7QEIvFl/+vHrI3cF6XOJS7iEI1FWslTo3uofB2+mn6sIJEQD9PrNZKoAAMDiA==} engines: {node: '>=12'} @@ -3718,6 +3970,15 @@ packages: dev: true optional: true + /esbuild-linux-32/0.15.13: + resolution: {integrity: sha512-VbZdWOEdrJiYApm2kkxoTOgsoCO1krBZ3quHdYk3g3ivWaMwNIVPIfEE0f0XQQ0u5pJtBsnk2/7OPiCFIPOe/w==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-64/0.14.49: resolution: {integrity: sha512-hYmzRIDzFfLrB5c1SknkxzM8LdEUOusp6M2TnuQZJLRtxTgyPnZZVtyMeCLki0wKgYPXkFsAVhi8vzo2mBNeTg==} engines: {node: '>=12'} @@ -3736,6 +3997,15 @@ packages: dev: true optional: true + /esbuild-linux-64/0.15.13: + resolution: {integrity: sha512-rXmnArVNio6yANSqDQlIO4WiP+Cv7+9EuAHNnag7rByAqFVuRusLbGi2697A5dFPNXoO//IiogVwi3AdcfPC6A==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-arm/0.14.49: resolution: {integrity: sha512-iE3e+ZVv1Qz1Sy0gifIsarJMQ89Rpm9mtLSRtG3AH0FPgAzQ5Z5oU6vYzhc/3gSPi2UxdCOfRhw2onXuFw/0lg==} engines: {node: '>=12'} @@ -3754,6 +4024,15 @@ packages: dev: true optional: true + /esbuild-linux-arm/0.15.13: + resolution: {integrity: sha512-Ac6LpfmJO8WhCMQmO253xX2IU2B3wPDbl4IvR0hnqcPrdfCaUa2j/lLMGTjmQ4W5JsJIdHEdW12dG8lFS0MbxQ==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-arm64/0.14.49: resolution: {integrity: sha512-KLQ+WpeuY+7bxukxLz5VgkAAVQxUv67Ft4DmHIPIW+2w3ObBPQhqNoeQUHxopoW/aiOn3m99NSmSV+bs4BSsdA==} engines: {node: '>=12'} @@ -3772,6 +4051,15 @@ packages: dev: true optional: true + /esbuild-linux-arm64/0.15.13: + resolution: {integrity: sha512-alEMGU4Z+d17U7KQQw2IV8tQycO6T+rOrgW8OS22Ua25x6kHxoG6Ngry6Aq6uranC+pNWNMB6aHFPh7aTQdORQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-mips64le/0.14.49: resolution: {integrity: sha512-n+rGODfm8RSum5pFIqFQVQpYBw+AztL8s6o9kfx7tjfK0yIGF6tm5HlG6aRjodiiKkH2xAiIM+U4xtQVZYU4rA==} engines: {node: '>=12'} @@ -3790,6 +4078,15 @@ packages: dev: true optional: true + /esbuild-linux-mips64le/0.15.13: + resolution: {integrity: sha512-47PgmyYEu+yN5rD/MbwS6DxP2FSGPo4Uxg5LwIdxTiyGC2XKwHhHyW7YYEDlSuXLQXEdTO7mYe8zQ74czP7W8A==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-ppc64le/0.14.49: resolution: {integrity: sha512-WP9zR4HX6iCBmMFH+XHHng2LmdoIeUmBpL4aL2TR8ruzXyT4dWrJ5BSbT8iNo6THN8lod6GOmYDLq/dgZLalGw==} engines: {node: '>=12'} @@ -3808,6 +4105,15 @@ packages: dev: true optional: true + /esbuild-linux-ppc64le/0.15.13: + resolution: {integrity: sha512-z6n28h2+PC1Ayle9DjKoBRcx/4cxHoOa2e689e2aDJSaKug3jXcQw7mM+GLg+9ydYoNzj8QxNL8ihOv/OnezhA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-riscv64/0.14.49: resolution: {integrity: sha512-h66ORBz+Dg+1KgLvzTVQEA1LX4XBd1SK0Fgbhhw4akpG/YkN8pS6OzYI/7SGENiN6ao5hETRDSkVcvU9NRtkMQ==} engines: {node: '>=12'} @@ -3826,6 +4132,15 @@ packages: dev: true optional: true + /esbuild-linux-riscv64/0.15.13: + resolution: {integrity: sha512-+Lu4zuuXuQhgLUGyZloWCqTslcCAjMZH1k3Xc9MSEJEpEFdpsSU0sRDXAnk18FKOfEjhu4YMGaykx9xjtpA6ow==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-linux-s390x/0.14.49: resolution: {integrity: sha512-DhrUoFVWD+XmKO1y7e4kNCqQHPs6twz6VV6Uezl/XHYGzM60rBewBF5jlZjG0nCk5W/Xy6y1xWeopkrhFFM0sQ==} engines: {node: '>=12'} @@ -3844,6 +4159,15 @@ packages: dev: true optional: true + /esbuild-linux-s390x/0.15.13: + resolution: {integrity: sha512-BMeXRljruf7J0TMxD5CIXS65y7puiZkAh+s4XFV9qy16SxOuMhxhVIXYLnbdfLrsYGFzx7U9mcdpFWkkvy/Uag==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + requiresBuild: true + dev: true + optional: true + /esbuild-netbsd-64/0.14.49: resolution: {integrity: sha512-BXaUwFOfCy2T+hABtiPUIpWjAeWK9P8O41gR4Pg73hpzoygVGnj0nI3YK4SJhe52ELgtdgWP/ckIkbn2XaTxjQ==} engines: {node: '>=12'} @@ -3862,6 +4186,15 @@ packages: dev: true optional: true + /esbuild-netbsd-64/0.15.13: + resolution: {integrity: sha512-EHj9QZOTel581JPj7UO3xYbltFTYnHy+SIqJVq6yd3KkCrsHRbapiPb0Lx3EOOtybBEE9EyqbmfW1NlSDsSzvQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + requiresBuild: true + dev: true + optional: true + /esbuild-openbsd-64/0.14.49: resolution: {integrity: sha512-lP06UQeLDGmVPw9Rg437Btu6J9/BmyhdoefnQ4gDEJTtJvKtQaUcOQrhjTq455ouZN4EHFH1h28WOJVANK41kA==} engines: {node: '>=12'} @@ -3880,6 +4213,15 @@ packages: dev: true optional: true + /esbuild-openbsd-64/0.15.13: + resolution: {integrity: sha512-nkuDlIjF/sfUhfx8SKq0+U+Fgx5K9JcPq1mUodnxI0x4kBdCv46rOGWbuJ6eof2n3wdoCLccOoJAbg9ba/bT2w==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + requiresBuild: true + dev: true + optional: true + /esbuild-register/3.4.2_esbuild@0.16.12: resolution: {integrity: sha512-kG/XyTDyz6+YDuyfB9ZoSIOOmgyFCH+xPRtsCa8W85HLRV5Csp+o3jWVbOSHgSLfyLc5DmP+KFDNwty4mEjC+Q==} peerDependencies: @@ -3909,6 +4251,15 @@ packages: dev: true optional: true + /esbuild-sunos-64/0.15.13: + resolution: {integrity: sha512-jVeu2GfxZQ++6lRdY43CS0Tm/r4WuQQ0Pdsrxbw+aOrHQPHV0+LNOLnvbN28M7BSUGnJnHkHm2HozGgNGyeIRw==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + requiresBuild: true + dev: true + optional: true + /esbuild-windows-32/0.14.49: resolution: {integrity: sha512-q7Rb+J9yHTeKr9QTPDYkqfkEj8/kcKz9lOabDuvEXpXuIcosWCJgo5Z7h/L4r7rbtTH4a8U2FGKb6s1eeOHmJA==} engines: {node: '>=12'} @@ -3927,6 +4278,15 @@ packages: dev: true optional: true + /esbuild-windows-32/0.15.13: + resolution: {integrity: sha512-XoF2iBf0wnqo16SDq+aDGi/+QbaLFpkiRarPVssMh9KYbFNCqPLlGAWwDvxEVz+ywX6Si37J2AKm+AXq1kC0JA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + /esbuild-windows-64/0.14.49: resolution: {integrity: sha512-+Cme7Ongv0UIUTniPqfTX6mJ8Deo7VXw9xN0yJEN1lQMHDppTNmKwAM3oGbD/Vqff+07K2gN0WfNkMohmG+dVw==} engines: {node: '>=12'} @@ -3945,6 +4305,15 @@ packages: dev: true optional: true + /esbuild-windows-64/0.15.13: + resolution: {integrity: sha512-Et6htEfGycjDrtqb2ng6nT+baesZPYQIW+HUEHK4D1ncggNrDNk3yoboYQ5KtiVrw/JaDMNttz8rrPubV/fvPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /esbuild-windows-arm64/0.14.49: resolution: {integrity: sha512-v+HYNAXzuANrCbbLFJ5nmO3m5y2PGZWLe3uloAkLt87aXiO2mZr3BTmacZdjwNkNEHuH3bNtN8cak+mzVjVPfA==} engines: {node: '>=12'} @@ -3963,6 +4332,15 @@ packages: dev: true optional: true + /esbuild-windows-arm64/0.15.13: + resolution: {integrity: sha512-3bv7tqntThQC9SWLRouMDmZnlOukBhOCTlkzNqzGCmrkCJI7io5LLjwJBOVY6kOUlIvdxbooNZwjtBvj+7uuVg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /esbuild/0.14.49: resolution: {integrity: sha512-/TlVHhOaq7Yz8N1OJrjqM3Auzo5wjvHFLk+T8pIue+fhnhIMpfAzsG6PLVMbFveVxqD2WOp3QHei+52IMUNmCw==} engines: {node: '>=12'} @@ -4021,6 +4399,36 @@ packages: esbuild-windows-arm64: 0.15.12 dev: true + /esbuild/0.15.13: + resolution: {integrity: sha512-Cu3SC84oyzzhrK/YyN4iEVy2jZu5t2fz66HEOShHURcjSkOSAVL8C/gfUT+lDJxkVHpg8GZ10DD0rMHRPqMFaQ==} + engines: {node: '>=12'} + hasBin: true + requiresBuild: true + optionalDependencies: + '@esbuild/android-arm': 0.15.13 + '@esbuild/linux-loong64': 0.15.13 + esbuild-android-64: 0.15.13 + esbuild-android-arm64: 0.15.13 + esbuild-darwin-64: 0.15.13 + esbuild-darwin-arm64: 0.15.13 + esbuild-freebsd-64: 0.15.13 + esbuild-freebsd-arm64: 0.15.13 + esbuild-linux-32: 0.15.13 + esbuild-linux-64: 0.15.13 + esbuild-linux-arm: 0.15.13 + esbuild-linux-arm64: 0.15.13 + esbuild-linux-mips64le: 0.15.13 + esbuild-linux-ppc64le: 0.15.13 + esbuild-linux-riscv64: 0.15.13 + esbuild-linux-s390x: 0.15.13 + esbuild-netbsd-64: 0.15.13 + esbuild-openbsd-64: 0.15.13 + esbuild-sunos-64: 0.15.13 + esbuild-windows-32: 0.15.13 + esbuild-windows-64: 0.15.13 + esbuild-windows-arm64: 0.15.13 + dev: true + /esbuild/0.16.12: resolution: {integrity: sha512-eq5KcuXajf2OmivCl4e89AD3j8fbV+UTE9vczEzq5haA07U9oOTzBWlh3+6ZdjJR7Rz2QfWZ2uxZyhZxBgJ4+g==} engines: {node: '>=12'} @@ -4480,6 +4888,11 @@ packages: number-to-bn: 1.7.0 dev: true + /event-target-shim/5.0.1: + resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} + engines: {node: '>=6'} + dev: true + /eventemitter3/4.0.4: resolution: {integrity: sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==} dev: true @@ -4627,6 +5040,14 @@ packages: dependencies: reusify: 1.0.4 + /fetch-blob/3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.2.1 + dev: true + /file-entry-cache/6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -4683,6 +5104,14 @@ packages: path-exists: 4.0.0 dev: true + /find-up/6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + locate-path: 7.1.1 + path-exists: 5.0.0 + dev: true + /find-yarn-workspace-root2/1.2.16: resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==} dependencies: @@ -4749,6 +5178,13 @@ packages: mime-types: 2.1.35 dev: true + /formdata-polyfill/4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + dependencies: + fetch-blob: 3.2.0 + dev: true + /forwarded/0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -4940,6 +5376,17 @@ packages: merge2: 1.4.1 slash: 3.0.0 + /globby/13.1.3: + resolution: {integrity: sha512-8krCNHXvlCgHDpegPzleMq07yMYTO2sXKASmZmquEYWEmCx6J5UTRbp5RwMJkTJGtcQ44YpiUYUiN0b9mzy8Bw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.2.12 + ignore: 5.2.0 + merge2: 1.4.1 + slash: 4.0.0 + dev: true + /got/11.8.6: resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} engines: {node: '>=10.19.0'} @@ -5058,6 +5505,13 @@ packages: inherits: 2.0.4 minimalistic-assert: 1.0.1 + /header-case/2.0.4: + resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==} + dependencies: + capital-case: 1.0.4 + tslib: 2.4.0 + dev: true + /hmac-drbg/1.0.1: resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} dependencies: @@ -5321,6 +5775,11 @@ packages: engines: {node: '>=6.5.0', npm: '>=3'} dev: true + /is-interactive/2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + dev: true + /is-map/2.0.2: resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} dev: true @@ -5412,6 +5871,11 @@ packages: /is-typedarray/1.0.0: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + /is-unicode-supported/1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + dev: true + /is-weakmap/2.0.1: resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} dev: true @@ -5770,6 +6234,13 @@ packages: p-locate: 5.0.0 dev: true + /locate-path/7.1.1: + resolution: {integrity: sha512-vJXaRMJgRVD3+cUZs3Mncj2mxpt5mP0EmNOsxRSZRMlbqjvxzDEOIUWXGmavo0ZC9+tNZCBLQ66reA11nbpHZg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + p-locate: 6.0.0 + dev: true + /lodash.merge/4.6.2: resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} @@ -5785,6 +6256,14 @@ packages: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} dev: true + /log-symbols/5.1.0: + resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} + engines: {node: '>=12'} + dependencies: + chalk: 5.2.0 + is-unicode-supported: 1.3.0 + dev: true + /loose-envify/1.4.0: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true @@ -5797,6 +6276,12 @@ packages: get-func-name: 2.0.0 dev: true + /lower-case/2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + dependencies: + tslib: 2.4.0 + dev: true + /lowercase-keys/2.0.0: resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} @@ -6147,10 +6632,22 @@ packages: - babel-plugin-macros dev: false + /no-case/3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + dependencies: + lower-case: 2.0.2 + tslib: 2.4.0 + dev: true + /node-addon-api/2.0.2: resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} dev: true + /node-domexception/1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + dev: true + /node-fetch/2.6.7: resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} engines: {node: 4.x || >=6.0.0} @@ -6162,6 +6659,15 @@ packages: dependencies: whatwg-url: 5.0.0 + /node-fetch/3.3.0: + resolution: {integrity: sha512-BKwRP/O0UvoMKp7GNdwPlObhYGB5DQqwhEDQlNKuoqwVYSxkSZCSbHjnFFmUEtwSKRPU4kNK8PbDYYitwaE3QA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + dev: true + /node-gyp-build/4.5.0: resolution: {integrity: sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==} hasBin: true @@ -6348,6 +6854,21 @@ packages: type-check: 0.4.0 word-wrap: 1.2.3 + /ora/6.1.2: + resolution: {integrity: sha512-EJQ3NiP5Xo94wJXIzAyOtSb0QEIAUu7m8t6UZ9krbz0vAJqr92JpcK/lEXg91q6B9pEGqrykkd2EQplnifDSBw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + bl: 5.1.0 + chalk: 5.2.0 + cli-cursor: 4.0.0 + cli-spinners: 2.7.0 + is-interactive: 2.0.0 + is-unicode-supported: 1.3.0 + log-symbols: 5.1.0 + strip-ansi: 7.0.1 + wcwidth: 1.0.1 + dev: true + /os-tmpdir/1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -6393,6 +6914,13 @@ packages: yocto-queue: 0.1.0 dev: true + /p-limit/4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + yocto-queue: 1.0.0 + dev: true + /p-locate/2.0.0: resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} engines: {node: '>=4'} @@ -6420,6 +6948,13 @@ packages: p-limit: 3.1.0 dev: true + /p-locate/6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + p-limit: 4.0.0 + dev: true + /p-map/2.1.0: resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} engines: {node: '>=6'} @@ -6433,6 +6968,13 @@ packages: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} + /param-case/3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + dependencies: + dot-case: 3.0.4 + tslib: 2.4.0 + dev: true + /parent-module/1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -6474,6 +7016,20 @@ packages: engines: {node: '>= 0.8'} dev: true + /pascal-case/3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + dependencies: + no-case: 3.0.4 + tslib: 2.4.0 + dev: true + + /path-case/3.0.4: + resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==} + dependencies: + dot-case: 3.0.4 + tslib: 2.4.0 + dev: true + /path-exists/3.0.0: resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} engines: {node: '>=4'} @@ -6483,6 +7039,11 @@ packages: engines: {node: '>=8'} dev: true + /path-exists/5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + /path-is-absolute/1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} @@ -6507,6 +7068,10 @@ packages: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} + /pathe/1.1.0: + resolution: {integrity: sha512-ODbEPR0KKHqECXW1GoxdDb+AZvULmXjVPy4rt+pGo2+TnjJTIPJQSVS6N63n8T2Ip+syHhbn52OewKicV0373w==} + dev: true + /pathval/1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} dev: true @@ -6692,6 +7257,12 @@ packages: hasBin: true dev: true + /prettier/2.8.3: + resolution: {integrity: sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + /pretty-format/29.2.1: resolution: {integrity: sha512-Y41Sa4aLCtKAXvwuIpTvcFBkyeYp2gdFWzXGA+ZNES3VwURIB165XO/z7CjETwzCCS53MjW/rLMyyqEnTtaOfA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -7007,6 +7578,14 @@ packages: lowercase-keys: 2.0.0 dev: true + /restore-cursor/4.0.0: + resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: true + /reusify/1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -7152,6 +7731,14 @@ packages: - supports-color dev: true + /sentence-case/3.0.4: + resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} + dependencies: + no-case: 3.0.4 + tslib: 2.4.0 + upper-case-first: 2.0.2 + dev: true + /serve-static/1.15.0: resolution: {integrity: sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==} engines: {node: '>= 0.8.0'} @@ -7277,6 +7864,11 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + /slash/4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + dev: true + /smartwrap/2.0.2: resolution: {integrity: sha512-vCsKNQxb7PnCNd2wY1WClWifAc2lwqsG8OaswpJkVJsvMGcnEntdTCDajZCkk93Ay1U3t/9puJmb525Rg5MZBA==} engines: {node: '>=6'} @@ -7290,6 +7882,13 @@ packages: yargs: 15.4.1 dev: true + /snake-case/3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + dependencies: + dot-case: 3.0.4 + tslib: 2.4.0 + dev: true + /source-map-js/1.0.2: resolution: {integrity: sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==} engines: {node: '>=0.10.0'} @@ -7457,6 +8056,13 @@ packages: dependencies: ansi-regex: 5.0.1 + /strip-ansi/7.0.1: + resolution: {integrity: sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==} + engines: {node: '>=12'} + dependencies: + ansi-regex: 6.0.1 + dev: true + /strip-bom/3.0.0: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} @@ -7943,6 +8549,18 @@ packages: picocolors: 1.0.0 dev: true + /upper-case-first/2.0.2: + resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} + dependencies: + tslib: 2.4.0 + dev: true + + /upper-case/2.0.2: + resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==} + dependencies: + tslib: 2.4.0 + dev: true + /uri-js/4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} dependencies: @@ -8273,6 +8891,11 @@ packages: defaults: 1.0.3 dev: true + /web-streams-polyfill/3.2.1: + resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} + engines: {node: '>= 8'} + dev: true + /web3-bzz/1.8.1: resolution: {integrity: sha512-dJJHS84nvpoxv6ijTMkdUSlRr5beCXNtx4UZcrFLHBva8dT63QEtKdLyDt2AyMJJdVzTCk78uir/6XtVWrdS6w==} engines: {node: '>=8.0.0'} @@ -8950,3 +9573,12 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true + + /yocto-queue/1.0.0: + resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} + engines: {node: '>=12.20'} + dev: true + + /zod/3.20.2: + resolution: {integrity: sha512-1MzNQdAvO+54H+EaK5YpyEy0T+Ejo/7YLHS93G3RnYWh5gaotGHwGeN/ZO687qEDU2y4CdStQYXVHIgrUl5UVQ==} + dev: true diff --git a/src/_test/index.ts b/src/_test/index.ts index b234fc8673..25ac367935 100644 --- a/src/_test/index.ts +++ b/src/_test/index.ts @@ -17,6 +17,8 @@ export { export { createHttpServer, + deploy, + deployBAYC, publicClient, testClient, walletClient, diff --git a/src/_test/utils.ts b/src/_test/utils.ts index 4ce97e1792..8a397d5a8b 100644 --- a/src/_test/utils.ts +++ b/src/_test/utils.ts @@ -1,5 +1,13 @@ /* c8 ignore start */ -import { localhost } from '../chains' +import { Abi } from 'abitype' +import errorsExample from '../../contracts/out/ErrorsExample.sol/ErrorsExample.json' +import { + deployContract, + DeployContractArgs, + getTransactionReceipt, + mine, +} from '../actions' +import { Chain, localhost } from '../chains' import { createPublicClient, createTestClient, @@ -11,10 +19,13 @@ import { import { rpc } from '../utils' import { RpcError } from '../types/eip1193' import { accounts, localWsUrl } from './constants' +import { errorsExampleABI } from './generated' import type { RequestListener } from 'http' import { createServer } from 'http' import type { AddressInfo } from 'net' +import { baycContractConfig } from './abis' +import { Hex } from '../types' export const publicClient = process.env.VITE_NETWORK_TRANSPORT_MODE === 'webSocket' @@ -109,4 +120,31 @@ export function createHttpServer( }) }) } + +export async function deploy( + args: DeployContractArgs, +) { + const hash = await deployContract(walletClient, args) + await mine(testClient, { blocks: 1 }) + const { contractAddress } = await getTransactionReceipt(publicClient, { + hash, + }) + return { contractAddress } +} + +export async function deployBAYC() { + return deploy({ + ...baycContractConfig, + args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], + from: accounts[0].address, + }) +} + +export async function deployErrorExample() { + return deploy({ + abi: errorsExampleABI, + bytecode: errorsExample.bytecode.object as Hex, + from: accounts[0].address, + }) +} /* c8 ignore stop */ diff --git a/src/actions/public/multicall.test.ts b/src/actions/public/multicall.test.ts index 5bc2da19e4..7aa07e854f 100644 --- a/src/actions/public/multicall.test.ts +++ b/src/actions/public/multicall.test.ts @@ -2,8 +2,6 @@ * TODO: Heaps more test cases :D * - Complex calldata types * - Complex return types (tuple/structs) - * - Calls against blocks - * - Reverts (custom errors/Error(string)/Panic(uint256)) */ import { describe, expect, test } from 'vitest' diff --git a/src/actions/public/multicall.ts b/src/actions/public/multicall.ts index 668c59a63f..ff0cee90f6 100644 --- a/src/actions/public/multicall.ts +++ b/src/actions/public/multicall.ts @@ -1,6 +1,6 @@ import { PublicClient } from '../../clients' import { multicall3Abi } from '../../constants' -import { BaseError, RawContractError } from '../../errors' +import { AbiDecodingZeroDataError, BaseError, RawContractError } from '../../errors' import { Address, ContractConfig, Hex, MulticallContracts } from '../../types' import { MulticallResults } from '../../types/multicall' import { @@ -28,7 +28,13 @@ export async function multicall< client: PublicClient, args: MulticallArgs, ): Promise> { - const { allowFailure = true, contracts, multicallAddress } = args + const { + allowFailure = true, + blockNumber, + blockTag, + contracts, + multicallAddress, + } = args const calls = contracts.map(({ abi, address, args, functionName }) => { try { @@ -62,11 +68,15 @@ export async function multicall< abi: multicall3Abi, address: multicallAddress, args: [calls], + blockNumber, + blockTag, functionName: 'aggregate3', }) return results.map(({ returnData, success }, i) => { + const { callData } = calls[i] const { abi, address, functionName, args } = contracts[i] try { + if (callData === '0x') throw new AbiDecodingZeroDataError() if (!success) throw new RawContractError({ data: returnData }) const result = decodeFunctionResult({ abi, diff --git a/src/actions/public/readContract.test.ts b/src/actions/public/readContract.test.ts index b6f7972df1..097946eccb 100644 --- a/src/actions/public/readContract.test.ts +++ b/src/actions/public/readContract.test.ts @@ -3,24 +3,19 @@ * - Complex calldata types * - Complex return types (tuple/structs) * - Calls against blocks - * - Reverts (custom errors/Error(string)/Panic(uint256)) */ import { describe, expect, test } from 'vitest' import { - accounts, initialBlockNumber, publicClient, - testClient, vitalikAddress, wagmiContractConfig, - walletClient, } from '../../_test' import { baycContractConfig } from '../../_test/abis' -import { mine } from '../test' +import { errorsExampleABI } from '../../_test/generated' +import { deployErrorExample } from '../../_test/utils' -import { deployContract } from './deployContract' -import { getTransactionReceipt } from './getTransactionReceipt' import { readContract } from './readContract' describe('wagmi', () => { @@ -156,6 +151,159 @@ describe('bayc', () => { }) }) +describe('contract errors', () => { + test('revert', async () => { + const { contractAddress } = await deployErrorExample() + + await expect(() => + readContract(publicClient, { + abi: errorsExampleABI, + address: contractAddress!, + functionName: 'revertRead', + }), + ).rejects.toMatchInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "revertRead" reverted with the following reason: + This is a revert message + + Contract: 0x0000000000000000000000000000000000000000 + Function: revertRead() + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@1.0.2] + `) + }) + + test('assert', async () => { + const { contractAddress } = await deployErrorExample() + + await expect(() => + readContract(publicClient, { + abi: errorsExampleABI, + address: contractAddress!, + functionName: 'assertRead', + }), + ).rejects.toMatchInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "assertRead" reverted with the following reason: + An \`assert\` condition failed. + + Contract: 0x0000000000000000000000000000000000000000 + Function: assertRead() + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@1.0.2] + `) + }) + + test('overflow', async () => { + const { contractAddress } = await deployErrorExample() + + await expect(() => + readContract(publicClient, { + abi: errorsExampleABI, + address: contractAddress!, + functionName: 'overflowRead', + }), + ).rejects.toMatchInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "overflowRead" reverted with the following reason: + Arithmic operation resulted in underflow or overflow. + + Contract: 0x0000000000000000000000000000000000000000 + Function: overflowRead() + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@1.0.2] + `) + }) + + test('divide by zero', async () => { + const { contractAddress } = await deployErrorExample() + + await expect(() => + readContract(publicClient, { + abi: errorsExampleABI, + address: contractAddress!, + functionName: 'divideByZeroRead', + }), + ).rejects.toMatchInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "divideByZeroRead" reverted with the following reason: + Division or modulo by zero (e.g. \`5 / 0\` or \`23 % 0\`). + + Contract: 0x0000000000000000000000000000000000000000 + Function: divideByZeroRead() + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@1.0.2] + `) + }) + + test('require', async () => { + const { contractAddress } = await deployErrorExample() + + await expect(() => + readContract(publicClient, { + abi: errorsExampleABI, + address: contractAddress!, + functionName: 'requireRead', + }), + ).rejects.toMatchInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "requireRead" reverted with the following reason: + execution reverted + + Contract: 0x0000000000000000000000000000000000000000 + Function: requireRead() + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@1.0.2] + `) + }) + + test('custom error: simple', async () => { + const { contractAddress } = await deployErrorExample() + + await expect(() => + readContract(publicClient, { + abi: errorsExampleABI, + address: contractAddress!, + functionName: 'simpleCustomRead', + }), + ).rejects.toMatchInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "simpleCustomRead" reverted. + + Error: SimpleError(string message) + Arguments: (bugger) + + Contract: 0x0000000000000000000000000000000000000000 + Function: simpleCustomRead() + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@1.0.2] + `) + }) + + test('custom error: complex', async () => { + const { contractAddress } = await deployErrorExample() + + await expect(() => + readContract(publicClient, { + abi: errorsExampleABI, + address: contractAddress!, + functionName: 'complexCustomRead', + }), + ).rejects.toMatchInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "complexCustomRead" reverted. + + Error: ComplexError((address sender, uint256 bar), string message, uint256 number) + Arguments: ({"sender":"0x0000000000000000000000000000000000000000","bar":"69"}, bugger, 69) + + Contract: 0x0000000000000000000000000000000000000000 + Function: complexCustomRead() + + Docs: https://viem.sh/docs/contract/readContract + Version: viem@1.0.2] + `) + }) +}) + test('fake contract address', async () => { await expect(() => readContract(publicClient, { @@ -178,17 +326,3 @@ test('fake contract address', async () => { Version: viem@1.0.2" `) }) - -// Deploy BAYC Contract -async function deployBAYC() { - const hash = await deployContract(walletClient, { - ...baycContractConfig, - args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], - from: accounts[0].address, - }) - await mine(testClient, { blocks: 1 }) - const { contractAddress } = await getTransactionReceipt(publicClient, { - hash, - }) - return { contractAddress } -} diff --git a/src/actions/public/simulateContract.test.ts b/src/actions/public/simulateContract.test.ts index 181b2734b2..a6c4a314ba 100644 --- a/src/actions/public/simulateContract.test.ts +++ b/src/actions/public/simulateContract.test.ts @@ -6,12 +6,12 @@ * - Calls against blocks * - Custom chain types * - Custom nonce - * - More reverts (custom errors/Error(string)/Panic(uint256)) */ import { describe, expect, test } from 'vitest' import { accounts, + deployBAYC, publicClient, testClient, wagmiContractConfig, @@ -22,9 +22,9 @@ import { encodeFunctionData } from '../../utils' import { mine } from '../test' import { sendTransaction } from '../wallet' -import { deployContract } from './deployContract' -import { getTransactionReceipt } from './getTransactionReceipt' import { simulateContract } from './simulateContract' +import { deployErrorExample } from '../../_test/utils' +import { errorsExampleABI } from '../../_test/generated' describe('wagmi', () => { test('default', async () => { @@ -209,6 +209,173 @@ describe('BAYC', () => { }) }) +describe('contract errors', () => { + test('revert', async () => { + const { contractAddress } = await deployErrorExample() + + await expect(() => + simulateContract(publicClient, { + abi: errorsExampleABI, + address: contractAddress!, + functionName: 'revertWrite', + from: accounts[0].address, + }), + ).rejects.toMatchInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "revertWrite" reverted with the following reason: + This is a revert message + + Contract: 0x0000000000000000000000000000000000000000 + Function: revertWrite() + Sender: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 + + Docs: https://viem.sh/docs/contract/simulateContract + Version: viem@1.0.2] + `) + }) + + test('assert', async () => { + const { contractAddress } = await deployErrorExample() + + await expect(() => + simulateContract(publicClient, { + abi: errorsExampleABI, + address: contractAddress!, + functionName: 'assertWrite', + from: accounts[0].address, + }), + ).rejects.toMatchInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "assertWrite" reverted with the following reason: + An \`assert\` condition failed. + + Contract: 0x0000000000000000000000000000000000000000 + Function: assertWrite() + Sender: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 + + Docs: https://viem.sh/docs/contract/simulateContract + Version: viem@1.0.2] + `) + }) + + test('overflow', async () => { + const { contractAddress } = await deployErrorExample() + + await expect(() => + simulateContract(publicClient, { + abi: errorsExampleABI, + address: contractAddress!, + functionName: 'overflowWrite', + from: accounts[0].address, + }), + ).rejects.toMatchInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "overflowWrite" reverted with the following reason: + Arithmic operation resulted in underflow or overflow. + + Contract: 0x0000000000000000000000000000000000000000 + Function: overflowWrite() + Sender: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 + + Docs: https://viem.sh/docs/contract/simulateContract + Version: viem@1.0.2] + `) + }) + + test('divide by zero', async () => { + const { contractAddress } = await deployErrorExample() + + await expect(() => + simulateContract(publicClient, { + abi: errorsExampleABI, + address: contractAddress!, + functionName: 'divideByZeroWrite', + from: accounts[0].address, + }), + ).rejects.toMatchInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "divideByZeroWrite" reverted with the following reason: + Division or modulo by zero (e.g. \`5 / 0\` or \`23 % 0\`). + + Contract: 0x0000000000000000000000000000000000000000 + Function: divideByZeroWrite() + Sender: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 + + Docs: https://viem.sh/docs/contract/simulateContract + Version: viem@1.0.2] + `) + }) + + test('require', async () => { + const { contractAddress } = await deployErrorExample() + + await expect(() => + simulateContract(publicClient, { + abi: errorsExampleABI, + address: contractAddress!, + functionName: 'requireWrite', + from: accounts[0].address, + }), + ).rejects.toMatchInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "requireWrite" reverted with the following reason: + execution reverted + + Contract: 0x0000000000000000000000000000000000000000 + Function: requireWrite() + Sender: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 + + Docs: https://viem.sh/docs/contract/simulateContract + Version: viem@1.0.2] + `) + }) + + test('custom error: simple', async () => { + const { contractAddress } = await deployErrorExample() + + await expect(() => + simulateContract(publicClient, { + abi: errorsExampleABI, + address: contractAddress!, + functionName: 'simpleCustomWrite', + from: accounts[0].address, + }), + ).rejects.toMatchInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "simpleCustomWrite" reverted. + + Error: SimpleError(string message) + Arguments: (bugger) + + Contract: 0x0000000000000000000000000000000000000000 + Function: simpleCustomWrite() + Sender: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 + + Docs: https://viem.sh/docs/contract/simulateContract + Version: viem@1.0.2] + `) + }) + + test('custom error: complex', async () => { + const { contractAddress } = await deployErrorExample() + + await expect(() => + simulateContract(publicClient, { + abi: errorsExampleABI, + address: contractAddress!, + functionName: 'complexCustomWrite', + from: accounts[0].address, + }), + ).rejects.toMatchInlineSnapshot(` + [ContractFunctionExecutionError: The contract function "complexCustomWrite" reverted. + + Error: ComplexError((address sender, uint256 bar), string message, uint256 number) + Arguments: ({"sender":"0x0000000000000000000000000000000000000000","bar":"69"}, bugger, 69) + + Contract: 0x0000000000000000000000000000000000000000 + Function: complexCustomWrite() + Sender: 0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266 + + Docs: https://viem.sh/docs/contract/simulateContract + Version: viem@1.0.2] + `) + }) +}) + test('fake contract address', async () => { await expect(() => simulateContract(publicClient, { @@ -242,17 +409,3 @@ test('fake contract address', async () => { Version: viem@1.0.2" `) }) - -// Deploy BAYC Contract -async function deployBAYC() { - const hash = await deployContract(walletClient, { - ...baycContractConfig, - args: ['Bored Ape Wagmi Club', 'BAYC', 69420n, 0n], - from: accounts[0].address, - }) - await mine(testClient, { blocks: 1 }) - const { contractAddress } = await getTransactionReceipt(publicClient, { - hash, - }) - return { contractAddress } -} diff --git a/src/constants/abis.test.ts b/src/constants/abis.test.ts index 946f2bf20e..f506aa7176 100644 --- a/src/constants/abis.test.ts +++ b/src/constants/abis.test.ts @@ -1,6 +1,6 @@ import { expect, test } from 'vitest' -import * as abis from './index' +import * as abis from './abis' test('exports abis', () => { expect(abis).toMatchInlineSnapshot(` diff --git a/src/constants/abis.ts b/src/constants/abis.ts index 4e27fe123b..f62b14a64a 100644 --- a/src/constants/abis.ts +++ b/src/constants/abis.ts @@ -42,515 +42,3 @@ export const multicall3Abi = [ type: 'function', }, ] as const - -/** - * [ERC-4626 Tokenized Vaults Standard](https://ethereum.org/en/developers/docs/standards/tokens/erc-4626) - */ -export const erc4626ABI = [ - { - anonymous: false, - inputs: [ - { - indexed: true, - name: 'owner', - type: 'address', - }, - { - indexed: true, - name: 'spender', - type: 'address', - }, - { - indexed: false, - name: 'value', - type: 'uint256', - }, - ], - name: 'Approval', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - name: 'sender', - type: 'address', - }, - { - indexed: true, - name: 'receiver', - type: 'address', - }, - { - indexed: false, - name: 'assets', - type: 'uint256', - }, - { - indexed: false, - name: 'shares', - type: 'uint256', - }, - ], - name: 'Deposit', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - name: 'from', - type: 'address', - }, - { - indexed: true, - name: 'to', - type: 'address', - }, - { - indexed: false, - name: 'value', - type: 'uint256', - }, - ], - name: 'Transfer', - type: 'event', - }, - { - anonymous: false, - inputs: [ - { - indexed: true, - name: 'sender', - type: 'address', - }, - { - indexed: true, - name: 'receiver', - type: 'address', - }, - { - indexed: true, - name: 'owner', - type: 'address', - }, - { - indexed: false, - name: 'assets', - type: 'uint256', - }, - { - indexed: false, - name: 'shares', - type: 'uint256', - }, - ], - name: 'Withdraw', - type: 'event', - }, - { - inputs: [ - { - name: 'owner', - type: 'address', - }, - { - name: 'spender', - type: 'address', - }, - ], - name: 'allowance', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - name: 'spender', - type: 'address', - }, - { - name: 'amount', - type: 'uint256', - }, - ], - name: 'approve', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'asset', - outputs: [ - { - name: 'assetTokenAddress', - type: 'address', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - name: 'account', - type: 'address', - }, - ], - name: 'balanceOf', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - name: 'shares', - type: 'uint256', - }, - ], - name: 'convertToAssets', - outputs: [ - { - name: 'assets', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - name: 'assets', - type: 'uint256', - }, - ], - name: 'convertToShares', - outputs: [ - { - name: 'shares', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - name: 'assets', - type: 'uint256', - }, - { - name: 'receiver', - type: 'address', - }, - ], - name: 'deposit', - outputs: [ - { - name: 'shares', - type: 'uint256', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - name: 'caller', - type: 'address', - }, - ], - name: 'maxDeposit', - outputs: [ - { - name: 'maxAssets', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - name: 'caller', - type: 'address', - }, - ], - name: 'maxMint', - outputs: [ - { - name: 'maxShares', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - name: 'owner', - type: 'address', - }, - ], - name: 'maxRedeem', - outputs: [ - { - name: 'maxShares', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - name: 'owner', - type: 'address', - }, - ], - name: 'maxWithdraw', - outputs: [ - { - name: 'maxAssets', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - name: 'shares', - type: 'uint256', - }, - { - name: 'receiver', - type: 'address', - }, - ], - name: 'mint', - outputs: [ - { - name: 'assets', - type: 'uint256', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - name: 'assets', - type: 'uint256', - }, - ], - name: 'previewDeposit', - outputs: [ - { - name: 'shares', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - name: 'shares', - type: 'uint256', - }, - ], - name: 'previewMint', - outputs: [ - { - name: 'assets', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - name: 'shares', - type: 'uint256', - }, - ], - name: 'previewRedeem', - outputs: [ - { - name: 'assets', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - name: 'assets', - type: 'uint256', - }, - ], - name: 'previewWithdraw', - outputs: [ - { - name: 'shares', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - name: 'shares', - type: 'uint256', - }, - { - name: 'receiver', - type: 'address', - }, - { - name: 'owner', - type: 'address', - }, - ], - name: 'redeem', - outputs: [ - { - name: 'assets', - type: 'uint256', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [], - name: 'totalAssets', - outputs: [ - { - name: 'totalManagedAssets', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [], - name: 'totalSupply', - outputs: [ - { - name: '', - type: 'uint256', - }, - ], - stateMutability: 'view', - type: 'function', - }, - { - inputs: [ - { - name: 'to', - type: 'address', - }, - { - name: 'amount', - type: 'uint256', - }, - ], - name: 'transfer', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - name: 'from', - type: 'address', - }, - { - name: 'to', - type: 'address', - }, - { - name: 'amount', - type: 'uint256', - }, - ], - name: 'transferFrom', - outputs: [ - { - name: '', - type: 'bool', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, - { - inputs: [ - { - name: 'assets', - type: 'uint256', - }, - { - name: 'receiver', - type: 'address', - }, - { - name: 'owner', - type: 'address', - }, - ], - name: 'withdraw', - outputs: [ - { - name: 'shares', - type: 'uint256', - }, - ], - stateMutability: 'nonpayable', - type: 'function', - }, -] as const diff --git a/src/constants/index.test.ts b/src/constants/index.test.ts index e74b36772a..33bd7822d2 100644 --- a/src/constants/index.test.ts +++ b/src/constants/index.test.ts @@ -48,6 +48,39 @@ test('exports clients', () => { "type": "function", }, ], + "panicReasons": { + "1": "An \`assert\` condition failed.", + "17": "Arithmic operation resulted in underflow or overflow.", + "18": "Division or modulo by zero (e.g. \`5 / 0\` or \`23 % 0\`).", + "33": "Attempted to convert to an invalid type.", + "34": "Attempted to access a storage byte array that is incorrectly encoded.", + "49": "Performed \`.pop()\` on an empty array", + "50": "Array index is out of bounds.", + "65": "Allocated too much memory or created an array which is too large.", + "81": "Attempted to call a zero-initialized variable of internal function type.", + }, + "solidityError": { + "inputs": [ + { + "internalType": "string", + "name": "message", + "type": "string", + }, + ], + "name": "Error", + "type": "error", + }, + "solidityPanic": { + "inputs": [ + { + "internalType": "uint256", + "name": "reason", + "type": "uint256", + }, + ], + "name": "Panic", + "type": "error", + }, } `) }) diff --git a/src/constants/index.ts b/src/constants/index.ts index 2c3c02e53f..33a54763fa 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1 +1,3 @@ export { multicall3Abi } from './abis' + +export { panicReasons, solidityError, solidityPanic } from './solidity' \ No newline at end of file diff --git a/src/constants/solidity.test.ts b/src/constants/solidity.test.ts new file mode 100644 index 0000000000..4b314f419f --- /dev/null +++ b/src/constants/solidity.test.ts @@ -0,0 +1,43 @@ +import { expect, test } from 'vitest' + +import * as solidity from './solidity' + +test('exports solidity constants', () => { + expect(solidity).toMatchInlineSnapshot(` + { + "panicReasons": { + "1": "An \`assert\` condition failed.", + "17": "Arithmic operation resulted in underflow or overflow.", + "18": "Division or modulo by zero (e.g. \`5 / 0\` or \`23 % 0\`).", + "33": "Attempted to convert to an invalid type.", + "34": "Attempted to access a storage byte array that is incorrectly encoded.", + "49": "Performed \`.pop()\` on an empty array", + "50": "Array index is out of bounds.", + "65": "Allocated too much memory or created an array which is too large.", + "81": "Attempted to call a zero-initialized variable of internal function type.", + }, + "solidityError": { + "inputs": [ + { + "internalType": "string", + "name": "message", + "type": "string", + }, + ], + "name": "Error", + "type": "error", + }, + "solidityPanic": { + "inputs": [ + { + "internalType": "uint256", + "name": "reason", + "type": "uint256", + }, + ], + "name": "Panic", + "type": "error", + }, + } + `) +}) diff --git a/src/constants/solidity.ts b/src/constants/solidity.ts new file mode 100644 index 0000000000..67cba2cf9d --- /dev/null +++ b/src/constants/solidity.ts @@ -0,0 +1,37 @@ +import { AbiError } from 'abitype' + +// https://docs.soliditylang.org/en/v0.8.16/control-structures.html#panic-via-assert-and-error-via-require +export const panicReasons = { + 1: 'An `assert` condition failed.', + 17: 'Arithmic operation resulted in underflow or overflow.', + 18: 'Division or modulo by zero (e.g. `5 / 0` or `23 % 0`).', + 33: 'Attempted to convert to an invalid type.', + 34: 'Attempted to access a storage byte array that is incorrectly encoded.', + 49: 'Performed `.pop()` on an empty array', + 50: 'Array index is out of bounds.', + 65: 'Allocated too much memory or created an array which is too large.', + 81: 'Attempted to call a zero-initialized variable of internal function type.', +} as const + +export const solidityError: AbiError = { + inputs: [ + { + internalType: 'string', + name: 'message', + type: 'string', + }, + ], + name: 'Error', + type: 'error', +} +export const solidityPanic: AbiError = { + inputs: [ + { + internalType: 'uint256', + name: 'reason', + type: 'uint256', + }, + ], + name: 'Panic', + type: 'error', +} diff --git a/src/errors/contract.test.ts b/src/errors/contract.test.ts new file mode 100644 index 0000000000..0b7f9d86ed --- /dev/null +++ b/src/errors/contract.test.ts @@ -0,0 +1,233 @@ +import { describe, expect, test } from 'vitest' +import { baycContractConfig } from '../_test/abis' +import { errorsExampleABI } from '../_test/generated' +import { BaseError } from './base' +import { + ContractFunctionExecutionError, + ContractFunctionRevertedError, + RawContractError, +} from './contract' + +describe('ContractFunctionExecutionError', () => { + test('default', () => { + expect( + new ContractFunctionExecutionError(new BaseError('Internal error.'), { + abi: baycContractConfig.abi, + functionName: 'totalSupply', + }), + ).toMatchInlineSnapshot(` + [ContractFunctionExecutionError: Internal error. + + Function: totalSupply() + + Version: viem@1.0.2] + `) + }) + + test('args: contractAddress', () => { + expect( + new ContractFunctionExecutionError(new BaseError('Internal error.'), { + abi: baycContractConfig.abi, + functionName: 'totalSupply', + contractAddress: '0x0000000000000000000000000000000000000000', + }), + ).toMatchInlineSnapshot(` + [ContractFunctionExecutionError: Internal error. + + Contract: 0x0000000000000000000000000000000000000000 + Function: totalSupply() + + Version: viem@1.0.2] + `) + }) + + test('args: args', () => { + expect( + new ContractFunctionExecutionError(new BaseError('Internal error.'), { + abi: baycContractConfig.abi, + functionName: 'mintApe', + args: [1n], + contractAddress: '0x0000000000000000000000000000000000000000', + }), + ).toMatchInlineSnapshot(` + [ContractFunctionExecutionError: Internal error. + + Contract: 0x0000000000000000000000000000000000000000 + Function: mintApe(uint256 numberOfTokens) + Arguments: (1) + + Version: viem@1.0.2] + `) + }) + + test('args: docsPath', () => { + expect( + new ContractFunctionExecutionError(new BaseError('Internal error.'), { + abi: baycContractConfig.abi, + functionName: 'mintApe', + args: [1n], + contractAddress: '0x0000000000000000000000000000000000000000', + docsPath: '/docs', + }), + ).toMatchInlineSnapshot(` + [ContractFunctionExecutionError: Internal error. + + Contract: 0x0000000000000000000000000000000000000000 + Function: mintApe(uint256 numberOfTokens) + Arguments: (1) + + Docs: https://viem.sh/docs + Version: viem@1.0.2] + `) + }) + + test('args: sender', () => { + expect( + new ContractFunctionExecutionError(new BaseError('Internal error.'), { + abi: baycContractConfig.abi, + functionName: 'mintApe', + args: [1n], + contractAddress: '0x0000000000000000000000000000000000000000', + sender: '0x0000000000000000000000000000000000000000', + }), + ).toMatchInlineSnapshot(` + [ContractFunctionExecutionError: Internal error. + + Contract: 0x0000000000000000000000000000000000000000 + Function: mintApe(uint256 numberOfTokens) + Arguments: (1) + Sender: 0x0000000000000000000000000000000000000000 + + Version: viem@1.0.2] + `) + }) + + test('cause: metaMessages', () => { + expect( + new ContractFunctionExecutionError( + new BaseError('Internal error.', { metaMessages: ['foo', 'bar'] }), + { + abi: baycContractConfig.abi, + functionName: 'totalSupply', + contractAddress: '0x0000000000000000000000000000000000000000', + }, + ), + ).toMatchInlineSnapshot(` + [ContractFunctionExecutionError: Internal error. + + foo + bar + + Contract: 0x0000000000000000000000000000000000000000 + Function: totalSupply() + + Version: viem@1.0.2] + `) + }) + + test('no message', () => { + expect( + new ContractFunctionExecutionError(new BaseError(''), { + abi: baycContractConfig.abi, + functionName: 'foo', + }), + ).toMatchInlineSnapshot(` + [ContractFunctionExecutionError: An unknown error occurred while executing the contract function "foo". + + + Version: viem@1.0.2] + `) + }) + + test('function does not exist', () => { + expect( + new ContractFunctionExecutionError(new BaseError('Internal error.'), { + abi: baycContractConfig.abi, + functionName: 'foo', + }), + ).toMatchInlineSnapshot(` + [ContractFunctionExecutionError: Internal error. + + + Version: viem@1.0.2] + `) + }) +}) + +describe('ContractFunctionRevertedError', () => { + test('default', () => { + expect( + new ContractFunctionRevertedError({ + abi: errorsExampleABI, + message: 'oh no', + functionName: 'totalSupply', + }), + ).toMatchInlineSnapshot(` + [ContractFunctionRevertedError: The contract function "totalSupply" reverted with the following reason: + oh no + + Version: viem@1.0.2] + `) + }) + + test('data: Error(string)', () => { + expect( + new ContractFunctionRevertedError({ + abi: errorsExampleABI, + data: '0x08c379a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000022456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473000000000000000000000000000000000000000000000000000000000000', + functionName: 'totalSupply', + }), + ).toMatchInlineSnapshot(` + [ContractFunctionRevertedError: The contract function "totalSupply" reverted with the following reason: + EnumerableSet: index out of bounds + + Version: viem@1.0.2] + `) + }) + + test('data: Panic(uint256)', () => { + expect( + new ContractFunctionRevertedError({ + abi: errorsExampleABI, + data: '0x4e487b710000000000000000000000000000000000000000000000000000000000000001', + functionName: 'totalSupply', + }), + ).toMatchInlineSnapshot(` + [ContractFunctionRevertedError: The contract function "totalSupply" reverted with the following reason: + An \`assert\` condition failed. + + Version: viem@1.0.2] + `) + }) + + test('data: custom error', () => { + expect( + new ContractFunctionRevertedError({ + abi: errorsExampleABI, + data: '0xdb731cf4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000450000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000004500000000000000000000000000000000000000000000000000000000000000066275676765720000000000000000000000000000000000000000000000000000', + functionName: 'customComplexError', + }), + ).toMatchInlineSnapshot(` + [ContractFunctionRevertedError: The contract function "customComplexError" reverted. + + Error: ComplexError((address sender, uint256 bar), string message, uint256 number) + Arguments: ({"sender":"0x0000000000000000000000000000000000000000","bar":"69"}, bugger, 69) + + Version: viem@1.0.2] + `) + }) + + test('data: zero data', () => { + expect( + new ContractFunctionRevertedError({ + abi: errorsExampleABI, + data: '0x', + functionName: 'customComplexError', + }), + ).toMatchInlineSnapshot(` + [ContractFunctionRevertedError: The contract function "customComplexError" reverted. + + Version: viem@1.0.2] + `) + }) +}) diff --git a/src/errors/contract.ts b/src/errors/contract.ts index 62f823de78..ea63ed0590 100644 --- a/src/errors/contract.ts +++ b/src/errors/contract.ts @@ -1,15 +1,22 @@ import { Abi } from 'abitype' +import { panicReasons } from '../constants' import { Address, Hex } from '../types' -import { DecodeErrorResultResponse, decodeErrorResult } from '../utils' +import { + DecodeErrorResultResponse, + decodeErrorResult, + getAbiItem, + formatAbiItemWithArgs, + formatAbiItem, +} from '../utils' import { BaseError } from './base' export class ContractFunctionExecutionError extends BaseError { - abi?: Abi + abi: Abi args?: unknown[] cause: BaseError contractAddress?: Address formattedArgs?: string - functionName?: string + functionName: string sender?: Address name = 'ContractFunctionExecutionError' @@ -21,21 +28,30 @@ export class ContractFunctionExecutionError extends BaseError { args, contractAddress, docsPath, - formattedArgs, functionName, - functionWithParams, sender, }: { - abi?: Abi + abi: Abi args?: any contractAddress?: Address docsPath?: string - formattedArgs?: string - functionName?: string - functionWithParams?: string + functionName: string sender?: Address }, ) { + const abiItem = getAbiItem({ abi, args, name: functionName }) + const formattedArgs = abiItem + ? formatAbiItemWithArgs({ + abiItem, + args, + includeFunctionName: false, + includeName: false, + }) + : undefined + const functionWithParams = abiItem + ? formatAbiItem(abiItem, { includeName: true }) + : undefined + super( cause.shortMessage || `An unknown error occurred while executing the contract function "${functionName}".`, @@ -84,19 +100,50 @@ export class ContractFunctionRevertedError extends BaseError { message, }: { abi: Abi; data?: Hex; functionName: string; message?: string }) { let decodedData: DecodeErrorResultResponse | undefined = undefined + let metaMessages let reason - if (data) { + if (data && data !== '0x') { decodedData = decodeErrorResult({ abi, data }) - const { errorName, args: errorArgs } = decodedData - if (errorName === 'Error') reason = (errorArgs as string[])[0] - // TODO: Support Panic(uint256) & custom errors. + const { abiItem, errorName, args: errorArgs } = decodedData + if (errorName === 'Error') { + reason = (errorArgs as [string])[0] + } else if (errorName === 'Panic') { + const [firstArg] = errorArgs as [number] + reason = panicReasons[firstArg as keyof typeof panicReasons] + } else if (errorArgs) { + const errorWithParams = abiItem + ? formatAbiItem(abiItem, { includeName: true }) + : undefined + const formattedArgs = abiItem + ? formatAbiItemWithArgs({ + abiItem, + args: errorArgs, + includeFunctionName: false, + includeName: false, + }) + : undefined + + metaMessages = [ + errorWithParams ? `Error: ${errorWithParams}` : '', + formattedArgs && formattedArgs !== '()' + ? `Arguments: ${[...Array(errorName?.length ?? 0).keys()] + .map(() => ' ') + .join('')}${formattedArgs}` + : '', + ] + } } else if (message) reason = message super( - [ - `The contract function "${functionName}" reverted with the following reason:`, - reason, - ].join('\n'), + reason + ? [ + `The contract function "${functionName}" reverted with the following reason:`, + reason, + ].join('\n') + : `The contract function "${functionName}" reverted.`, + { + metaMessages, + }, ) this.reason = reason diff --git a/src/errors/index.ts b/src/errors/index.ts index 4da0347374..dbb32ccbc4 100644 --- a/src/errors/index.ts +++ b/src/errors/index.ts @@ -26,6 +26,8 @@ export { BlockNotFoundError } from './block' export { ContractFunctionExecutionError, + ContractFunctionRevertedError, + ContractFunctionZeroDataError, RawContractError, } from './contract' diff --git a/src/index.test.ts b/src/index.test.ts index 3b11a21551..ac10f484e5 100644 --- a/src/index.test.ts +++ b/src/index.test.ts @@ -19,6 +19,9 @@ test('exports actions', () => { "AbiFunctionSignatureNotFoundError": [Function], "BaseError": [Function], "BlockNotFoundError": [Function], + "ContractFunctionExecutionError": [Function], + "ContractFunctionRevertedError": [Function], + "ContractFunctionZeroDataError": [Function], "DataLengthTooLongError": [Function], "DataLengthTooShortError": [Function], "FilterTypeNotSupportedError": [Function], diff --git a/src/index.ts b/src/index.ts index 62b7d2a2ee..a6893ace36 100644 --- a/src/index.ts +++ b/src/index.ts @@ -208,6 +208,9 @@ export { AbiFunctionSignatureNotFoundError, BaseError, BlockNotFoundError, + ContractFunctionExecutionError, + ContractFunctionRevertedError, + ContractFunctionZeroDataError, DataLengthTooLongError, DataLengthTooShortError, HttpRequestError, diff --git a/src/utils/abi/decodeErrorResult.test.ts b/src/utils/abi/decodeErrorResult.test.ts index d88b85d48d..41a740e126 100644 --- a/src/utils/abi/decodeErrorResult.test.ts +++ b/src/utils/abi/decodeErrorResult.test.ts @@ -14,7 +14,15 @@ test('revert SoldOutError()', () => { ], data: '0x7f6df6bb', }), - ).toEqual({ errorName: 'SoldOutError', args: undefined }) + ).toEqual({ + abiItem: { + inputs: [], + name: 'SoldOutError', + type: 'error', + }, + errorName: 'SoldOutError', + args: undefined, + }) expect( decodeErrorResult({ abi: [ @@ -26,7 +34,14 @@ test('revert SoldOutError()', () => { ], data: '0x7f6df6bb', }), - ).toEqual({ errorName: 'SoldOutError', args: undefined }) + ).toEqual({ + abiItem: { + name: 'SoldOutError', + type: 'error', + }, + errorName: 'SoldOutError', + args: undefined, + }) }) test('revert AccessDeniedError(string)', () => { @@ -48,6 +63,17 @@ test('revert AccessDeniedError(string)', () => { data: '0x83aa206e0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001a796f7520646f206e6f7420686176652061636365737320736572000000000000', }), ).toEqual({ + abiItem: { + inputs: [ + { + internalType: 'string', + name: 'a', + type: 'string', + }, + ], + name: 'AccessDeniedError', + type: 'error', + }, errorName: 'AccessDeniedError', args: ['you do not have access ser'], }) @@ -94,6 +120,39 @@ test('revert AccessDeniedError((uint256,bool,address,uint256))', () => { data: '0x0a1895610000000000000000000000000000000000000000000000000000000000010f2c0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000a5cc3c03994db5b0d9a5eedd10cabab0813678ac0000000000000000000000000000000000000000000000000000000000000029', }), ).toEqual({ + abiItem: { + inputs: [ + { + components: [ + { + internalType: 'uint256', + name: 'weight', + type: 'uint256', + }, + { + internalType: 'bool', + name: 'voted', + type: 'bool', + }, + { + internalType: 'address', + name: 'delegate', + type: 'address', + }, + { + internalType: 'uint256', + name: 'vote', + type: 'uint256', + }, + ], + internalType: 'struct Ballot.Voter', + name: 'voter', + type: 'tuple', + }, + ], + name: 'AccessDeniedError', + type: 'error', + }, errorName: 'AccessDeniedError', args: [ { @@ -112,6 +171,17 @@ test('Error(string)', () => { data: '0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000047465737400000000000000000000000000000000000000000000000000000000', }), ).toEqual({ + abiItem: { + inputs: [ + { + internalType: 'string', + name: 'message', + type: 'string', + }, + ], + name: 'Error', + type: 'error', + }, errorName: 'Error', args: ['test'], }) diff --git a/src/utils/abi/decodeErrorResult.ts b/src/utils/abi/decodeErrorResult.ts index d94b55cb25..db1dcf4065 100644 --- a/src/utils/abi/decodeErrorResult.ts +++ b/src/utils/abi/decodeErrorResult.ts @@ -1,40 +1,19 @@ import { Abi, AbiError } from 'abitype' +import { solidityError, solidityPanic } from '../../constants' import { AbiDecodingZeroDataError, AbiErrorSignatureNotFoundError, } from '../../errors' -import { Hex } from '../../types' +import { AbiItem, Hex } from '../../types' import { slice } from '../data' import { getFunctionSignature } from '../hash' import { decodeAbi } from './decodeAbi' import { formatAbiItem } from './formatAbiItem' -const solidityError: AbiError = { - inputs: [ - { - internalType: 'string', - name: 'message', - type: 'string', - }, - ], - name: 'Error', - type: 'error', -} -const solidityPanic: AbiError = { - inputs: [ - { - internalType: 'uint256', - name: 'reason', - type: 'uint256', - }, - ], - name: 'Panic', - type: 'error', -} - export type DecodeErrorResultArgs = { abi?: Abi; data: Hex } export type DecodeErrorResultResponse = { + abiItem: AbiItem errorName: string args?: readonly unknown[] } @@ -47,21 +26,20 @@ export function decodeErrorResult({ if (signature === '0x') throw new AbiDecodingZeroDataError() const abi_ = [...(abi || []), solidityError, solidityPanic] - const description = abi_.find( + const abiItem = abi_.find( (x) => x.type === 'error' && signature === getFunctionSignature(formatAbiItem(x)), ) - if (!description) + if (!abiItem) throw new AbiErrorSignatureNotFoundError(signature, { docsPath: '/docs/contract/decodeErrorResult', }) return { - errorName: (description as { name: string }).name, - args: ('inputs' in description && - description.inputs && - description.inputs.length > 0 - ? decodeAbi({ data: slice(data, 4), params: description.inputs }) + abiItem, + args: ('inputs' in abiItem && abiItem.inputs && abiItem.inputs.length > 0 + ? decodeAbi({ data: slice(data, 4), params: abiItem.inputs }) : undefined) as readonly unknown[] | undefined, + errorName: (abiItem as { name: string }).name, } } diff --git a/src/utils/contract/getContractError.ts b/src/utils/contract/getContractError.ts index 58b749ecc2..2e929fec08 100644 --- a/src/utils/contract/getContractError.ts +++ b/src/utils/contract/getContractError.ts @@ -10,7 +10,6 @@ import { ContractFunctionZeroDataError, } from '../../errors/contract' import { Address } from '../../types' -import { formatAbiItemWithArgs, formatAbiItem, getAbiItem } from '../abi' const EXECUTION_REVERTED_ERROR_CODE = 3 @@ -36,21 +35,8 @@ export function getContractError( err instanceof RawContractError ? err : err.cause || {} ) as RawContractError - const abiItem = getAbiItem({ abi, args, name: functionName }) - const formattedArgs = abiItem - ? formatAbiItemWithArgs({ - abiItem, - args, - includeFunctionName: false, - includeName: false, - }) - : undefined - const functionWithParams = abiItem - ? formatAbiItem(abiItem, { includeName: true }) - : undefined - let cause = err - if (err instanceof AbiDecodingZeroDataError || data === '0x') { + if (err instanceof AbiDecodingZeroDataError) { cause = new ContractFunctionZeroDataError({ functionName }) } else if (code === EXECUTION_REVERTED_ERROR_CODE && (data || message)) { cause = new ContractFunctionRevertedError({ @@ -66,9 +52,7 @@ export function getContractError( args, contractAddress: address, docsPath, - formattedArgs, functionName, - functionWithParams, sender, }) } diff --git a/wagmi.config.ts b/wagmi.config.ts new file mode 100644 index 0000000000..d9adf8cd43 --- /dev/null +++ b/wagmi.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from '@wagmi/cli' +import { foundry } from '@wagmi/cli/plugins' + +export default defineConfig({ + out: 'src/_test/generated.ts', + contracts: [], + plugins: [ + foundry({ + project: 'contracts/', + }), + ], +}) From 9c71b4be95c02c3cd8a5135f848a3f40123cef33 Mon Sep 17 00:00:00 2001 From: "moxey.eth" Date: Wed, 8 Feb 2023 17:22:40 +1100 Subject: [PATCH 4/7] ci: refactor actions --- .github/actions/setup/action.yml | 52 ++++++++++ .github/workflows/bench.yml | 84 +--------------- .github/workflows/main.yml | 159 ++----------------------------- 3 files changed, 66 insertions(+), 229 deletions(-) create mode 100644 .github/actions/setup/action.yml diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml new file mode 100644 index 0000000000..7d013c3d0b --- /dev/null +++ b/.github/actions/setup/action.yml @@ -0,0 +1,52 @@ +name: 'Setup' +runs: + using: "composite" + steps: + - uses: actions/checkout@v3 + - uses: pnpm/action-setup@v2.2.2 + with: + version: ${{ matrix.pnpm-version }} + - name: Set up Node ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + cache: 'pnpm' + node-version: ${{ matrix.node-version }} + - name: Cache pnpm + uses: actions/cache@v3 + with: + path: ~/.pnpm-store + key: pnpm-${{ hashFiles('pnpm-lock.yaml') }} + restore-keys: pnpm- + - name: Cache node_modules + uses: actions/cache@v3 + id: cache-node-modules + with: + path: | + dist + node_modules + playgrounds/**/node_modules + site/node_modules + key: modules-${{ hashFiles('pnpm-lock.yaml') }} + - name: Install rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + target: wasm32-unknown-unknown + profile: minimal + override: true + - name: Install Foundry + uses: foundry-rs/foundry-toolchain@v1 + with: + version: nightly + - name: Install Dependencies + shell: bash + if: steps.cache-node-modules.outputs.cache-hit != 'true' + run: pnpm i + - name: Build Contracts + shell: bash + if: steps.cache-node-modules.outputs.cache-hit == 'true' + run: pnpm contracts:build + - name: Link Dependencies + shell: bash + if: steps.cache-node-modules.outputs.cache-hit == 'true' + run: pnpm dev \ No newline at end of file diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index be34edc822..b9e133e5b3 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -16,50 +16,8 @@ jobs: pnpm-version: [7] steps: - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2.2.2 - with: - version: ${{ matrix.pnpm-version }} - - name: Set up Node ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - cache: 'pnpm' - node-version: ${{ matrix.node-version }} - - name: Cache pnpm - uses: actions/cache@v3 - with: - path: ~/.pnpm-store - key: pnpm-${{ hashFiles('pnpm-lock.yaml') }} - restore-keys: pnpm- - - name: Cache node_modules - uses: actions/cache@v3 - id: cache-node-modules - with: - path: | - dist - node_modules - playgrounds/**/node_modules - site/node_modules - key: modules-${{ hashFiles('pnpm-lock.yaml') }} - - name: Install rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - target: wasm32-unknown-unknown - profile: minimal - override: true - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - name: Install Dependencies - if: steps.cache-node-modules.outputs.cache-hit != 'true' - run: pnpm i - - name: Build Contracts - if: steps.cache-node-modules.outputs.cache-hit == 'true' - run: pnpm contracts:build - - name: Link Dependencies - if: steps.cache-node-modules.outputs.cache-hit == 'true' - run: pnpm dev + - name: Setup + uses: ./.github/actions/setup bench: name: Benchmark @@ -71,42 +29,8 @@ jobs: pnpm-version: [7] steps: - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2.2.2 - with: - version: ${{ matrix.pnpm-version }} - - name: Set up Node ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - cache: 'pnpm' - node-version: ${{ matrix.node-version }} - - name: Cache node_modules - uses: actions/cache@v3 - with: - path: | - dist - node_modules - playgrounds/**/node_modules - site/node_modules - key: modules-${{ hashFiles('pnpm-lock.yaml') }} - - name: Install rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - target: wasm32-unknown-unknown - profile: minimal - override: true - - name: Install Anvil - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - name: Launch Anvil - run: anvil --fork-url $VITE_ANVIL_FORK_URL --fork-block-number $VITE_ANVIL_BLOCK_NUMBER --block-time $VITE_ANVIL_BLOCK_TIME & - env: - VITE_ANVIL_BLOCK_NUMBER: ${{ secrets.VITE_ANVIL_BLOCK_NUMBER }} - VITE_ANVIL_BLOCK_TIME: ${{ secrets.VITE_ANVIL_BLOCK_TIME }} - VITE_ANVIL_FORK_URL: ${{ secrets.VITE_ANVIL_FORK_URL }} - - name: Build Contracts - run: pnpm contracts:build + - name: Setup + uses: ./.github/actions/setup - name: Bench run: pnpm bench:ci env: diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index e6b99e1920..646604098e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -19,50 +19,8 @@ jobs: pnpm-version: [7] steps: - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2.2.2 - with: - version: ${{ matrix.pnpm-version }} - - name: Set up Node ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - cache: 'pnpm' - node-version: ${{ matrix.node-version }} - - name: Cache pnpm - uses: actions/cache@v3 - with: - path: ~/.pnpm-store - key: pnpm-${{ hashFiles('pnpm-lock.yaml') }} - restore-keys: pnpm- - - name: Cache node_modules - uses: actions/cache@v3 - id: cache-node-modules - with: - path: | - dist - node_modules - playgrounds/**/node_modules - site/node_modules - key: modules-${{ hashFiles('pnpm-lock.yaml') }} - - name: Install rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - target: wasm32-unknown-unknown - profile: minimal - override: true - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - name: Install Dependencies - if: steps.cache-node-modules.outputs.cache-hit != 'true' - run: pnpm i - - name: Build Contracts - if: steps.cache-node-modules.outputs.cache-hit == 'true' - run: pnpm contracts:build - - name: Link Dependencies - if: steps.cache-node-modules.outputs.cache-hit == 'true' - run: pnpm dev + - name: Setup + uses: ./.github/actions/setup lint: name: Lint @@ -74,38 +32,8 @@ jobs: pnpm-version: [7] steps: - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2.2.2 - with: - version: ${{ matrix.pnpm-version }} - - name: Set up Node ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - cache: 'pnpm' - node-version: ${{ matrix.node-version }} - - name: Cache node_modules - uses: actions/cache@v3 - with: - path: | - dist - node_modules - playgrounds/**/node_modules - site/node_modules - key: modules-${{ hashFiles('pnpm-lock.yaml') }} - - name: Install rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - target: wasm32-unknown-unknown - profile: minimal - override: true - - name: Install Foundry - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly - - name: Build Contracts - run: pnpm contracts:build - - name: Link - run: pnpm dev + - name: Setup + uses: ./.github/actions/setup - name: Check types run: pnpm typecheck - name: Lint & format code @@ -134,23 +62,8 @@ jobs: pnpm-version: [7] steps: - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2.2.2 - with: - version: ${{ matrix.pnpm-version }} - - name: Set up Node ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - cache: 'pnpm' - node-version: ${{ matrix.node-version }} - - name: Cache node_modules - uses: actions/cache@v3 - with: - path: | - dist - node_modules - playgrounds/**/node_modules - site/node_modules - key: modules-${{ hashFiles('pnpm-lock.yaml') }} + - name: Setup + uses: ./.github/actions/setup - name: Build run: pnpm build @@ -167,42 +80,14 @@ jobs: transport-mode: ['http', 'webSocket'] steps: - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2.2.2 - with: - version: ${{ matrix.pnpm-version }} - - name: Set up Node ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - cache: 'pnpm' - node-version: ${{ matrix.node-version }} - - name: Cache node_modules - uses: actions/cache@v3 - with: - path: | - dist - node_modules - playgrounds/**/node_modules - site/node_modules - key: modules-${{ hashFiles('pnpm-lock.yaml') }} - - name: Install rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - target: wasm32-unknown-unknown - profile: minimal - override: true - - name: Install Anvil - uses: foundry-rs/foundry-toolchain@v1 - with: - version: nightly + - name: Setup + uses: ./.github/actions/setup - name: Launch Anvil run: anvil --fork-url $VITE_ANVIL_FORK_URL --fork-block-number $VITE_ANVIL_BLOCK_NUMBER --block-time $VITE_ANVIL_BLOCK_TIME & env: VITE_ANVIL_BLOCK_NUMBER: ${{ secrets.VITE_ANVIL_BLOCK_NUMBER }} VITE_ANVIL_BLOCK_TIME: ${{ secrets.VITE_ANVIL_BLOCK_TIME }} VITE_ANVIL_FORK_URL: ${{ secrets.VITE_ANVIL_FORK_URL }} - - name: Build Contracts - run: pnpm contracts:build - name: Test uses: nick-fields/retry@v2 with: @@ -230,30 +115,8 @@ jobs: pnpm-version: [7] steps: - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2.2.2 - with: - version: ${{ matrix.pnpm-version }} - - name: Set up Node ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - cache: 'pnpm' - node-version: ${{ matrix.node-version }} - - name: Cache node_modules - uses: actions/cache@v3 - with: - path: | - dist - node_modules - playgrounds/**/node_modules - site/node_modules - key: modules-${{ hashFiles('pnpm-lock.yaml') }} - - name: Install rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - target: wasm32-unknown-unknown - profile: minimal - override: true + - name: Setup + uses: ./.github/actions/setup - name: Install Anvil uses: foundry-rs/foundry-toolchain@v1 with: @@ -264,8 +127,6 @@ jobs: VITE_ANVIL_BLOCK_NUMBER: ${{ secrets.VITE_ANVIL_BLOCK_NUMBER }} VITE_ANVIL_BLOCK_TIME: ${{ secrets.VITE_ANVIL_BLOCK_TIME }} VITE_ANVIL_FORK_URL: ${{ secrets.VITE_ANVIL_FORK_URL }} - - name: Build Contracts - run: pnpm contracts:build - name: Bench run: pnpm bench:ci --changed env: From 66e274427bce82e326174d6b587108df7c4a1f2b Mon Sep 17 00:00:00 2001 From: jxom Date: Wed, 8 Feb 2023 17:23:15 +1100 Subject: [PATCH 5/7] Delete foundry.toml --- contracts/foundry.toml | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 contracts/foundry.toml diff --git a/contracts/foundry.toml b/contracts/foundry.toml deleted file mode 100644 index 93d2364a88..0000000000 --- a/contracts/foundry.toml +++ /dev/null @@ -1,2 +0,0 @@ -[profile.ci.fuzz] -runs = 10_000 From a3f9f6abe6362c0c3d2d26c7a28c9f453884df5b Mon Sep 17 00:00:00 2001 From: "moxey.eth" Date: Wed, 8 Feb 2023 19:11:55 +1100 Subject: [PATCH 6/7] chore: changeset --- .changeset/fifty-weeks-exercise.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fifty-weeks-exercise.md diff --git a/.changeset/fifty-weeks-exercise.md b/.changeset/fifty-weeks-exercise.md new file mode 100644 index 0000000000..9e1fb416da --- /dev/null +++ b/.changeset/fifty-weeks-exercise.md @@ -0,0 +1,5 @@ +--- +"viem": patch +--- + +support `Panic` & custom contract errors From bf0ee4d7dd65308779cb73e996a8aedcd01414e2 Mon Sep 17 00:00:00 2001 From: "moxey.eth" Date: Thu, 9 Feb 2023 11:21:01 +1100 Subject: [PATCH 7/7] refactor --- .github/workflows/release.yml | 4 +- .github/workflows/size.yml | 34 ++----------- .github/workflows/snapshot.yml | 4 +- package.json | 2 +- src/actions/public/multicall.ts | 6 ++- src/constants/index.test.ts | 90 ++++----------------------------- src/constants/index.ts | 2 +- src/constants/solidity.ts | 2 - 8 files changed, 21 insertions(+), 123 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b559e62653..aafa27abb2 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -28,9 +28,7 @@ jobs: cache: 'pnpm' node-version: ${{ matrix.node-version }} - name: Install Dependencies - run: pnpm i - env: - SKIP_WAGMI_CLI: true + run: pnpm i --ignore-scripts - name: Create Release Pull Request or Publish to npm id: changesets diff --git a/.github/workflows/size.yml b/.github/workflows/size.yml index 3c0d5e72ec..ab3731bfbe 100644 --- a/.github/workflows/size.yml +++ b/.github/workflows/size.yml @@ -12,36 +12,8 @@ jobs: pnpm-version: [7] steps: - uses: actions/checkout@v3 - - uses: pnpm/action-setup@v2.2.2 - with: - version: ${{ matrix.pnpm-version }} - - name: Set up Node ${{ matrix.node-version }} - uses: actions/setup-node@v3 - with: - cache: 'pnpm' - node-version: ${{ matrix.node-version }} - - name: Cache pnpm - uses: actions/cache@v3 - with: - path: ~/.pnpm-store - key: pnpm-${{ hashFiles('pnpm-lock.yaml') }} - restore-keys: pnpm- - - name: Cache node_modules - uses: actions/cache@v3 - id: cache-node-modules - with: - path: | - dist - node_modules - playgrounds/**/node_modules - site/node_modules - key: modules-${{ hashFiles('pnpm-lock.yaml') }} - - name: Install Dependencies - if: steps.cache-node-modules.outputs.cache-hit != 'true' - env: - SKIP_WAGMI_CLI: true + - name: Setup + uses: ./.github/actions/setup - uses: preactjs/compressed-size-action@v2 with: - repo-token: "${{ secrets.GITHUB_TOKEN }}" - env: - SKIP_WAGMI_CLI: true \ No newline at end of file + repo-token: "${{ secrets.GITHUB_TOKEN }}" \ No newline at end of file diff --git a/.github/workflows/snapshot.yml b/.github/workflows/snapshot.yml index 38f0ff75dc..eba17672a0 100644 --- a/.github/workflows/snapshot.yml +++ b/.github/workflows/snapshot.yml @@ -27,9 +27,7 @@ jobs: node-version: ${{ matrix.node-version }} - name: Install Dependencies - run: pnpm i - env: - SKIP_WAGMI_CLI: true + run: pnpm i --ignore-scripts - name: Publish to npm uses: seek-oss/changesets-snapshot@v0 diff --git a/package.json b/package.json index 04786b91a9..4a6dd14750 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "lint:fix": "pnpm lint --apply-suggested", "playground": "pnpm --filter playground-dev dev", "playground:benchmark": "pnpm --filter playground-benchmark dev", - "postinstall": "pnpm dev && if [ -z $SKIP_WAGMI_CLI ]; then pnpm contracts:build; fi", + "postinstall": "pnpm dev && pnpm contracts:build", "preinstall": "npx only-allow pnpm", "prepublishOnly": "pnpm ts-node scripts/generate-package-json.ts", "prepare": "npx simple-git-hooks", diff --git a/src/actions/public/multicall.ts b/src/actions/public/multicall.ts index ff0cee90f6..99043b900e 100644 --- a/src/actions/public/multicall.ts +++ b/src/actions/public/multicall.ts @@ -1,6 +1,10 @@ import { PublicClient } from '../../clients' import { multicall3Abi } from '../../constants' -import { AbiDecodingZeroDataError, BaseError, RawContractError } from '../../errors' +import { + AbiDecodingZeroDataError, + BaseError, + RawContractError, +} from '../../errors' import { Address, ContractConfig, Hex, MulticallContracts } from '../../types' import { MulticallResults } from '../../types/multicall' import { diff --git a/src/constants/index.test.ts b/src/constants/index.test.ts index 33bd7822d2..862f08336c 100644 --- a/src/constants/index.test.ts +++ b/src/constants/index.test.ts @@ -1,86 +1,14 @@ import { expect, test } from 'vitest' -import * as clients from './index' +import * as index from './index' -test('exports clients', () => { - expect(clients).toMatchInlineSnapshot(` - { - "multicall3Abi": [ - { - "inputs": [ - { - "components": [ - { - "name": "target", - "type": "address", - }, - { - "name": "allowFailure", - "type": "bool", - }, - { - "name": "callData", - "type": "bytes", - }, - ], - "name": "calls", - "type": "tuple[]", - }, - ], - "name": "aggregate3", - "outputs": [ - { - "components": [ - { - "name": "success", - "type": "bool", - }, - { - "name": "returnData", - "type": "bytes", - }, - ], - "name": "returnData", - "type": "tuple[]", - }, - ], - "stateMutability": "view", - "type": "function", - }, - ], - "panicReasons": { - "1": "An \`assert\` condition failed.", - "17": "Arithmic operation resulted in underflow or overflow.", - "18": "Division or modulo by zero (e.g. \`5 / 0\` or \`23 % 0\`).", - "33": "Attempted to convert to an invalid type.", - "34": "Attempted to access a storage byte array that is incorrectly encoded.", - "49": "Performed \`.pop()\` on an empty array", - "50": "Array index is out of bounds.", - "65": "Allocated too much memory or created an array which is too large.", - "81": "Attempted to call a zero-initialized variable of internal function type.", - }, - "solidityError": { - "inputs": [ - { - "internalType": "string", - "name": "message", - "type": "string", - }, - ], - "name": "Error", - "type": "error", - }, - "solidityPanic": { - "inputs": [ - { - "internalType": "uint256", - "name": "reason", - "type": "uint256", - }, - ], - "name": "Panic", - "type": "error", - }, - } +test('exports index', () => { + expect(Object.keys(index)).toMatchInlineSnapshot(` + [ + "multicall3Abi", + "panicReasons", + "solidityError", + "solidityPanic", + ] `) }) diff --git a/src/constants/index.ts b/src/constants/index.ts index 33a54763fa..a40ae4cfed 100644 --- a/src/constants/index.ts +++ b/src/constants/index.ts @@ -1,3 +1,3 @@ export { multicall3Abi } from './abis' -export { panicReasons, solidityError, solidityPanic } from './solidity' \ No newline at end of file +export { panicReasons, solidityError, solidityPanic } from './solidity' diff --git a/src/constants/solidity.ts b/src/constants/solidity.ts index 67cba2cf9d..7606b031e6 100644 --- a/src/constants/solidity.ts +++ b/src/constants/solidity.ts @@ -16,7 +16,6 @@ export const panicReasons = { export const solidityError: AbiError = { inputs: [ { - internalType: 'string', name: 'message', type: 'string', }, @@ -27,7 +26,6 @@ export const solidityError: AbiError = { export const solidityPanic: AbiError = { inputs: [ { - internalType: 'uint256', name: 'reason', type: 'uint256', },